Source Code Cross Referenced for OperationHistoryActionHandler.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » operations » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » ui workbench » org.eclipse.ui.operations 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2005, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.ui.operations;
011:
012:        import java.lang.reflect.InvocationTargetException;
013:
014:        import org.eclipse.core.commands.ExecutionException;
015:        import org.eclipse.core.commands.operations.IAdvancedUndoableOperation2;
016:        import org.eclipse.core.commands.operations.IOperationHistory;
017:        import org.eclipse.core.commands.operations.IOperationHistoryListener;
018:        import org.eclipse.core.commands.operations.IUndoContext;
019:        import org.eclipse.core.commands.operations.IUndoableOperation;
020:        import org.eclipse.core.commands.operations.OperationHistoryEvent;
021:        import org.eclipse.core.runtime.IAdaptable;
022:        import org.eclipse.core.runtime.IProgressMonitor;
023:        import org.eclipse.core.runtime.IStatus;
024:        import org.eclipse.core.runtime.OperationCanceledException;
025:        import org.eclipse.jface.action.Action;
026:        import org.eclipse.jface.operation.IRunnableWithProgress;
027:        import org.eclipse.osgi.util.NLS;
028:        import org.eclipse.swt.widgets.Display;
029:        import org.eclipse.swt.widgets.Shell;
030:        import org.eclipse.ui.IPartListener;
031:        import org.eclipse.ui.IWorkbenchPart;
032:        import org.eclipse.ui.IWorkbenchPartSite;
033:        import org.eclipse.ui.IWorkbenchWindow;
034:        import org.eclipse.ui.PlatformUI;
035:        import org.eclipse.ui.actions.ActionFactory;
036:        import org.eclipse.ui.internal.WorkbenchMessages;
037:        import org.eclipse.ui.internal.WorkbenchPlugin;
038:        import org.eclipse.ui.internal.misc.StatusUtil;
039:        import org.eclipse.ui.internal.operations.TimeTriggeredProgressMonitorDialog;
040:        import org.eclipse.ui.internal.util.Util;
041:        import org.eclipse.ui.part.MultiPageEditorSite;
042:        import org.eclipse.ui.statushandlers.StatusManager;
043:
044:        /**
045:         * <p>
046:         * OperationHistoryActionHandler implements common behavior for the undo and
047:         * redo actions. It supports filtering of undo or redo on a particular undo
048:         * context. If an undo context is not specified, or there has been no history
049:         * available for the specified undo context, then the workbench undo context
050:         * will be used.
051:         * </p>
052:         * <p>
053:         * OperationHistoryActionHandler provides an adapter in the info parameter of
054:         * the IOperationHistory undo and redo methods that is used to get UI info for
055:         * prompting the user during operations or operation approval. Adapters are
056:         * provided for org.eclipse.ui.IWorkbenchWindow, org.eclipse.swt.widgets.Shell,
057:         * org.eclipse.ui.IWorkbenchPart, org.eclipse.core.commands.IUndoContext, and
058:         * org.eclipse.runtime.IProgressMonitor.
059:         * </p>
060:         * <p>
061:         * OperationHistoryActionHandler assumes a linear undo/redo model. When the
062:         * handler is run, the operation history is asked to perform the most recent
063:         * undo/redo for the handler's undo context. The handler can be configured
064:         * (using #setPruneHistory(true)) to flush the operation undo or redo history
065:         * for the handler's undo context when there is no valid operation on top of the
066:         * history. This avoids keeping a stale history of invalid operations. By
067:         * default, pruning does not occur and it is assumed that clients of the
068:         * particular undo context are pruning the history when necessary.
069:         * </p>
070:         * 
071:         * @since 3.1
072:         */
073:        public abstract class OperationHistoryActionHandler extends Action
074:                implements  ActionFactory.IWorkbenchAction, IAdaptable {
075:
076:            private static final int MAX_LABEL_LENGTH = 32;
077:
078:            private class PartListener implements  IPartListener {
079:                /**
080:                 * @see IPartListener#partActivated(IWorkbenchPart)
081:                 */
082:                public void partActivated(IWorkbenchPart part) {
083:                }
084:
085:                /**
086:                 * @see IPartListener#partBroughtToTop(IWorkbenchPart)
087:                 */
088:                public void partBroughtToTop(IWorkbenchPart part) {
089:                }
090:
091:                /**
092:                 * @see IPartListener#partClosed(IWorkbenchPart)
093:                 */
094:                public void partClosed(IWorkbenchPart part) {
095:                    if (part.equals(site.getPart())) {
096:                        dispose();
097:                        // Special case for MultiPageEditorSite
098:                        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=103379
099:                    } else if ((site instanceof  MultiPageEditorSite)
100:                            && (part.equals(((MultiPageEditorSite) site)
101:                                    .getMultiPageEditor()))) {
102:                        dispose();
103:                    }
104:                }
105:
106:                /**
107:                 * @see IPartListener#partDeactivated(IWorkbenchPart)
108:                 */
109:                public void partDeactivated(IWorkbenchPart part) {
110:                }
111:
112:                /**
113:                 * @see IPartListener#partOpened(IWorkbenchPart)
114:                 */
115:                public void partOpened(IWorkbenchPart part) {
116:                }
117:
118:            }
119:
120:            private class HistoryListener implements  IOperationHistoryListener {
121:                public void historyNotification(
122:                        final OperationHistoryEvent event) {
123:                    Display display = getWorkbenchWindow().getWorkbench()
124:                            .getDisplay();
125:                    switch (event.getEventType()) {
126:                    case OperationHistoryEvent.OPERATION_ADDED:
127:                    case OperationHistoryEvent.OPERATION_REMOVED:
128:                    case OperationHistoryEvent.UNDONE:
129:                    case OperationHistoryEvent.REDONE:
130:                        if (display != null
131:                                && event.getOperation().hasContext(undoContext)) {
132:                            contextActive = true;
133:                            display.asyncExec(new Runnable() {
134:                                public void run() {
135:                                    update();
136:                                }
137:                            });
138:                        }
139:                        break;
140:                    case OperationHistoryEvent.OPERATION_NOT_OK:
141:                        if (display != null
142:                                && event.getOperation().hasContext(undoContext)) {
143:                            contextActive = true;
144:                            display.asyncExec(new Runnable() {
145:                                public void run() {
146:                                    if (pruning) {
147:                                        IStatus status = event.getStatus();
148:                                        /*
149:                                         * Prune the history unless we can determine
150:                                         * that this was a cancelled attempt. See
151:                                         * https://bugs.eclipse.org/bugs/show_bug.cgi?id=101215
152:                                         */
153:                                        if (status == null
154:                                                || status.getSeverity() != IStatus.CANCEL) {
155:                                            flush();
156:                                        }
157:                                        // not all flushes will trigger an update so
158:                                        // force it here
159:                                        update();
160:                                    } else {
161:                                        update();
162:                                    }
163:                                }
164:                            });
165:                        }
166:                        break;
167:                    case OperationHistoryEvent.OPERATION_CHANGED:
168:                        if (event.getOperation().hasContext(undoContext)) {
169:                            contextActive = true;
170:                        }
171:                        if (display != null
172:                                && event.getOperation() == getOperation()) {
173:                            display.asyncExec(new Runnable() {
174:                                public void run() {
175:                                    update();
176:                                }
177:                            });
178:                        }
179:                        break;
180:                    default:
181:                        if (event.getOperation().hasContext(undoContext)) {
182:                            contextActive = true;
183:                        }
184:                        break;
185:                    }
186:                }
187:            }
188:
189:            private boolean contextActive = false;
190:
191:            private boolean pruning = false;
192:
193:            private IPartListener partListener = new PartListener();
194:
195:            private IOperationHistoryListener historyListener = new HistoryListener();
196:
197:            private TimeTriggeredProgressMonitorDialog progressDialog;
198:
199:            private IUndoContext undoContext = null;
200:
201:            IWorkbenchPartSite site;
202:
203:            /**
204:             * Construct an operation history action for the specified workbench window
205:             * with the specified undo context.
206:             * 
207:             * @param site -
208:             *            the workbench part site for the action.
209:             * @param context -
210:             *            the undo context to be used
211:             */
212:            OperationHistoryActionHandler(IWorkbenchPartSite site,
213:                    IUndoContext context) {
214:                // string will be reset inside action
215:                super (""); //$NON-NLS-1$
216:                this .site = site;
217:                undoContext = context;
218:                checkUndoContext();
219:                site.getPage().addPartListener(partListener);
220:                getHistory().addOperationHistoryListener(historyListener);
221:                // An update must be forced in case the undo limit is 0.
222:                // see bug #89707
223:                update();
224:            }
225:
226:            /*
227:             * (non-Javadoc)
228:             * 
229:             * @see org.eclipse.ui.actions.ActionFactory.IWorkbenchAction#dispose()
230:             */
231:            public void dispose() {
232:
233:                IOperationHistory history = getHistory();
234:                if (history != null) {
235:                    history.removeOperationHistoryListener(historyListener);
236:                }
237:
238:                if (isInvalid()) {
239:                    return;
240:                }
241:
242:                site.getPage().removePartListener(partListener);
243:                site = null;
244:                progressDialog = null;
245:                // We do not flush the history for our undo context because it may be
246:                // used elsewhere. It is up to clients to clean up the history
247:                // appropriately.
248:                // We do null out the context to signify that this handler is no longer
249:                // accessing the history.
250:                undoContext = null;
251:            }
252:
253:            /*
254:             * Flush the history associated with this action.
255:             */
256:            abstract void flush();
257:
258:            /*
259:             * Return the string describing the command, including the binding for the
260:             * operation label.
261:             */
262:            abstract String getCommandString();
263:
264:            /*
265:             * Return the string describing the command for a tooltip, including the
266:             * binding for the operation label.
267:             */
268:            abstract String getTooltipString();
269:
270:            /*
271:             * Return the simple string describing the command, with no binding to any
272:             * operation.
273:             */
274:            abstract String getSimpleCommandString();
275:
276:            /*
277:             * Return the simple string describing the tooltip, with no binding to any
278:             * operation.
279:             */
280:            abstract String getSimpleTooltipString();
281:
282:            /*
283:             * Return the operation history we are using.
284:             */
285:            IOperationHistory getHistory() {
286:                if (PlatformUI.getWorkbench() == null) {
287:                    return null;
288:                }
289:
290:                return PlatformUI.getWorkbench().getOperationSupport()
291:                        .getOperationHistory();
292:            }
293:
294:            /*
295:             * Return the current operation.
296:             */
297:            abstract IUndoableOperation getOperation();
298:
299:            /*
300:             * (non-Javadoc)
301:             * 
302:             * @see org.eclipse.ui.actions.ActionFactory.IWorkbenchAction#run()
303:             */
304:            public final void run() {
305:                if (isInvalid()) {
306:                    return;
307:                }
308:
309:                Shell parent = getWorkbenchWindow().getShell();
310:                progressDialog = new TimeTriggeredProgressMonitorDialog(parent,
311:                        getWorkbenchWindow().getWorkbench()
312:                                .getProgressService().getLongOperationTime());
313:                IRunnableWithProgress runnable = new IRunnableWithProgress() {
314:                    public void run(IProgressMonitor pm)
315:                            throws InvocationTargetException {
316:                        try {
317:                            runCommand(pm);
318:                        } catch (ExecutionException e) {
319:                            if (pruning) {
320:                                flush();
321:                            }
322:                            throw new InvocationTargetException(e);
323:                        }
324:                    }
325:                };
326:                try {
327:                    boolean runInBackground = false;
328:                    if (getOperation() instanceof  IAdvancedUndoableOperation2) {
329:                        runInBackground = ((IAdvancedUndoableOperation2) getOperation())
330:                                .runInBackground();
331:                    }
332:                    progressDialog.run(runInBackground, true, runnable);
333:                } catch (InvocationTargetException e) {
334:                    Throwable t = e.getTargetException();
335:                    if (t == null) {
336:                        reportException(e);
337:                    } else {
338:                        reportException(t);
339:                    }
340:                } catch (InterruptedException e) {
341:                    // Operation was cancelled and acknowledged by runnable with this
342:                    // exception.
343:                    // Do nothing.
344:                } catch (OperationCanceledException e) {
345:                    // the operation was cancelled. Do nothing.
346:                } finally {
347:                    progressDialog = null;
348:                }
349:            }
350:
351:            abstract IStatus runCommand(IProgressMonitor pm)
352:                    throws ExecutionException;
353:
354:            /*
355:             * (non-Javadoc)
356:             * 
357:             * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
358:             */
359:            public Object getAdapter(Class adapter) {
360:                if (adapter.equals(IUndoContext.class)) {
361:                    return undoContext;
362:                }
363:                if (adapter.equals(IProgressMonitor.class)) {
364:                    if (progressDialog != null) {
365:                        return progressDialog.getProgressMonitor();
366:                    }
367:                }
368:                if (site != null) {
369:                    if (adapter.equals(Shell.class)) {
370:                        return getWorkbenchWindow().getShell();
371:                    }
372:                    if (adapter.equals(IWorkbenchWindow.class)) {
373:                        return getWorkbenchWindow();
374:                    }
375:                    if (adapter.equals(IWorkbenchPart.class)) {
376:                        return site.getPart();
377:                    }
378:                    // Refer all other requests to the part itself.
379:                    // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=108144
380:                    IWorkbenchPart part = site.getPart();
381:                    if (part != null) {
382:                        return Util.getAdapter(part, adapter);
383:                    }
384:                }
385:                return null;
386:            }
387:
388:            /*
389:             * Return the workbench window for this action handler
390:             */
391:            private IWorkbenchWindow getWorkbenchWindow() {
392:                if (site != null) {
393:                    return site.getWorkbenchWindow();
394:                }
395:                return null;
396:            }
397:
398:            /**
399:             * The undo and redo subclasses should implement this.
400:             * 
401:             * @return - a boolean indicating enablement state
402:             */
403:            abstract boolean shouldBeEnabled();
404:
405:            /**
406:             * Set the context shown by the handler. Normally the context is set up when
407:             * the action handler is created, but the context can also be changed
408:             * dynamically.
409:             * 
410:             * @param context
411:             *            the context to be used for the undo history
412:             */
413:            public void setContext(IUndoContext context) {
414:                // optimization - do nothing if there was no real change
415:                if (context == undoContext) {
416:                    return;
417:                }
418:                undoContext = context;
419:                checkUndoContext();
420:                update();
421:            }
422:
423:            /**
424:             * Specify whether the action handler should actively prune the operation
425:             * history when invalid operations are encountered. The default value is
426:             * <code>false</code>.
427:             * 
428:             * @param prune
429:             *            <code>true</code> if the history should be pruned by the
430:             *            handler, and <code>false</code> if it should not.
431:             * 
432:             */
433:            public void setPruneHistory(boolean prune) {
434:                pruning = prune;
435:            }
436:
437:            /**
438:             * Update enabling and labels according to the current status of the
439:             * operation history.
440:             */
441:            public void update() {
442:                if (isInvalid()) {
443:                    return;
444:                }
445:
446:                boolean enabled = shouldBeEnabled();
447:                String text, tooltipText;
448:                if (enabled) {
449:                    tooltipText = NLS.bind(getTooltipString(), getOperation()
450:                            .getLabel());
451:                    text = NLS.bind(getCommandString(),
452:                            shortenText(getOperation().getLabel()));
453:                } else {
454:                    tooltipText = NLS
455:                            .bind(
456:                                    WorkbenchMessages.Operations_undoRedoCommandDisabled,
457:                                    getSimpleTooltipString());
458:                    text = getSimpleCommandString();
459:                    /*
460:                     * if there is nothing to do and we are pruning the history, flush
461:                     * the history of this context.
462:                     */
463:                    if (undoContext != null && pruning) {
464:                        flush();
465:                    }
466:                }
467:                setText(text);
468:                setToolTipText(tooltipText);
469:                setEnabled(enabled);
470:            }
471:
472:            /*
473:             * Shorten the specified command label if it is too long
474:             */
475:            private String shortenText(String message) {
476:                int length = message.length();
477:                if (length > MAX_LABEL_LENGTH) {
478:                    StringBuffer result = new StringBuffer();
479:                    int mid = MAX_LABEL_LENGTH / 2;
480:                    result.append(message.substring(0, mid));
481:                    result.append("..."); //$NON-NLS-1$
482:                    result.append(message.substring(length - mid));
483:                    return result.toString();
484:                }
485:                return message;
486:            }
487:
488:            /*
489:             * Report the specified exception to the log and to the user.
490:             */
491:            final void reportException(Throwable t) {
492:                // get any nested exceptions
493:                Throwable nestedException = StatusUtil.getCause(t);
494:                Throwable exception = (nestedException == null) ? t
495:                        : nestedException;
496:
497:                // Messages
498:                String exceptionMessage = exception.getMessage();
499:                if (exceptionMessage == null) {
500:                    exceptionMessage = WorkbenchMessages.WorkbenchWindow_exceptionMessage;
501:                }
502:                IStatus status = StatusUtil.newStatus(
503:                        WorkbenchPlugin.PI_WORKBENCH, exceptionMessage,
504:                        exception);
505:
506:                // Log and show the problem
507:                WorkbenchPlugin.log(exceptionMessage, status);
508:                StatusUtil.handleStatus(status, StatusManager.SHOW,
509:                        getWorkbenchWindow().getShell());
510:            }
511:
512:            /*
513:             * Answer true if the receiver is not valid for running commands, accessing
514:             * the history, etc.
515:             */
516:            final boolean isInvalid() {
517:                return undoContext == null || site == null;
518:            }
519:
520:            /*
521:             * Get the undo context that should be used.
522:             */
523:            final IUndoContext getUndoContext() {
524:                // If no context was specified, or the specified one is not
525:                // in use, use the workbench context.
526:                if (undoContext == null || !contextActive) {
527:                    return PlatformUI.getWorkbench().getOperationSupport()
528:                            .getUndoContext();
529:                }
530:                return undoContext;
531:            }
532:
533:            /*
534:             * The undo context has been set. Check whether there is undo or redo
535:             * history available and set the contextActive flag accordingly. We check
536:             * both undo and redo here because we don't ever want the undo/redo action
537:             * handlers to have different values for contextActive.
538:             */
539:            private void checkUndoContext() {
540:                if (undoContext == null) {
541:                    return;
542:                }
543:                contextActive = getHistory().getUndoOperation(undoContext) != null
544:                        || getHistory().getRedoOperation(undoContext) != null;
545:            }
546:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.