This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 103467
Collapse All | Expand All

(-)a/openide.awt/src/org/openide/awt/UndoRedo.java (-1 / +248 lines)
Lines 115-121 Link Here
115
115
116
    /** An undo manager which fires a change event each time it consumes a new undoable edit.
116
    /** An undo manager which fires a change event each time it consumes a new undoable edit.
117
    */
117
    */
118
    public static class Manager extends UndoManager implements UndoRedo {
118
    public static class Manager extends UndoGroupManager implements UndoRedo {
119
        static final long serialVersionUID = 6721367974521509720L;
119
        static final long serialVersionUID = 6721367974521509720L;
120
120
121
        private final ChangeSupport cs = new ChangeSupport(this);
121
        private final ChangeSupport cs = new ChangeSupport(this);
Lines 275-278 Link Here
275
            return ""; // NOI18N
275
            return ""; // NOI18N
276
        }
276
        }
277
    }
277
    }
278
279
    /**
280
     * <tt>UndoGroupManager</tt> extends {@link UndoManager}
281
     * and allows explicit control of what
282
     * <tt>UndoableEdit</tt>s are coalesced into compound edits,
283
     * rather than using the rules defined by the edits themselves.
284
     * Other than the default usage, special handling is initiated by invoking
285
     * <tt>beginUndoGroup()</tt>.
286
     * <p>
287
     * Three use cases are supported.
288
     * </p>
289
     * <ol>
290
     * <li> Default behavior is defined by {@link UndoManager}.</li>
291
     * <li> <tt>UnddoableEdit</tt>s issued between {@link #beginUndoGroup}
292
     * and {@link endUndoGroup} are placed into a single {@link CompoundEdit}.
293
     * Thus <tt>undo()</tt> and <tt>redo()</tt> treat them 
294
     * as a single undo/redo.</li>
295
     * <li> Use {@link beginUndoGroup} to commit accumulated
296
     * <tt>UndoableEdit</tt>s into a single <tt>CompoundEdit</tt>
297
     * (and to continue accumulating);
298
     * an application could do this at strategic points, such as EndOfLine
299
     * input or cursor movement. In this way, the application can accumulate
300
     * large chunks.</li>
301
     * </ol>
302
     * @see UndoManager
303
     */
304
    public static class UndoGroupManager extends UndoManager {
305
        /** signals that edits are being accumulated */
306
        private boolean buildUndoGroup;
307
        /** accumulate edits here in undoGroup */
308
        private CompoundEdit undoGroup;
309
310
        /**
311
         * Direct this <tt>UndoGroupManager</tt> to begin coalescing any
312
         * <tt>UndoableEdit</tt>s that are added into a <tt>CompoundEdit</tt>.
313
         * <p>If edits are already being coalesced and some have been 
314
         * accumulated, they are commited as an atomic group and a new
315
         * group is started.
316
         * @see #addEdit
317
         * @see #endUndoGroup
318
         */
319
        public synchronized void beginUndoGroup() {
320
            commitUndoGroup();
321
            buildUndoGroup = true;
322
        }
323
324
        /**
325
         * Direct this <tt>UndoGroupManager</tt> to stop coalescing edits.
326
         * Until <tt>beginUndoGroupManager</tt> is invoked,
327
         * any received <tt>UndoableEdit</tt>s are added singly.
328
         * <p>
329
         * This has no effect if edits are not being coalesced, for example
330
         * if <tt>beginUndoGroup</tt> has not been called.
331
         */
332
        public synchronized void endUndoGroup() {
333
            buildUndoGroup = false;
334
            commitUndoGroup();
335
        }
336
337
        /**
338
         * Commit any accumulated <tt>UndoableEdit</tt>s as an atomic
339
         * <tt>undo</tt>/<tt>redo</tt> group. {@link CompoundEdit#end}
340
         * is invoked on the <tt>CompoundEdit</tt> and it is added as a single
341
         * <tt>UndoableEdit</tt> to this <tt>UndoManager</tt>.
342
         * <p>
343
         * If edits are currently being coalesced, a new undo group is started.
344
         * This has no effect if edits are not being coalesced, for example
345
         * <tt>beginUndoGroup</tt> has not been called.
346
         */
347
        private synchronized void commitUndoGroup() {
348
            if(undoGroup == null) {
349
                return;
350
            }
351
            // super.addEdit may end up in this.addEdit,
352
            // so buildUndoGroup must be false
353
            boolean saveBuildUndoGroup = buildUndoGroup;
354
            buildUndoGroup = false;
355
356
            undoGroup.end();
357
            super.addEdit(undoGroup);
358
            undoGroup = null;
359
360
            buildUndoGroup = saveBuildUndoGroup;
361
        }
362
363
        /** Add this edit separately, not part of a group.
364
         * @return super.addEdit
365
         */
366
        private boolean commitAddEdit(UndoableEdit anEdit) {
367
            commitUndoGroup();
368
369
            boolean saveBuildUndoGroup = buildUndoGroup;
370
            buildUndoGroup = false;
371
            boolean f = super.addEdit(anEdit);
372
            //boolean f = addEdit(undoGroup);
373
            buildUndoGroup = saveBuildUndoGroup;
374
            return f;
375
        }
376
377
        /** SeparateEdit tags an UndoableEdit so the
378
         * UndoGroupManager does not coalesce it.
379
         */
380
        public interface SeparateEdit {
381
        }
382
383
        /**
384
         * If this <tt>UndoManager</tt> is coalescing edits then add
385
         * <tt>anEdit</tt> to the accumulating <tt>CompoundEdit</tt>.
386
         * Otherwise, add it to this UndoManager. In either case the
387
         * edit is saved for later <tt>undo</tt> or <tt>redo</tt>.
388
         * @return {@inheritDoc}
389
         * @see #beginUndoGroup
390
         * @see #endUndoGroup
391
         */
392
        @Override
393
        public synchronized boolean addEdit(UndoableEdit anEdit) {
394
            if(!isInProgress())
395
                return false;
396
397
            if(buildUndoGroup) {
398
                if(anEdit instanceof SeparateEdit)
399
                    return commitAddEdit(anEdit);
400
                if(undoGroup == null)
401
                    undoGroup = new CompoundEdit();
402
                return undoGroup.addEdit(anEdit);
403
            } else {
404
                return super.addEdit(anEdit);
405
            }
406
        }
407
408
        /** {@inheritDoc} */
409
        @Override
410
        public synchronized void discardAllEdits() {
411
            commitUndoGroup();
412
            super.discardAllEdits();
413
        }
414
415
        //
416
        // TODO: limits
417
        //
418
419
        /** {@inheritDoc} */
420
        @Override
421
        public synchronized void undoOrRedo() {
422
            commitUndoGroup();
423
            super.undoOrRedo();
424
        }
425
426
        /** {@inheritDoc} */
427
        @Override
428
        public synchronized boolean canUndoOrRedo() {
429
            if(undoGroup != null)
430
                return true;
431
            return super.canUndoOrRedo();
432
        }
433
434
        /** {@inheritDoc} */
435
        @Override
436
        public synchronized void undo() {
437
            commitUndoGroup();
438
            super.undo();
439
        }
440
441
        /** {@inheritDoc} */
442
        @Override
443
        public synchronized boolean canUndo() {
444
            if(undoGroup != null)
445
                return true;
446
            return super.canUndo();
447
        }
448
449
        /** {@inheritDoc} */
450
        @Override
451
        public synchronized void redo() {
452
            if(undoGroup != null)
453
                throw new CannotRedoException();
454
            super.redo();
455
        }
456
457
        /** {@inheritDoc} */
458
        @Override
459
        public synchronized boolean canRedo() {
460
            if(undoGroup != null)
461
                return false;
462
            return super.canRedo();
463
        }
464
465
        /** {@inheritDoc} */
466
        @Override
467
        public synchronized void end() {
468
            commitUndoGroup();
469
            super.end();
470
        }
471
472
        /** {@inheritDoc} */
473
        @Override
474
        public synchronized String getUndoOrRedoPresentationName() {
475
            if(undoGroup != null)
476
                return undoGroup.getUndoPresentationName();
477
            return super.getUndoOrRedoPresentationName();
478
        }
479
480
        /** {@inheritDoc} */
481
        @Override
482
        public synchronized String getUndoPresentationName() {
483
            if(undoGroup != null)
484
                return undoGroup.getUndoPresentationName();
485
            return super.getUndoPresentationName();
486
        }
487
488
        /** {@inheritDoc} */
489
        @Override
490
        public synchronized String getRedoPresentationName() {
491
            if(undoGroup != null)
492
                return undoGroup.getRedoPresentationName();
493
            return super.getRedoPresentationName();
494
        }
495
496
        /** {@inheritDoc} */
497
        @Override
498
        public boolean isSignificant() {
499
            if(undoGroup != null && undoGroup.isSignificant()) {
500
                return true;
501
            }
502
            return super.isSignificant();
503
        }
504
505
        /** {@inheritDoc} */
506
        @Override
507
        public synchronized void die() {
508
            commitUndoGroup();
509
            super.die();
510
        }
511
512
        /** {@inheritDoc} */
513
        @Override
514
        public String getPresentationName() {
515
            if(undoGroup != null)
516
                return undoGroup.getPresentationName();
517
            return super.getPresentationName();
518
        }
519
520
        // The protected methods are only accessed from
521
        // synchronized methods that do commitUndoGroup
522
        // so they do not need to be overridden in this class
523
    }
524
278
}
525
}
(-)a/openide.text/src/org/openide/text/CloneableEditorSupport.java (-1 / +2 lines)
Lines 2983-2989 Link Here
2983
    }
2983
    }
2984
2984
2985
    /** Generic undoable edit that delegates to the given undoable edit. */
2985
    /** Generic undoable edit that delegates to the given undoable edit. */
2986
    private class FilterUndoableEdit implements UndoableEdit {
2986
    private class FilterUndoableEdit
2987
            implements UndoableEdit, UndoRedo.Manager.SeparateEdit {
2987
        protected UndoableEdit delegate;
2988
        protected UndoableEdit delegate;
2988
2989
2989
        FilterUndoableEdit() {
2990
        FilterUndoableEdit() {

Return to bug 103467