Source Code Cross Referenced for NewKeysPreferencePage.java in  » IDE-Eclipse » ui-workbench » org » eclipse » ui » internal » keys » 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.internal.keys 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Copyright (c) 2005, 2007 IBM Corporation and others.
0003:         * All rights reserved. This program and the accompanying materials
0004:         * are made available under the terms of the Eclipse Public License v1.0
0005:         * which accompanies this distribution, and is available at
0006:         * http://www.eclipse.org/legal/epl-v10.html
0007:         *
0008:         * Contributors:
0009:         *     IBM Corporation - initial API and implementation
0010:         *******************************************************************************/package org.eclipse.ui.internal.keys;
0011:
0012:        import java.io.IOException;
0013:        import java.net.URL;
0014:        import java.util.ArrayList;
0015:        import java.util.Arrays;
0016:        import java.util.Collection;
0017:        import java.util.Collections;
0018:        import java.util.HashSet;
0019:        import java.util.Iterator;
0020:        import java.util.List;
0021:        import java.util.Locale;
0022:        import java.util.Set;
0023:
0024:        import org.eclipse.core.commands.Category;
0025:        import org.eclipse.core.commands.Command;
0026:        import org.eclipse.core.commands.CommandManager;
0027:        import org.eclipse.core.commands.ParameterizedCommand;
0028:        import org.eclipse.core.commands.common.NamedHandleObject;
0029:        import org.eclipse.core.commands.common.NamedHandleObjectComparator;
0030:        import org.eclipse.core.commands.common.NotDefinedException;
0031:        import org.eclipse.core.commands.contexts.Context;
0032:        import org.eclipse.core.commands.contexts.ContextManager;
0033:        import org.eclipse.core.commands.util.Tracing;
0034:        import org.eclipse.core.databinding.observable.Diffs;
0035:        import org.eclipse.core.databinding.observable.IStaleListener;
0036:        import org.eclipse.core.databinding.observable.StaleEvent;
0037:        import org.eclipse.core.databinding.observable.set.IObservableSet;
0038:        import org.eclipse.core.databinding.observable.set.ISetChangeListener;
0039:        import org.eclipse.core.databinding.observable.set.ObservableSet;
0040:        import org.eclipse.core.databinding.observable.set.SetChangeEvent;
0041:        import org.eclipse.core.databinding.observable.set.UnionSet;
0042:        import org.eclipse.core.databinding.observable.set.WritableSet;
0043:        import org.eclipse.core.databinding.observable.value.IObservableValue;
0044:        import org.eclipse.core.databinding.observable.value.IValueChangeListener;
0045:        import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
0046:        import org.eclipse.core.runtime.IStatus;
0047:        import org.eclipse.core.runtime.Status;
0048:        import org.eclipse.jface.bindings.Binding;
0049:        import org.eclipse.jface.bindings.BindingManager;
0050:        import org.eclipse.jface.bindings.Scheme;
0051:        import org.eclipse.jface.bindings.keys.KeyBinding;
0052:        import org.eclipse.jface.bindings.keys.KeySequence;
0053:        import org.eclipse.jface.bindings.keys.KeySequenceText;
0054:        import org.eclipse.jface.bindings.keys.KeyStroke;
0055:        import org.eclipse.jface.contexts.IContextIds;
0056:        import org.eclipse.jface.databinding.swt.SWTObservables;
0057:        import org.eclipse.jface.databinding.viewers.ViewersObservables;
0058:        import org.eclipse.jface.dialogs.IDialogConstants;
0059:        import org.eclipse.jface.dialogs.IDialogSettings;
0060:        import org.eclipse.jface.dialogs.MessageDialog;
0061:        import org.eclipse.jface.internal.databinding.provisional.swt.ControlUpdater;
0062:        import org.eclipse.jface.preference.PreferencePage;
0063:        import org.eclipse.jface.resource.DeviceResourceException;
0064:        import org.eclipse.jface.resource.ImageDescriptor;
0065:        import org.eclipse.jface.resource.JFaceResources;
0066:        import org.eclipse.jface.resource.LocalResourceManager;
0067:        import org.eclipse.jface.util.IPropertyChangeListener;
0068:        import org.eclipse.jface.util.PropertyChangeEvent;
0069:        import org.eclipse.jface.viewers.AbstractListViewer;
0070:        import org.eclipse.jface.viewers.ArrayContentProvider;
0071:        import org.eclipse.jface.viewers.ComboViewer;
0072:        import org.eclipse.jface.viewers.IBaseLabelProvider;
0073:        import org.eclipse.jface.viewers.ISelection;
0074:        import org.eclipse.jface.viewers.ISelectionChangedListener;
0075:        import org.eclipse.jface.viewers.IStructuredSelection;
0076:        import org.eclipse.jface.viewers.ITableLabelProvider;
0077:        import org.eclipse.jface.viewers.ITreeContentProvider;
0078:        import org.eclipse.jface.viewers.LabelProvider;
0079:        import org.eclipse.jface.viewers.NamedHandleObjectLabelProvider;
0080:        import org.eclipse.jface.viewers.SelectionChangedEvent;
0081:        import org.eclipse.jface.viewers.StructuredSelection;
0082:        import org.eclipse.jface.viewers.TreeViewer;
0083:        import org.eclipse.jface.viewers.Viewer;
0084:        import org.eclipse.jface.viewers.ViewerComparator;
0085:        import org.eclipse.jface.window.Window;
0086:        import org.eclipse.swt.SWT;
0087:        import org.eclipse.swt.custom.BusyIndicator;
0088:        import org.eclipse.swt.events.DisposeEvent;
0089:        import org.eclipse.swt.events.DisposeListener;
0090:        import org.eclipse.swt.events.FocusEvent;
0091:        import org.eclipse.swt.events.FocusListener;
0092:        import org.eclipse.swt.events.SelectionAdapter;
0093:        import org.eclipse.swt.events.SelectionEvent;
0094:        import org.eclipse.swt.events.SelectionListener;
0095:        import org.eclipse.swt.graphics.Image;
0096:        import org.eclipse.swt.graphics.Point;
0097:        import org.eclipse.swt.layout.GridData;
0098:        import org.eclipse.swt.layout.GridLayout;
0099:        import org.eclipse.swt.widgets.Button;
0100:        import org.eclipse.swt.widgets.Combo;
0101:        import org.eclipse.swt.widgets.Composite;
0102:        import org.eclipse.swt.widgets.Control;
0103:        import org.eclipse.swt.widgets.Display;
0104:        import org.eclipse.swt.widgets.Label;
0105:        import org.eclipse.swt.widgets.Menu;
0106:        import org.eclipse.swt.widgets.MenuItem;
0107:        import org.eclipse.swt.widgets.Text;
0108:        import org.eclipse.swt.widgets.Tree;
0109:        import org.eclipse.swt.widgets.TreeColumn;
0110:        import org.eclipse.ui.IWorkbench;
0111:        import org.eclipse.ui.IWorkbenchPreferencePage;
0112:        import org.eclipse.ui.PlatformUI;
0113:        import org.eclipse.ui.commands.ICommandService;
0114:        import org.eclipse.ui.contexts.IContextService;
0115:        import org.eclipse.ui.dialogs.FilteredTree;
0116:        import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
0117:        import org.eclipse.ui.internal.WorkbenchPlugin;
0118:        import org.eclipse.ui.internal.commands.ICommandImageService;
0119:        import org.eclipse.ui.internal.misc.Policy;
0120:        import org.eclipse.ui.internal.misc.StatusUtil;
0121:        import org.eclipse.ui.internal.util.BundleUtility;
0122:        import org.eclipse.ui.internal.util.Util;
0123:        import org.eclipse.ui.keys.IBindingService;
0124:        import org.eclipse.ui.statushandlers.StatusManager;
0125:
0126:        /**
0127:         * <p>
0128:         * A preference page that is capable of displaying and editing the bindings
0129:         * between commands and user input events. These are typically things like
0130:         * keyboard shortcuts.
0131:         * </p>
0132:         * <p>
0133:         * This preference page has four general types of methods. Create methods are
0134:         * called when the page is first made visible. They are responsible for creating
0135:         * all of the widgets, and laying them out within the preference page. Fill
0136:         * methods populate the contents of the widgets that contain collections of data
0137:         * from which items can be selected. The select methods respond to selection
0138:         * events from the user, such as a button press or a table selection. The update
0139:         * methods update the contents of various widgets based on the current state of
0140:         * the user interface. For example, the command name label will always try to
0141:         * match the current select in the binding table.
0142:         * </p>
0143:         * 
0144:         * @since 3.2
0145:         */
0146:        public final class NewKeysPreferencePage extends PreferencePage
0147:                implements  IWorkbenchPreferencePage {
0148:
0149:            private static boolean DEBUG = Policy.DEBUG_KEY_BINDINGS;
0150:
0151:            private static final String TRACING_COMPONENT = "NewKeysPref"; //$NON-NLS-1$
0152:
0153:            /**
0154:             * @since 3.3
0155:             * 
0156:             */
0157:            private final class ResortColumn extends SelectionAdapter {
0158:                private final BindingComparator comparator;
0159:                private final TreeColumn treeColumn;
0160:                private final Tree tree;
0161:                private final int column;
0162:
0163:                /**
0164:                 * @param comparator
0165:                 * @param commandNameColumn
0166:                 * @param tree
0167:                 */
0168:                private ResortColumn(BindingComparator comparator,
0169:                        TreeColumn treeColumn, Tree tree, int column) {
0170:                    this .comparator = comparator;
0171:                    this .treeColumn = treeColumn;
0172:                    this .tree = tree;
0173:                    this .column = column;
0174:                }
0175:
0176:                public void widgetSelected(SelectionEvent e) {
0177:                    if (comparator.getSortColumn() == column) {
0178:                        comparator.setAscending(!comparator.isAscending());
0179:                    }
0180:                    tree.setSortColumn(treeColumn);
0181:                    comparator.setSortColumn(column);
0182:                    tree.setSortDirection(comparator.isAscending() ? SWT.UP
0183:                            : SWT.DOWN);
0184:                    try {
0185:                        filteredTree.getViewer().getTree().setRedraw(false);
0186:                        filteredTree.getViewer().refresh();
0187:                    } finally {
0188:                        filteredTree.getViewer().getTree().setRedraw(true);
0189:                    }
0190:                }
0191:            }
0192:
0193:            private class ObservableSetContentProvider implements 
0194:                    ITreeContentProvider {
0195:
0196:                private class KnownElementsSet extends ObservableSet {
0197:
0198:                    KnownElementsSet(Set wrappedSet) {
0199:                        super (SWTObservables.getRealm(Display.getDefault()),
0200:                                wrappedSet, Object.class);
0201:                    }
0202:
0203:                    void doFireDiff(Set added, Set removed) {
0204:                        fireSetChange(Diffs.createSetDiff(added, removed));
0205:                    }
0206:
0207:                    void doFireStale(boolean isStale) {
0208:                        if (isStale) {
0209:                            fireStale();
0210:                        } else {
0211:                            fireChange();
0212:                        }
0213:                    }
0214:                }
0215:
0216:                private IObservableSet readableSet;
0217:
0218:                private Viewer viewer;
0219:
0220:                /**
0221:                 * This readableSet returns the same elements as the input readableSet.
0222:                 * However, it only fires events AFTER the elements have been added or
0223:                 * removed from the viewer.
0224:                 */
0225:                private KnownElementsSet knownElements;
0226:
0227:                private ISetChangeListener listener = new ISetChangeListener() {
0228:
0229:                    public void handleSetChange(SetChangeEvent event) {
0230:                        boolean wasStale = knownElements.isStale();
0231:                        if (isDisposed()) {
0232:                            return;
0233:                        }
0234:                        doDiff(event.diff.getAdditions(), event.diff
0235:                                .getRemovals(), true);
0236:                        if (!wasStale && event.getObservableSet().isStale()) {
0237:                            knownElements.doFireStale(true);
0238:                        }
0239:                    }
0240:                };
0241:
0242:                private IStaleListener staleListener = new IStaleListener() {
0243:                    public void handleStale(StaleEvent event) {
0244:                        knownElements.doFireStale(event.getObservable()
0245:                                .isStale());
0246:                    }
0247:                };
0248:
0249:                /**
0250:                 * 
0251:                 */
0252:                public ObservableSetContentProvider() {
0253:                    readableSet = new ObservableSet(SWTObservables
0254:                            .getRealm(Display.getDefault()),
0255:                            Collections.EMPTY_SET, Object.class) {
0256:                    };
0257:                    knownElements = new KnownElementsSet(readableSet);
0258:                }
0259:
0260:                public void dispose() {
0261:                    setInput(null);
0262:                }
0263:
0264:                private void doDiff(Set added, Set removed, boolean updateViewer) {
0265:                    knownElements.doFireDiff(added, Collections.EMPTY_SET);
0266:
0267:                    if (updateViewer) {
0268:                        if (added.size() > 20 || removed.size() > 20) {
0269:                            viewer.refresh();
0270:                        } else {
0271:                            Object[] toAdd = added.toArray();
0272:                            if (viewer instanceof  TreeViewer) {
0273:                                TreeViewer tv = (TreeViewer) viewer;
0274:                                tv.add(model, toAdd);
0275:                            } else if (viewer instanceof  AbstractListViewer) {
0276:                                AbstractListViewer lv = (AbstractListViewer) viewer;
0277:                                lv.add(toAdd);
0278:                            }
0279:                            Object[] toRemove = removed.toArray();
0280:                            if (viewer instanceof  TreeViewer) {
0281:                                TreeViewer tv = (TreeViewer) viewer;
0282:                                tv.remove(toRemove);
0283:                            } else if (viewer instanceof  AbstractListViewer) {
0284:                                AbstractListViewer lv = (AbstractListViewer) viewer;
0285:                                lv.remove(toRemove);
0286:                            }
0287:                        }
0288:                    }
0289:                    knownElements.doFireDiff(Collections.EMPTY_SET, removed);
0290:                }
0291:
0292:                public Object[] getElements(Object inputElement) {
0293:                    return readableSet.toArray();
0294:                }
0295:
0296:                /**
0297:                 * Returns the readableSet of elements known to this content provider.
0298:                 * Items are added to this readableSet before being added to the viewer,
0299:                 * and they are removed after being removed from the viewer. The
0300:                 * readableSet is always updated after the viewer. This is intended for
0301:                 * use by label providers, as it will always return the items that need
0302:                 * labels.
0303:                 * 
0304:                 * @return readableSet of items that will need labels
0305:                 */
0306:                public IObservableSet getKnownElements() {
0307:                    return knownElements;
0308:                }
0309:
0310:                public void inputChanged(Viewer viewer, Object oldInput,
0311:                        Object newInput) {
0312:                    this .viewer = viewer;
0313:
0314:                    if (newInput != null
0315:                            && !(newInput instanceof  IObservableSet)) {
0316:                        throw new IllegalArgumentException(
0317:                                "This content provider only works with input of type IReadableSet"); //$NON-NLS-1$
0318:                    }
0319:
0320:                    setInput((IObservableSet) newInput);
0321:                }
0322:
0323:                private boolean isDisposed() {
0324:                    return viewer.getControl() == null
0325:                            || viewer.getControl().isDisposed();
0326:                }
0327:
0328:                private void setInput(IObservableSet newSet) {
0329:                    boolean updateViewer = true;
0330:                    if (newSet == null) {
0331:                        newSet = new ObservableSet(SWTObservables
0332:                                .getRealm(Display.getDefault()),
0333:                                Collections.EMPTY_SET, Object.class) {
0334:                        };
0335:                        // don't update the viewer - its input is null
0336:                        updateViewer = false;
0337:                    }
0338:
0339:                    boolean wasStale = false;
0340:                    if (readableSet != null) {
0341:                        wasStale = readableSet.isStale();
0342:                        readableSet.removeSetChangeListener(listener);
0343:                        readableSet.removeStaleListener(staleListener);
0344:                    }
0345:
0346:                    HashSet additions = new HashSet();
0347:                    HashSet removals = new HashSet();
0348:
0349:                    additions.addAll(newSet);
0350:                    additions.removeAll(readableSet);
0351:
0352:                    removals.addAll(readableSet);
0353:                    removals.removeAll(newSet);
0354:
0355:                    readableSet = newSet;
0356:
0357:                    doDiff(additions, removals, updateViewer);
0358:
0359:                    if (readableSet != null) {
0360:                        readableSet.addSetChangeListener(listener);
0361:                        readableSet.addStaleListener(staleListener);
0362:                    }
0363:
0364:                    boolean isStale = (readableSet != null && readableSet
0365:                            .isStale());
0366:                    if (isStale != wasStale) {
0367:                        knownElements.doFireStale(isStale);
0368:                    }
0369:                }
0370:
0371:                /*
0372:                 * (non-Javadoc)
0373:                 * 
0374:                 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
0375:                 */
0376:                public Object[] getChildren(Object parentElement) {
0377:                    // TODO Auto-generated method stub
0378:                    return null;
0379:                }
0380:
0381:                /*
0382:                 * (non-Javadoc)
0383:                 * 
0384:                 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
0385:                 */
0386:                public Object getParent(Object element) {
0387:                    // TODO Auto-generated method stub
0388:                    return null;
0389:                }
0390:
0391:                /*
0392:                 * (non-Javadoc)
0393:                 * 
0394:                 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
0395:                 */
0396:                public boolean hasChildren(Object element) {
0397:                    // TODO Auto-generated method stub
0398:                    return false;
0399:                }
0400:
0401:            }
0402:
0403:            /**
0404:             * A FilteredTree that provides a combo which is used to organize and
0405:             * display elements in the tree according to the selected criteria.
0406:             * 
0407:             */
0408:            protected class CategoryFilterTree extends FilteredTree {
0409:
0410:                private CategoryPatternFilter filter;
0411:
0412:                /**
0413:                 * Constructor for PatternFilteredTree.
0414:                 * 
0415:                 * @param parent
0416:                 * @param treeStyle
0417:                 * @param filter
0418:                 */
0419:                protected CategoryFilterTree(Composite parent, int treeStyle,
0420:                        CategoryPatternFilter filter) {
0421:                    super (parent, treeStyle, filter);
0422:                    this .filter = filter;
0423:                }
0424:
0425:                public void filterCategories(boolean b) {
0426:                    filter.filterCategories(b);
0427:                    textChanged();
0428:                }
0429:
0430:                public boolean isFilteringCategories() {
0431:                    return filter.isFilteringCategories();
0432:                }
0433:            }
0434:
0435:            /**
0436:             * A label provider that simply extracts the command name and the formatted
0437:             * trigger sequence from a given binding, and matches them to the correct
0438:             * column.
0439:             */
0440:            private final class BindingLabelProvider extends LabelProvider
0441:                    implements  ITableLabelProvider {
0442:
0443:                /**
0444:                 * The index of the column containing the command name.
0445:                 */
0446:                private static final int COLUMN_COMMAND = 0;
0447:
0448:                /**
0449:                 * The index of the column containing the trigger sequence.
0450:                 */
0451:                private static final int COLUMN_TRIGGER_SEQUENCE = 1;
0452:
0453:                /**
0454:                 * The index of the column containing the trigger sequence.
0455:                 */
0456:                private static final int COLUMN_WHEN = 2;
0457:
0458:                /**
0459:                 * The index of the column containing the Category.
0460:                 */
0461:                private static final int COLUMN_CATEGORY = 3;
0462:
0463:                /**
0464:                 * The index of the column with the image for User binding
0465:                 */
0466:                private static final int COLUMN_USER = 4;
0467:
0468:                /**
0469:                 * A resource manager for this preference page.
0470:                 */
0471:                private final LocalResourceManager localResourceManager = new LocalResourceManager(
0472:                        JFaceResources.getResources());
0473:
0474:                public final void dispose() {
0475:                    super .dispose();
0476:                    localResourceManager.dispose();
0477:                }
0478:
0479:                public final Image getColumnImage(final Object element,
0480:                        final int columnIndex) {
0481:                    final Object value = element;
0482:                    if (value instanceof  Binding) {
0483:                        switch (columnIndex) {
0484:                        case COLUMN_COMMAND:
0485:                            final ParameterizedCommand parameterizedCommand = ((Binding) value)
0486:                                    .getParameterizedCommand();
0487:                            if (parameterizedCommand != null) {
0488:                                final String commandId = parameterizedCommand
0489:                                        .getId();
0490:                                final ImageDescriptor imageDescriptor = commandImageService
0491:                                        .getImageDescriptor(commandId);
0492:                                if (imageDescriptor == null) {
0493:                                    return null;
0494:                                }
0495:                                try {
0496:                                    return localResourceManager
0497:                                            .createImage(imageDescriptor);
0498:                                } catch (final DeviceResourceException e) {
0499:                                    final String message = "Problem retrieving image for a command '" //$NON-NLS-1$
0500:                                            + commandId + '\'';
0501:                                    final IStatus status = new Status(
0502:                                            IStatus.ERROR,
0503:                                            WorkbenchPlugin.PI_WORKBENCH, 0,
0504:                                            message, e);
0505:                                    WorkbenchPlugin.log(message, status);
0506:                                }
0507:                            }
0508:                            return null;
0509:
0510:                        case COLUMN_USER:
0511:                            if (((Binding) value).getType() == Binding.USER)
0512:                                return ImageFactory.getImage("change"); //$NON-NLS-1$
0513:                            return ImageFactory.getImage("blank"); //$NON-NLS-1$
0514:                        }
0515:
0516:                    } else if (value instanceof  ParameterizedCommand) {
0517:                        switch (columnIndex) {
0518:                        case COLUMN_COMMAND:
0519:                            final ParameterizedCommand parameterizedCommand = (ParameterizedCommand) value;
0520:                            final String commandId = parameterizedCommand
0521:                                    .getId();
0522:                            final ImageDescriptor imageDescriptor = commandImageService
0523:                                    .getImageDescriptor(commandId);
0524:                            if (imageDescriptor == null) {
0525:                                return null;
0526:                            }
0527:                            try {
0528:                                return localResourceManager
0529:                                        .createImage(imageDescriptor);
0530:                            } catch (final DeviceResourceException e) {
0531:                                final String message = "Problem retrieving image for a command '" //$NON-NLS-1$
0532:                                        + commandId + '\'';
0533:                                final IStatus status = new Status(
0534:                                        IStatus.ERROR,
0535:                                        WorkbenchPlugin.PI_WORKBENCH, 0,
0536:                                        message, e);
0537:                                WorkbenchPlugin.log(message, status);
0538:                            }
0539:                            return null;
0540:                        case COLUMN_USER:
0541:                            return ImageFactory.getImage("blank"); //$NON-NLS-1$
0542:                        }
0543:
0544:                    } else if ((value instanceof  Category)
0545:                            || (value instanceof  String)) {
0546:                        switch (columnIndex) {
0547:                        case COLUMN_COMMAND:
0548:                            final URL url = BundleUtility.find(
0549:                                    PlatformUI.PLUGIN_ID,
0550:                                    ICON_GROUP_OF_BINDINGS);
0551:                            final ImageDescriptor imageDescriptor = ImageDescriptor
0552:                                    .createFromURL(url);
0553:                            try {
0554:                                return localResourceManager
0555:                                        .createImage(imageDescriptor);
0556:                            } catch (final DeviceResourceException e) {
0557:                                final String message = "Problem retrieving image for groups of bindings: '" //$NON-NLS-1$
0558:                                        + ICON_GROUP_OF_BINDINGS + '\'';
0559:                                final IStatus status = new Status(
0560:                                        IStatus.ERROR,
0561:                                        WorkbenchPlugin.PI_WORKBENCH, 0,
0562:                                        message, e);
0563:                                WorkbenchPlugin.log(message, status);
0564:                            }
0565:                        }
0566:
0567:                    }
0568:
0569:                    return null;
0570:                }
0571:
0572:                private boolean checkConflict(Binding binding) {
0573:                    Collection matches = (Collection) localChangeManager
0574:                            .getActiveBindingsDisregardingContext().get(
0575:                                    binding.getTriggerSequence());
0576:                    if (matches != null) {
0577:                        Iterator i = matches.iterator();
0578:                        while (i.hasNext()) {
0579:                            Binding b = (Binding) i.next();
0580:                            if (binding != b
0581:                                    && b.getContextId().equals(
0582:                                            binding.getContextId())
0583:                                    && b.getSchemeId().equals(
0584:                                            binding.getSchemeId())) {
0585:                                return true;
0586:                            }
0587:                        }
0588:                    }
0589:                    return false;
0590:                }
0591:
0592:                public final String getColumnText(final Object element,
0593:                        final int columnIndex) {
0594:                    final Object value = element;
0595:                    if (value instanceof  Binding) {
0596:                        final Binding binding = (Binding) value;
0597:                        switch (columnIndex) {
0598:                        case COLUMN_COMMAND:
0599:                            try {
0600:                                return binding.getParameterizedCommand()
0601:                                        .getName();
0602:
0603:                            } catch (final NotDefinedException e) {
0604:                                return NewKeysPreferenceMessages.Undefined_Command;
0605:                            }
0606:                        case COLUMN_TRIGGER_SEQUENCE:
0607:                            if (checkConflict(binding)) {
0608:                                return "*" + binding.getTriggerSequence().format(); //$NON-NLS-1$
0609:                            }
0610:                            return binding.getTriggerSequence().format();
0611:
0612:                        case COLUMN_WHEN:
0613:                            try {
0614:                                return contextService.getContext(
0615:                                        binding.getContextId()).getName();
0616:                            } catch (NotDefinedException e1) {
0617:                                return NewKeysPreferenceMessages.Undefined_Context;
0618:                            }
0619:                        case COLUMN_CATEGORY:
0620:                            try {
0621:                                return binding.getParameterizedCommand()
0622:                                        .getCommand().getCategory().getName();
0623:                            } catch (NotDefinedException e) {
0624:                                return NewKeysPreferenceMessages.Unavailable_Category;
0625:                            }
0626:                        default:
0627:                            return null;
0628:                        }
0629:                    } else if (value instanceof  Category) {
0630:                        if (columnIndex == COLUMN_COMMAND) {
0631:                            try {
0632:                                return ((Category) value).getName();
0633:                            } catch (final NotDefinedException e) {
0634:                                return NewKeysPreferenceMessages.Unavailable_Category;
0635:                            }
0636:                        }
0637:
0638:                        return null;
0639:
0640:                    } else if (value instanceof  String) {
0641:                        // This is a context.
0642:                        if (columnIndex == COLUMN_COMMAND) {
0643:                            try {
0644:                                return contextService
0645:                                        .getContext((String) value).getName();
0646:                            } catch (final NotDefinedException e) {
0647:                                return NewKeysPreferenceMessages.Undefined_Context;
0648:                            }
0649:                        }
0650:
0651:                        return null;
0652:                    } else if (value instanceof  ParameterizedCommand) {
0653:                        if (columnIndex == COLUMN_COMMAND) {
0654:                            try {
0655:                                return ((ParameterizedCommand) value).getName();
0656:                            } catch (final NotDefinedException e) {
0657:                                return NewKeysPreferenceMessages.Undefined_Command;
0658:                            }
0659:                        }
0660:                        if (columnIndex == COLUMN_TRIGGER_SEQUENCE)
0661:                            return ""; //$NON-NLS-1$
0662:
0663:                        if (columnIndex == COLUMN_WHEN)
0664:                            return ""; //$NON-NLS-1$
0665:
0666:                        if (columnIndex == COLUMN_CATEGORY) {
0667:                            try {
0668:                                return ((ParameterizedCommand) value)
0669:                                        .getCommand().getCategory().getName();
0670:                            } catch (NotDefinedException e) {
0671:                                return NewKeysPreferenceMessages.Unavailable_Category;
0672:                            }
0673:                        }
0674:                        return null;
0675:                    }
0676:
0677:                    return null;
0678:                }
0679:
0680:                /*
0681:                 * (non-Javadoc)
0682:                 * 
0683:                 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
0684:                 */
0685:                public String getText(Object element) {
0686:                    String rc = getColumnText(element, 0);
0687:                    if (rc == null) {
0688:                        super .getText(element);
0689:                    }
0690:                    StringBuffer buf = new StringBuffer(rc);
0691:                    for (int i = 1; i < COLUMN_USER; i++) {
0692:                        String text = getColumnText(element, i);
0693:                        if (text != null) {
0694:                            buf.append(' ');
0695:                            buf.append(text);
0696:                        }
0697:                    }
0698:                    return buf.toString();
0699:                }
0700:            }
0701:
0702:            /**
0703:             * Sorts the bindings in the filtered tree based on the current grouping.
0704:             */
0705:            private final class BindingComparator extends ViewerComparator {
0706:
0707:                private int sortColumn = 0;
0708:
0709:                private int lastSortColumn = 0;
0710:
0711:                private boolean ascending = true;
0712:
0713:                public final int category(final Object element) {
0714:                    switch (grouping) {
0715:                    case GROUPING_CATEGORY:
0716:                        // TODO This has to be done with something other than the hash.
0717:                        try {
0718:                            final ParameterizedCommand command = (element instanceof  ParameterizedCommand) ? (ParameterizedCommand) element
0719:                                    : ((Binding) element)
0720:                                            .getParameterizedCommand();
0721:                            return command.getCommand().getCategory()
0722:                                    .hashCode();
0723:                        } catch (final NotDefinedException e) {
0724:                            return 0;
0725:                        }
0726:                    case GROUPING_CONTEXT:
0727:                        // TODO This has to be done with something other than the hash.
0728:                        if (element instanceof  Binding) {
0729:                            return ((Binding) element).getContextId()
0730:                                    .hashCode();
0731:                        }
0732:                    case GROUPING_NONE:
0733:                    default:
0734:                        return 0;
0735:                    }
0736:                }
0737:
0738:                public final int compare(final Viewer viewer, final Object a,
0739:                        final Object b) {
0740:
0741:                    int result = compareColumn(viewer, a, b, sortColumn);
0742:                    if (result == 0 && sortColumn != lastSortColumn) {
0743:                        result = compareColumn(viewer, a, b, lastSortColumn);
0744:                    }
0745:                    return ascending ? result : (-1) * result;
0746:                }
0747:
0748:                private int compareColumn(final Viewer viewer, final Object a,
0749:                        final Object b, final int columnNumber) {
0750:                    if (columnNumber == BindingLabelProvider.COLUMN_USER) {
0751:                        return sortUser(viewer, a, b);
0752:                    }
0753:                    IBaseLabelProvider baseLabel = ((TreeViewer) viewer)
0754:                            .getLabelProvider();
0755:                    if (baseLabel instanceof  ITableLabelProvider) {
0756:                        ITableLabelProvider tableProvider = (ITableLabelProvider) baseLabel;
0757:                        String e1p = tableProvider.getColumnText(a,
0758:                                columnNumber);
0759:                        String e2p = tableProvider.getColumnText(b,
0760:                                columnNumber);
0761:                        if (e1p != null && e2p != null) {
0762:                            return getComparator().compare(e1p, e2p);
0763:                        }
0764:                    }
0765:                    return 0;
0766:                }
0767:
0768:                private int sortUser(final Viewer viewer, final Object a,
0769:                        final Object b) {
0770:                    int typeA = (a instanceof  Binding ? ((Binding) a).getType()
0771:                            : Binding.SYSTEM);
0772:                    int typeB = (b instanceof  Binding ? ((Binding) b).getType()
0773:                            : Binding.SYSTEM);
0774:                    int result = typeA - typeB;
0775:                    return result;
0776:                }
0777:
0778:                /**
0779:                 * @return Returns the sortColumn.
0780:                 */
0781:                public int getSortColumn() {
0782:                    return sortColumn;
0783:                }
0784:
0785:                /**
0786:                 * @param sortColumn
0787:                 *            The sortColumn to set.
0788:                 */
0789:                public void setSortColumn(int sortColumn) {
0790:                    lastSortColumn = this .sortColumn;
0791:                    if (lastSortColumn != sortColumn) {
0792:                        ascending = true;
0793:                    }
0794:                    this .sortColumn = sortColumn;
0795:                }
0796:
0797:                /**
0798:                 * @return Returns the ascending.
0799:                 */
0800:                public boolean isAscending() {
0801:                    return ascending;
0802:                }
0803:
0804:                /**
0805:                 * @param ascending
0806:                 *            The ascending to set.
0807:                 */
0808:                public void setAscending(boolean ascending) {
0809:                    this .ascending = ascending;
0810:                }
0811:            }
0812:
0813:            /**
0814:             * The constant value for <code>grouping</code> when the bindings should
0815:             * be grouped by category.
0816:             */
0817:            private static final int GROUPING_CATEGORY = 0;
0818:
0819:            /**
0820:             * The constant value for <code>grouping</code> when the bindings should
0821:             * be grouped by context.
0822:             */
0823:            private static final int GROUPING_CONTEXT = 1;
0824:
0825:            /**
0826:             * The constant value for <code>grouping</code> when the bindings should
0827:             * not be grouped (i.e., they should be displayed in a flat list).
0828:             */
0829:            private static final int GROUPING_NONE = 2;
0830:
0831:            /**
0832:             * The path at which the icon for "groups of bindings" is located.
0833:             */
0834:            private static final String ICON_GROUP_OF_BINDINGS = "$nl$/icons/full/obj16/keygroups_obj.gif"; //$NON-NLS-1$
0835:
0836:            private static final String CONTEXT_ID_ACTION_SETS = "org.eclipse.ui.contexts.actionSet"; //$NON-NLS-1$
0837:
0838:            private static final String CONTEXT_ID_INTERNAL = ".internal."; //$NON-NLS-1$
0839:
0840:            /**
0841:             * The number of items to show in the bindings table tree.
0842:             */
0843:            private static final int ITEMS_TO_SHOW = 7;
0844:
0845:            /**
0846:             * A comparator that can be used for display of
0847:             * <code>NamedHandleObject</code> instances to the end user.
0848:             */
0849:            private static final NamedHandleObjectComparator NAMED_HANDLE_OBJECT_COMPARATOR = new NamedHandleObjectComparator();
0850:
0851:            public final static String TAG_DIALOG_SECTION = "org.eclipse.ui.preferences.keysPreferencePage"; //$NON-NLS-1$
0852:
0853:            private final String TAG_FIELD = "showAllField"; //$NON-NLS-1$
0854:
0855:            private static final String TAG_FILTER_ACTION_SETS = "actionSetFilter"; //$NON-NLS-1$
0856:
0857:            private static final String TAG_FILTER_INTERNAL = "internalFilter"; //$NON-NLS-1$
0858:
0859:            private static final String TAG_FILTER_UNCAT = "uncategorizedFilter"; //$NON-NLS-1$
0860:
0861:            /**
0862:             * Sorts the given array of <code>NamedHandleObject</code> instances based
0863:             * on their name. This is generally useful if they will be displayed to an
0864:             * end users.
0865:             * 
0866:             * @param objects
0867:             *            The objects to be sorted; must not be <code>null</code>.
0868:             * @return The same array, but sorted in place; never <code>null</code>.
0869:             */
0870:            private static final NamedHandleObject[] sortByName(
0871:                    final NamedHandleObject[] objects) {
0872:                Arrays.sort(objects, NAMED_HANDLE_OBJECT_COMPARATOR);
0873:                return objects;
0874:            }
0875:
0876:            /**
0877:             * The workbench's binding service. This binding service is used to access
0878:             * the current set of bindings, and to persist changes.
0879:             */
0880:            private IBindingService bindingService;
0881:
0882:            /**
0883:             * The text widget containing the key sequence. This value is
0884:             * <code>null</code> until the controls are created.
0885:             */
0886:            private Text bindingText;
0887:
0888:            /**
0889:             * The workbench's command image service. This command image service is used
0890:             * to provide an icon beside each command.
0891:             */
0892:            private ICommandImageService commandImageService;
0893:
0894:            /**
0895:             * The label containing the name of the currently selected binding's
0896:             * command. This value is <code>null</code> until the controls are
0897:             * created.
0898:             */
0899:            private Label commandNameValueLabel;
0900:
0901:            /**
0902:             * The workbench's command service. This command service is used to access
0903:             * the list of commands.
0904:             */
0905:            private ICommandService commandService;
0906:
0907:            /**
0908:             * The workbench's context service. This context service is used to access
0909:             * the list of contexts.
0910:             */
0911:            private IContextService contextService;
0912:
0913:            /**
0914:             * The label containing the description of the currently selected binding's
0915:             * command. This value is <code>null</code> until the controls are
0916:             * created.
0917:             */
0918:            private Text descriptionValueText;
0919:
0920:            /**
0921:             * The filtered tree containing the list of commands and bindings to edit.
0922:             */
0923:            private CategoryFilterTree filteredTree;
0924:
0925:            private CategoryPatternFilter patternFilter;
0926:
0927:            /**
0928:             * The grouping for the bindings tree. Either there should be no group
0929:             * (i.e., flat list), or the bindings should be grouped by either category
0930:             * or context.
0931:             */
0932:            private int grouping = GROUPING_NONE;
0933:
0934:            /**
0935:             * The key sequence entry widget containing the trigger sequence for the
0936:             * currently selected binding. This value is <code>null</code> until the
0937:             * controls are created.
0938:             */
0939:            private KeySequenceText keySequenceText;
0940:
0941:            /**
0942:             * A binding manager local to this preference page. When the page is
0943:             * initialized, the current bindings are read out from the binding service
0944:             * and placed in this manager. This manager is then updated as the user
0945:             * makes changes. When the user has finished, the contents of this manager
0946:             * are compared with the contents of the binding service. The changes are
0947:             * then persisted.
0948:             */
0949:            private BindingManager localChangeManager;
0950:
0951:            /**
0952:             * The context id of the binding which the user is trying to add. This value
0953:             * is derived from the binding that is selected at the time the user tried
0954:             * to add a binding. If this value is <code>null</code>, then the user is
0955:             * not currently trying to add a binding to a command that already has a
0956:             * binding.
0957:             */
0958:            private String markedContextId = null;
0959:
0960:            /**
0961:             * The parameterized command to which the user is currently trying to add a
0962:             * binding. If this value is <code>null</code>, then the user is not
0963:             * currently trying to add a binding to a command that already has a
0964:             * binding.
0965:             */
0966:            private ParameterizedCommand markedParameterizedCommand = null;
0967:
0968:            /**
0969:             * The combo box containing the list of possible schemes to choose from.
0970:             * This value is <code>null</code> until the contents are created.
0971:             */
0972:            private ComboViewer schemeCombo = null;
0973:
0974:            /**
0975:             * The check box controlling whether all commands should be shown in the
0976:             * filtered tree. This value is <code>null</code> until the contents are
0977:             * created.
0978:             */
0979:            private Button showAllCheckBox = null;
0980:
0981:            private boolean filterActionSetContexts = true;
0982:
0983:            private boolean filterInternalContexts = true;
0984:
0985:            private IObservableSet commandModel;
0986:
0987:            private IObservableSet bindingModel;
0988:
0989:            private UnionSet model;
0990:
0991:            /**
0992:             * The combo box containing the list of possible contexts to choose from.
0993:             * This value is <code>null</code> until the contents are create.
0994:             */
0995:            private ComboViewer whenCombo = null;
0996:
0997:            /**
0998:             * Adds a new binding based on an existing binding. The command and the
0999:             * context are copied from the existing binding. The scheme id is set to be
1000:             * the user's personal derivative scheme. The preference page is updated,
1001:             * and focus is placed in the key sequence field.
1002:             * 
1003:             * @param binding
1004:             *            The binding to be added; must not be <code>null</code>.
1005:             */
1006:            private final void bindingAdd(final Binding binding) {
1007:                if (!(binding.getParameterizedCommand().getCommand()
1008:                        .isDefined()))
1009:                    return;
1010:
1011:                // Remember the parameterized command and context.
1012:                markedParameterizedCommand = binding.getParameterizedCommand();
1013:                markedContextId = binding.getContextId();
1014:
1015:                // Update the preference page.
1016:                update();
1017:
1018:                // Select the new binding.
1019:                filteredTree.getViewer().setSelection(
1020:                        new StructuredSelection(binding
1021:                                .getParameterizedCommand()), true);
1022:                bindingText.setFocus();
1023:                bindingText.selectAll();
1024:            }
1025:
1026:            /**
1027:             * Removes an existing binding. The preference page is then updated.
1028:             * 
1029:             * @param binding
1030:             *            The binding to be removed; must not be <code>null</code>.
1031:             */
1032:            private final void bindingRemove(final KeyBinding binding) {
1033:                ArrayList extraSystemDeletes = new ArrayList();
1034:                final String contextId = binding.getContextId();
1035:                final String schemeId = binding.getSchemeId();
1036:                final KeySequence triggerSequence = binding.getKeySequence();
1037:                if (binding.getType() == Binding.USER) {
1038:                    localChangeManager.removeBinding(binding);
1039:                } else {
1040:                    // TODO This should be the user's personal scheme.
1041:                    Collection previousConflictMatches = (Collection) localChangeManager
1042:                            .getActiveBindingsDisregardingContext().get(
1043:                                    binding.getTriggerSequence());
1044:                    KeyBinding deleteBinding = new KeyBinding(triggerSequence,
1045:                            null, schemeId, contextId, null, null, null,
1046:                            Binding.USER);
1047:                    localChangeManager.addBinding(deleteBinding);
1048:                    if (previousConflictMatches != null) {
1049:                        Iterator i = previousConflictMatches.iterator();
1050:                        while (i.hasNext()) {
1051:                            Binding b = (Binding) i.next();
1052:                            if (b != binding && deletes(deleteBinding, b)) {
1053:                                extraSystemDeletes.add(b);
1054:                            }
1055:                        }
1056:                    }
1057:                }
1058:
1059:                // update the model
1060:                bindingModel.remove(binding);
1061:                bindingAdd(binding);
1062:                if (!extraSystemDeletes.isEmpty()) {
1063:                    Iterator i = extraSystemDeletes.iterator();
1064:                    while (i.hasNext()) {
1065:                        KeyBinding b = (KeyBinding) i.next();
1066:                        KeyBinding newBinding = new KeyBinding(b
1067:                                .getKeySequence(), b.getParameterizedCommand(),
1068:                                b.getSchemeId(), b.getContextId(), null, null,
1069:                                null, Binding.USER);
1070:                        localChangeManager.addBinding(newBinding);
1071:
1072:                        bindingModel.remove(b);
1073:                        bindingModel.add(newBinding);
1074:                    }
1075:                }
1076:                updateConflicts(binding);
1077:            }
1078:
1079:            private final void updateConflicts(final Collection bindings) {
1080:                Iterator i = bindings.iterator();
1081:                while (i.hasNext()) {
1082:                    final Binding b = (Binding) i.next();
1083:                    if (b.getParameterizedCommand() != null) {
1084:                        updateConflicts(b);
1085:                    }
1086:                }
1087:            }
1088:
1089:            private final void updateConflicts(final Binding binding) {
1090:                Collection matches = (Collection) localChangeManager
1091:                        .getActiveBindingsDisregardingContext().get(
1092:                                binding.getTriggerSequence());
1093:                if (matches != null) {
1094:                    Iterator i = matches.iterator();
1095:                    while (i.hasNext()) {
1096:                        Binding b = (Binding) i.next();
1097:                        if (binding != b
1098:                                && b.getContextId().equals(
1099:                                        binding.getContextId())) {
1100:                            filteredTree.getViewer().update(b, null);
1101:                        }
1102:                    }
1103:                }
1104:            }
1105:
1106:            private final void bindingRestore(final KeyBinding binding) {
1107:                final ParameterizedCommand cmd = binding
1108:                        .getParameterizedCommand();
1109:                bindingRestore(cmd, false);
1110:            }
1111:
1112:            private String locale = Locale.getDefault().toString();
1113:
1114:            private boolean localMatches(String l) {
1115:                if (l == null) {
1116:                    return true;
1117:                }
1118:                return Util.equals(locale, l);
1119:            }
1120:
1121:            private String platform = SWT.getPlatform();
1122:
1123:            private boolean platformMatches(String p) {
1124:                if (p == null) {
1125:                    return true;
1126:                }
1127:                return Util.equals(platform, p);
1128:            }
1129:
1130:            private final String[] getSchemeIds(String schemeId) {
1131:                final List strings = new ArrayList();
1132:                while (schemeId != null) {
1133:                    strings.add(schemeId);
1134:                    try {
1135:                        schemeId = bindingService.getScheme(schemeId)
1136:                                .getParentId();
1137:                    } catch (final NotDefinedException e) {
1138:                        return new String[0];
1139:                    }
1140:                }
1141:
1142:                return (String[]) strings.toArray(new String[strings.size()]);
1143:            }
1144:
1145:            private final void bindingRestore(final ParameterizedCommand cmd,
1146:                    boolean removeCmd) {
1147:                Set addSystemAll = new HashSet();
1148:                ArrayList removeUser = new ArrayList();
1149:                ArrayList removeBinding = new ArrayList();
1150:                Binding[] bindings = localChangeManager.getBindings();
1151:                for (int i = 0; i < bindings.length; i++) {
1152:                    final Binding b = bindings[i];
1153:                    if (b.getParameterizedCommand() == null
1154:                            && localMatches(b.getLocale())
1155:                            && platformMatches(b.getPlatform())) {
1156:                        // flat out, a delete marker
1157:                        removeBinding.add(b);
1158:                    } else if (cmd.equals(b.getParameterizedCommand())) {
1159:                        if (b.getType() == Binding.SYSTEM
1160:                                && localMatches(b.getLocale())
1161:                                && platformMatches(b.getPlatform())) {
1162:                            // a system binding for this command
1163:                            addSystemAll.add(b);
1164:                        } else if (b.getType() == Binding.USER) {
1165:                            // a user binding for this command
1166:                            removeUser.add(b);
1167:                            localChangeManager.removeBinding(b);
1168:                        }
1169:                    }
1170:                }
1171:
1172:                if (!addSystemAll.isEmpty()) {
1173:                    String[] activeSchemeIds = getSchemeIds(getSchemeId());
1174:                    Binding[] sysArray = (Binding[]) addSystemAll
1175:                            .toArray(new Binding[addSystemAll.size()]);
1176:                    for (int k = 0; k < sysArray.length; k++) {
1177:                        Binding sys = sysArray[k];
1178:                        boolean deleted = false;
1179:                        for (Iterator i = removeBinding.iterator(); i.hasNext();) {
1180:                            Binding del = (Binding) i.next();
1181:                            if (deletes(del, sys)) {
1182:                                if (del.getType() == Binding.USER) {
1183:                                    removeUser.add(del);
1184:                                    localChangeManager.removeBinding(del);
1185:                                } else {
1186:                                    deleted = true;
1187:                                    addSystemAll.remove(sys);
1188:                                }
1189:                            }
1190:                        }
1191:                        // Check the scheme ids.
1192:                        final String schemeId = sys.getSchemeId();
1193:                        boolean found = false;
1194:                        if (activeSchemeIds != null && !deleted) {
1195:                            for (int j = 0; j < activeSchemeIds.length; j++) {
1196:                                if (Util.equals(schemeId, activeSchemeIds[j])) {
1197:                                    found = true;
1198:                                    break;
1199:                                }
1200:                            }
1201:                        }
1202:                        if (!found && sys.getType() == Binding.SYSTEM) {
1203:                            addSystemAll.remove(sys);
1204:                        }
1205:                    }
1206:                }
1207:
1208:                bindingModel.addAll(addSystemAll);
1209:                bindingModel.removeAll(removeUser);
1210:                updateConflicts(addSystemAll);
1211:                updateConflicts(removeUser);
1212:                if (addSystemAll.isEmpty()) {
1213:                    commandModel.add(cmd);
1214:                    filteredTree.getViewer().setSelection(
1215:                            new StructuredSelection(cmd), true);
1216:                } else if (removeCmd) {
1217:                    commandModel.remove(cmd);
1218:                }
1219:                if (!addSystemAll.isEmpty()) {
1220:                    // Select the new binding.
1221:                    filteredTree.getViewer().setSelection(
1222:                            new StructuredSelection(addSystemAll.iterator()
1223:                                    .next()), true);
1224:                }
1225:
1226:                update();
1227:            }
1228:
1229:            final static boolean deletes(final Binding del,
1230:                    final Binding binding) {
1231:                boolean deletes = true;
1232:                deletes &= Util.equals(del.getContextId(), binding
1233:                        .getContextId());
1234:                deletes &= Util.equals(del.getTriggerSequence(), binding
1235:                        .getTriggerSequence());
1236:                if (del.getLocale() != null) {
1237:                    deletes &= Util
1238:                            .equals(del.getLocale(), binding.getLocale());
1239:                }
1240:                if (del.getPlatform() != null) {
1241:                    deletes &= Util.equals(del.getPlatform(), binding
1242:                            .getPlatform());
1243:                }
1244:                deletes &= (binding.getType() == Binding.SYSTEM);
1245:                deletes &= Util.equals(del.getParameterizedCommand(), null);
1246:
1247:                return deletes;
1248:            }
1249:
1250:            /**
1251:             * Creates the button bar across the bottom of the preference page. This
1252:             * button bar contains the "Advanced..." button.
1253:             * 
1254:             * @param parent
1255:             *            The composite in which the button bar should be placed; never
1256:             *            <code>null</code>.
1257:             * @return The button bar composite; never <code>null</code>.
1258:             */
1259:            private final Control createButtonBar(final Composite parent) {
1260:                GridLayout layout;
1261:                GridData gridData;
1262:                int widthHint;
1263:
1264:                // Create the composite to house the button bar.
1265:                final Composite buttonBar = new Composite(parent, SWT.NONE);
1266:                layout = new GridLayout(1, false);
1267:                layout.marginWidth = 0;
1268:                buttonBar.setLayout(layout);
1269:                gridData = new GridData();
1270:                gridData.horizontalAlignment = SWT.END;
1271:                buttonBar.setLayoutData(gridData);
1272:
1273:                // Advanced button.
1274:                final Button advancedButton = new Button(buttonBar, SWT.PUSH);
1275:                gridData = new GridData();
1276:                widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
1277:                advancedButton
1278:                        .setText(NewKeysPreferenceMessages.AdvancedButton_Text);
1279:                gridData.widthHint = Math.max(widthHint, advancedButton
1280:                        .computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
1281:                advancedButton.setLayoutData(gridData);
1282:                advancedButton.addSelectionListener(new SelectionListener() {
1283:                    public void widgetDefaultSelected(SelectionEvent e) {
1284:                    }
1285:
1286:                    public void widgetSelected(SelectionEvent e) {
1287:                        KeysPreferenceFiltersDialog dialog = new KeysPreferenceFiltersDialog(
1288:                                getShell());
1289:                        dialog.setFilterActionSet(filterActionSetContexts);
1290:                        dialog.setFilterInternal(filterInternalContexts);
1291:                        dialog.setFilterUncategorized(filteredTree
1292:                                .isFilteringCategories());
1293:                        if (dialog.open() == Window.OK) {
1294:                            filterActionSetContexts = dialog
1295:                                    .getFilterActionSet();
1296:                            filterInternalContexts = dialog.getFilterInternal();
1297:                            filteredTree.filterCategories(dialog
1298:                                    .getFilterUncategorized());
1299:                            whenCombo.setInput(getContexts());
1300:                            updateDataControls();
1301:                        }
1302:                    }
1303:                });
1304:                return buttonBar;
1305:            }
1306:
1307:            /*
1308:             * (non-Javadoc)
1309:             * 
1310:             * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
1311:             */
1312:            protected final Control createContents(final Composite parent) {
1313:                PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
1314:                        IWorkbenchHelpContextIds.KEYS_PREFERENCE_PAGE);
1315:
1316:                GridLayout layout = null;
1317:
1318:                long startTime = 0L;
1319:                if (DEBUG) {
1320:                    startTime = System.currentTimeMillis();
1321:                }
1322:
1323:                IDialogSettings settings = getDialogSettings();
1324:                if (settings.get(TAG_FILTER_ACTION_SETS) != null) {
1325:                    filterActionSetContexts = settings
1326:                            .getBoolean(TAG_FILTER_ACTION_SETS);
1327:                }
1328:                if (settings.get(TAG_FILTER_INTERNAL) != null) {
1329:                    filterInternalContexts = settings
1330:                            .getBoolean(TAG_FILTER_INTERNAL);
1331:                }
1332:                patternFilter = new CategoryPatternFilter(true, commandService
1333:                        .getCategory(null));
1334:                if (settings.get(TAG_FILTER_UNCAT) != null) {
1335:                    patternFilter.filterCategories(settings
1336:                            .getBoolean(TAG_FILTER_UNCAT));
1337:                }
1338:
1339:                // Creates a composite to hold all of the page contents.
1340:                final Composite page = new Composite(parent, SWT.NONE);
1341:                layout = new GridLayout(1, false);
1342:                layout.marginWidth = 0;
1343:                page.setLayout(layout);
1344:
1345:                createSchemeControls(page);
1346:                createTree(page);
1347:                createTreeControls(page);
1348:                createDataControls(page);
1349:                createButtonBar(page);
1350:
1351:                fill();
1352:                update();
1353:
1354:                applyDialogFont(page);
1355:
1356:                if (DEBUG) {
1357:                    final long elapsedTime = System.currentTimeMillis()
1358:                            - startTime;
1359:                    Tracing.printTrace(TRACING_COMPONENT, "Created page in " //$NON-NLS-1$
1360:                            + elapsedTime + "ms"); //$NON-NLS-1$
1361:                }
1362:
1363:                return page;
1364:            }
1365:
1366:            private final Control createDataControls(final Composite parent) {
1367:                GridLayout layout;
1368:                GridData gridData;
1369:
1370:                // Creates the data area.
1371:                final Composite dataArea = new Composite(parent, SWT.NONE);
1372:                layout = new GridLayout(2, true);
1373:                layout.marginWidth = 0;
1374:                dataArea.setLayout(layout);
1375:                gridData = new GridData();
1376:                gridData.grabExcessHorizontalSpace = true;
1377:                gridData.horizontalAlignment = SWT.FILL;
1378:                dataArea.setLayoutData(gridData);
1379:
1380:                // LEFT DATA AREA
1381:                // Creates the left data area.
1382:                final Composite leftDataArea = new Composite(dataArea, SWT.NONE);
1383:                layout = new GridLayout(3, false);
1384:                leftDataArea.setLayout(layout);
1385:                gridData = new GridData();
1386:                gridData.grabExcessHorizontalSpace = true;
1387:                gridData.verticalAlignment = SWT.TOP;
1388:                gridData.horizontalAlignment = SWT.FILL;
1389:                leftDataArea.setLayoutData(gridData);
1390:
1391:                // The command name label.
1392:                final Label commandNameLabel = new Label(leftDataArea, SWT.NONE);
1393:                commandNameLabel
1394:                        .setText(NewKeysPreferenceMessages.CommandNameLabel_Text);
1395:
1396:                // The current command name.
1397:                commandNameValueLabel = new Label(leftDataArea, SWT.NONE);
1398:                gridData = new GridData();
1399:                gridData.grabExcessHorizontalSpace = true;
1400:                gridData.horizontalSpan = 2;
1401:                gridData.horizontalAlignment = SWT.FILL;
1402:                commandNameValueLabel.setLayoutData(gridData);
1403:
1404:                // The binding label.
1405:                final Label bindingLabel = new Label(leftDataArea, SWT.NONE);
1406:                bindingLabel
1407:                        .setText(NewKeysPreferenceMessages.BindingLabel_Text);
1408:
1409:                // The key sequence entry widget.
1410:                bindingText = new Text(leftDataArea, SWT.BORDER);
1411:                gridData = new GridData();
1412:                gridData.grabExcessHorizontalSpace = true;
1413:                gridData.horizontalAlignment = SWT.FILL;
1414:                gridData.widthHint = 200;
1415:                bindingText.setLayoutData(gridData);
1416:
1417:                bindingText.addFocusListener(new FocusListener() {
1418:                    public void focusGained(FocusEvent e) {
1419:                        bindingService.setKeyFilterEnabled(false);
1420:                    }
1421:
1422:                    public void focusLost(FocusEvent e) {
1423:                        bindingService.setKeyFilterEnabled(true);
1424:                    }
1425:                });
1426:                bindingText.addDisposeListener(new DisposeListener() {
1427:                    public void widgetDisposed(DisposeEvent e) {
1428:                        if (!bindingService.isKeyFilterEnabled()) {
1429:                            bindingService.setKeyFilterEnabled(true);
1430:                        }
1431:                    }
1432:                });
1433:
1434:                keySequenceText = new KeySequenceText(bindingText);
1435:                keySequenceText.setKeyStrokeLimit(4);
1436:                keySequenceText
1437:                        .addPropertyChangeListener(new IPropertyChangeListener() {
1438:                            public final void propertyChange(
1439:                                    final PropertyChangeEvent event) {
1440:                                if (!event.getOldValue().equals(
1441:                                        event.getNewValue())) {
1442:                                    keySequenceChanged();
1443:                                }
1444:                            }
1445:                        });
1446:
1447:                // Button for adding trapped key strokes
1448:                final Button addKeyButton = new Button(leftDataArea, SWT.LEFT
1449:                        | SWT.ARROW);
1450:                addKeyButton
1451:                        .setToolTipText(NewKeysPreferenceMessages.AddKeyButton_ToolTipText);
1452:                gridData = new GridData();
1453:                gridData.heightHint = schemeCombo.getCombo().getTextHeight();
1454:                addKeyButton.setLayoutData(gridData);
1455:
1456:                // Arrow buttons aren't normally added to the tab list. Let's fix that.
1457:                final Control[] tabStops = dataArea.getTabList();
1458:                final ArrayList newTabStops = new ArrayList();
1459:                for (int i = 0; i < tabStops.length; i++) {
1460:                    Control tabStop = tabStops[i];
1461:                    newTabStops.add(tabStop);
1462:                    if (bindingText.equals(tabStop)) {
1463:                        newTabStops.add(addKeyButton);
1464:                    }
1465:                }
1466:                final Control[] newTabStopArray = (Control[]) newTabStops
1467:                        .toArray(new Control[newTabStops.size()]);
1468:                dataArea.setTabList(newTabStopArray);
1469:
1470:                // Construct the menu to attach to the above button.
1471:                final Menu addKeyMenu = new Menu(addKeyButton);
1472:                final Iterator trappedKeyItr = KeySequenceText.TRAPPED_KEYS
1473:                        .iterator();
1474:                while (trappedKeyItr.hasNext()) {
1475:                    final KeyStroke trappedKey = (KeyStroke) trappedKeyItr
1476:                            .next();
1477:                    final MenuItem menuItem = new MenuItem(addKeyMenu, SWT.PUSH);
1478:                    menuItem.setText(trappedKey.format());
1479:                    menuItem.addSelectionListener(new SelectionAdapter() {
1480:
1481:                        public void widgetSelected(SelectionEvent e) {
1482:                            keySequenceText.insert(trappedKey);
1483:                            bindingText.setFocus();
1484:                            bindingText
1485:                                    .setSelection(bindingText.getTextLimit());
1486:                        }
1487:                    });
1488:                }
1489:                addKeyButton.addSelectionListener(new SelectionAdapter() {
1490:
1491:                    public void widgetSelected(SelectionEvent selectionEvent) {
1492:                        Point buttonLocation = addKeyButton.getLocation();
1493:                        buttonLocation = dataArea.toDisplay(buttonLocation.x,
1494:                                buttonLocation.y);
1495:                        Point buttonSize = addKeyButton.getSize();
1496:                        addKeyMenu.setLocation(buttonLocation.x,
1497:                                buttonLocation.y + buttonSize.y);
1498:                        addKeyMenu.setVisible(true);
1499:                    }
1500:                });
1501:
1502:                final IObservableValue selection = ViewersObservables
1503:                        .observeSingleSelection(filteredTree.getViewer());
1504:
1505:                // The when label.
1506:                final Label whenLabel = new Label(leftDataArea, SWT.NONE);
1507:                whenLabel.setText(NewKeysPreferenceMessages.WhenLabel_Text);
1508:
1509:                // The when combo.
1510:                whenCombo = new ComboViewer(leftDataArea);
1511:                gridData = new GridData();
1512:                gridData.grabExcessHorizontalSpace = true;
1513:                gridData.horizontalAlignment = SWT.FILL;
1514:                gridData.horizontalSpan = 2;
1515:                whenCombo.getCombo().setLayoutData(gridData);
1516:                whenCombo
1517:                        .setLabelProvider(new NamedHandleObjectLabelProvider());
1518:                whenCombo.setContentProvider(new ArrayContentProvider());
1519:                whenCombo.setComparator(new ViewerComparator());
1520:                whenCombo
1521:                        .addPostSelectionChangedListener(new ISelectionChangedListener() {
1522:
1523:                            public void selectionChanged(
1524:                                    SelectionChangedEvent event) {
1525:                                updateWhenCombo();
1526:                            }
1527:                        });
1528:
1529:                whenCombo.getCombo().setVisibleItemCount(20);
1530:                whenCombo.getCombo().setVisible(false);
1531:                whenLabel.setVisible(false);
1532:                selection.addValueChangeListener(new IValueChangeListener() {
1533:
1534:                    public void handleValueChange(ValueChangeEvent event) {
1535:                        boolean visible = false;
1536:                        if (selection.getValue() instanceof  KeyBinding) {
1537:                            visible = true;
1538:                        }
1539:                        Combo combo = whenCombo.getCombo();
1540:                        if (!combo.isDisposed()) {
1541:                            combo.setVisible(visible);
1542:                        }
1543:                        if (!whenLabel.isDisposed()) {
1544:                            whenLabel.setVisible(visible);
1545:                        }
1546:                    }
1547:                });
1548:
1549:                final Label asterisk = new Label(leftDataArea, SWT.NONE);
1550:                asterisk.setText(NewKeysPreferenceMessages.Asterisk_Text);
1551:                gridData = new GridData();
1552:                gridData.grabExcessHorizontalSpace = true;
1553:                gridData.horizontalSpan = 2;
1554:                gridData.horizontalAlignment = SWT.FILL;
1555:                asterisk.setLayoutData(gridData);
1556:
1557:                // RIGHT DATA AREA
1558:                // Creates the right data area.
1559:                final Composite rightDataArea = new Composite(dataArea,
1560:                        SWT.NONE);
1561:                layout = new GridLayout(1, false);
1562:                rightDataArea.setLayout(layout);
1563:                gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
1564:                rightDataArea.setLayoutData(gridData);
1565:
1566:                // The description label.
1567:                final Label descriptionLabel = new Label(rightDataArea,
1568:                        SWT.NONE);
1569:                descriptionLabel
1570:                        .setText(NewKeysPreferenceMessages.DescriptionLabel_Text);
1571:                gridData = new GridData();
1572:                gridData.grabExcessHorizontalSpace = true;
1573:                gridData.horizontalAlignment = SWT.FILL;
1574:                descriptionLabel.setLayoutData(gridData);
1575:
1576:                // The description value.
1577:                descriptionValueText = new Text(rightDataArea, SWT.BORDER
1578:                        | SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL
1579:                        | SWT.H_SCROLL);
1580:                gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
1581:                gridData.horizontalIndent = 20;
1582:                descriptionValueText.setLayoutData(gridData);
1583:                return dataArea;
1584:            }
1585:
1586:            private final Control createSchemeControls(final Composite parent) {
1587:                GridLayout layout;
1588:                GridData gridData;
1589:
1590:                // Create a composite to hold the controls.
1591:                final Composite schemeControls = new Composite(parent, SWT.NONE);
1592:                layout = new GridLayout(3, false);
1593:                layout.marginWidth = 0;
1594:                schemeControls.setLayout(layout);
1595:                gridData = new GridData();
1596:                gridData.grabExcessHorizontalSpace = true;
1597:                gridData.horizontalAlignment = SWT.FILL;
1598:                schemeControls.setLayoutData(gridData);
1599:
1600:                // Create the label.
1601:                final Label schemeLabel = new Label(schemeControls, SWT.NONE);
1602:                schemeLabel.setText(NewKeysPreferenceMessages.SchemeLabel_Text);
1603:
1604:                // Create the combo.
1605:                schemeCombo = new ComboViewer(schemeControls);
1606:                schemeCombo
1607:                        .setLabelProvider(new NamedHandleObjectLabelProvider());
1608:                schemeCombo.setContentProvider(new ArrayContentProvider());
1609:                gridData = new GridData();
1610:                gridData.widthHint = 150;
1611:                gridData.horizontalAlignment = SWT.FILL;
1612:                schemeCombo.getCombo().setLayoutData(gridData);
1613:                schemeCombo
1614:                        .addSelectionChangedListener(new ISelectionChangedListener() {
1615:                            public final void selectionChanged(
1616:                                    final SelectionChangedEvent event) {
1617:                                selectSchemeCombo(event);
1618:                            }
1619:                        });
1620:
1621:                return schemeControls;
1622:            }
1623:
1624:            private final Control createTree(final Composite parent) {
1625:                GridData gridData;
1626:
1627:                filteredTree = new CategoryFilterTree(parent, SWT.SINGLE
1628:                        | SWT.FULL_SELECTION | SWT.BORDER, patternFilter);
1629:                final GridLayout layout = new GridLayout(1, false);
1630:                layout.marginWidth = 0;
1631:                filteredTree.setLayout(layout);
1632:                gridData = new GridData();
1633:                gridData.grabExcessHorizontalSpace = true;
1634:                gridData.grabExcessVerticalSpace = true;
1635:                gridData.horizontalAlignment = SWT.FILL;
1636:                gridData.verticalAlignment = SWT.FILL;
1637:                filteredTree.setLayoutData(gridData);
1638:
1639:                // Make sure the filtered tree has a height of ITEMS_TO_SHOW
1640:                final Tree tree = filteredTree.getViewer().getTree();
1641:                tree.setHeaderVisible(true);
1642:                final Object layoutData = tree.getLayoutData();
1643:                if (layoutData instanceof  GridData) {
1644:                    gridData = (GridData) layoutData;
1645:                    final int itemHeight = tree.getItemHeight();
1646:                    if (itemHeight > 1) {
1647:                        gridData.heightHint = ITEMS_TO_SHOW * itemHeight;
1648:                    }
1649:                }
1650:
1651:                final BindingComparator comparator = new BindingComparator();
1652:                comparator.setSortColumn(0);
1653:
1654:                // Create the columns for the tree.
1655:
1656:                final TreeColumn commandNameColumn = new TreeColumn(tree,
1657:                        SWT.LEFT, BindingLabelProvider.COLUMN_COMMAND);
1658:                commandNameColumn
1659:                        .setText(NewKeysPreferenceMessages.CommandNameColumn_Text);
1660:                tree.setSortColumn(commandNameColumn);
1661:                tree.setSortDirection(comparator.isAscending() ? SWT.UP
1662:                        : SWT.DOWN);
1663:                commandNameColumn.addSelectionListener(new ResortColumn(
1664:                        comparator, commandNameColumn, tree,
1665:                        BindingLabelProvider.COLUMN_COMMAND));
1666:
1667:                final TreeColumn triggerSequenceColumn = new TreeColumn(tree,
1668:                        SWT.LEFT, BindingLabelProvider.COLUMN_TRIGGER_SEQUENCE);
1669:                triggerSequenceColumn
1670:                        .setText(NewKeysPreferenceMessages.TriggerSequenceColumn_Text);
1671:                triggerSequenceColumn.addSelectionListener(new ResortColumn(
1672:                        comparator, triggerSequenceColumn, tree,
1673:                        BindingLabelProvider.COLUMN_TRIGGER_SEQUENCE));
1674:
1675:                final TreeColumn whenColumn = new TreeColumn(tree, SWT.LEFT,
1676:                        BindingLabelProvider.COLUMN_WHEN);
1677:                whenColumn.setText(NewKeysPreferenceMessages.WhenColumn_Text);
1678:                whenColumn.addSelectionListener(new ResortColumn(comparator,
1679:                        whenColumn, tree, BindingLabelProvider.COLUMN_WHEN));
1680:
1681:                final TreeColumn categoryColumn = new TreeColumn(tree,
1682:                        SWT.LEFT, BindingLabelProvider.COLUMN_CATEGORY);
1683:                categoryColumn
1684:                        .setText(NewKeysPreferenceMessages.CategoryColumn_Text);
1685:                categoryColumn.addSelectionListener(new ResortColumn(
1686:                        comparator, categoryColumn, tree,
1687:                        BindingLabelProvider.COLUMN_CATEGORY));
1688:
1689:                final TreeColumn userMarker = new TreeColumn(tree, SWT.LEFT,
1690:                        BindingLabelProvider.COLUMN_USER);
1691:                userMarker.setText(NewKeysPreferenceMessages.UserColumn_Text);
1692:                userMarker.addSelectionListener(new ResortColumn(comparator,
1693:                        userMarker, tree, BindingLabelProvider.COLUMN_USER));
1694:
1695:                // Set up the providers for the viewer.
1696:                final TreeViewer viewer = filteredTree.getViewer();
1697:                viewer.setLabelProvider(new BindingLabelProvider());
1698:
1699:                viewer.setContentProvider(new ObservableSetContentProvider());
1700:
1701:                viewer.setComparator(comparator);
1702:
1703:                /*
1704:                 * Listen for selection changes so that the data controls can be
1705:                 * updated.
1706:                 */
1707:                viewer
1708:                        .addSelectionChangedListener(new ISelectionChangedListener() {
1709:                            public final void selectionChanged(
1710:                                    final SelectionChangedEvent event) {
1711:                                selectTreeRow(event);
1712:                            }
1713:                        });
1714:
1715:                // Adjust how the filter works.
1716:                filteredTree.getPatternFilter().setIncludeLeadingWildcard(true);
1717:                return filteredTree;
1718:            }
1719:
1720:            private final Control createTreeControls(final Composite parent) {
1721:                GridLayout layout;
1722:                GridData gridData;
1723:                int widthHint;
1724:
1725:                // Creates controls related to the tree.
1726:                final Composite treeControls = new Composite(parent, SWT.NONE);
1727:                layout = new GridLayout(4, false);
1728:                layout.marginWidth = 0;
1729:                treeControls.setLayout(layout);
1730:                gridData = new GridData();
1731:                gridData.grabExcessHorizontalSpace = true;
1732:                gridData.horizontalAlignment = SWT.FILL;
1733:                treeControls.setLayoutData(gridData);
1734:
1735:                // Create the show all check box.
1736:                showAllCheckBox = new Button(treeControls, SWT.CHECK);
1737:                gridData = new GridData();
1738:                gridData.grabExcessHorizontalSpace = true;
1739:                gridData.horizontalAlignment = SWT.FILL;
1740:                gridData.verticalAlignment = SWT.TOP;
1741:                showAllCheckBox.setLayoutData(gridData);
1742:                showAllCheckBox
1743:                        .setText(NewKeysPreferenceMessages.ShowAllCheckBox_Text);
1744:                IDialogSettings settings = getDialogSettings();
1745:                showAllCheckBox.setSelection(settings.getBoolean(TAG_FIELD));
1746:                showAllCheckBox.addSelectionListener(new SelectionAdapter() {
1747:                    public void widgetSelected(SelectionEvent e) {
1748:                        updateShowAll();
1749:                    }
1750:                });
1751:
1752:                final IObservableValue selection = ViewersObservables
1753:                        .observeSingleSelection(filteredTree.getViewer());
1754:
1755:                // Create the delete binding button.
1756:                final Button addBindingButton = new Button(treeControls,
1757:                        SWT.PUSH);
1758:                gridData = new GridData();
1759:                widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
1760:                addBindingButton
1761:                        .setText(NewKeysPreferenceMessages.AddBindingButton_Text);
1762:                gridData.widthHint = Math.max(widthHint, addBindingButton
1763:                        .computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
1764:                addBindingButton.setLayoutData(gridData);
1765:                addBindingButton.addSelectionListener(new SelectionAdapter() {
1766:                    public final void widgetSelected(final SelectionEvent event) {
1767:                        selectAddBindingButton(event);
1768:                    }
1769:                });
1770:                new ControlUpdater(addBindingButton) {
1771:                    protected void updateControl() {
1772:                        Object selectedObject = selection.getValue();
1773:                        addBindingButton
1774:                                .setEnabled(selectedObject instanceof  KeyBinding);
1775:                    }
1776:                };
1777:
1778:                // Create the delete binding button.
1779:                final Button removeBindingButton = new Button(treeControls,
1780:                        SWT.PUSH);
1781:                gridData = new GridData();
1782:                widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
1783:                removeBindingButton
1784:                        .setText(NewKeysPreferenceMessages.RemoveBindingButton_Text);
1785:                gridData.widthHint = Math.max(widthHint, removeBindingButton
1786:                        .computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
1787:                removeBindingButton.setLayoutData(gridData);
1788:                removeBindingButton
1789:                        .addSelectionListener(new SelectionAdapter() {
1790:                            public final void widgetSelected(
1791:                                    final SelectionEvent event) {
1792:                                selectRemoveBindingButton(event);
1793:                            }
1794:                        });
1795:                new ControlUpdater(removeBindingButton) {
1796:                    protected void updateControl() {
1797:                        Object selectedObject = selection.getValue();
1798:                        removeBindingButton
1799:                                .setEnabled(selectedObject instanceof  KeyBinding);
1800:                    }
1801:                };
1802:
1803:                // Create the delete binding button.
1804:                final Button restore = new Button(treeControls, SWT.PUSH);
1805:                gridData = new GridData();
1806:                widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
1807:                restore
1808:                        .setText(NewKeysPreferenceMessages.RestoreBindingButton_Text);
1809:                gridData.widthHint = Math.max(widthHint, restore.computeSize(
1810:                        SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
1811:                restore.setLayoutData(gridData);
1812:                restore.addSelectionListener(new SelectionAdapter() {
1813:                    public final void widgetSelected(final SelectionEvent event) {
1814:                        selectRestoreBindingButton(event);
1815:                    }
1816:                });
1817:
1818:                return treeControls;
1819:            }
1820:
1821:            private void updateShowAll() {
1822:                BusyIndicator.showWhile(filteredTree.getViewer().getTree()
1823:                        .getDisplay(), new Runnable() {
1824:                    public void run() {
1825:                        try {
1826:                            filteredTree.getViewer().getTree().setRedraw(false);
1827:                            fillInCommands();
1828:                        } finally {
1829:                            filteredTree.getViewer().getTree().setRedraw(true);
1830:                        }
1831:                    }
1832:                });
1833:            }
1834:
1835:            /**
1836:             * Copies all of the information from the workbench into a local change
1837:             * manager, and then the local change manager is used to populate the
1838:             * contents of the various widgets on the page.
1839:             * 
1840:             * The widgets affected by this method are: scheme combo, bindings
1841:             * table/tree model, and the when combo.
1842:             */
1843:            private final void fill() {
1844:                // Make an internal binding manager to track changes.
1845:                localChangeManager = new BindingManager(new ContextManager(),
1846:                        new CommandManager());
1847:                final Scheme[] definedSchemes = bindingService
1848:                        .getDefinedSchemes();
1849:                try {
1850:                    for (int i = 0; i < definedSchemes.length; i++) {
1851:                        final Scheme scheme = definedSchemes[i];
1852:                        final Scheme copy = localChangeManager.getScheme(scheme
1853:                                .getId());
1854:                        copy.define(scheme.getName(), scheme.getDescription(),
1855:                                scheme.getParentId());
1856:                    }
1857:                    localChangeManager.setActiveScheme(bindingService
1858:                            .getActiveScheme());
1859:                } catch (final NotDefinedException e) {
1860:                    throw new Error(
1861:                            "There is a programmer error in the keys preference page"); //$NON-NLS-1$
1862:                }
1863:                localChangeManager.setLocale(bindingService.getLocale());
1864:                localChangeManager.setPlatform(bindingService.getPlatform());
1865:                localChangeManager.setBindings(bindingService.getBindings());
1866:
1867:                // Update the scheme combo.
1868:                schemeCombo.setInput(sortByName(localChangeManager
1869:                        .getDefinedSchemes()));
1870:                setScheme(localChangeManager.getActiveScheme());
1871:
1872:                // Update the when combo.
1873:                whenCombo.setInput(getContexts());
1874:
1875:                commandModel = new WritableSet();
1876:                bindingModel = new WritableSet();
1877:                model = new UnionSet(new IObservableSet[] { bindingModel,
1878:                        commandModel });
1879:
1880:                bindingModel.addAll(localChangeManager
1881:                        .getActiveBindingsDisregardingContextFlat());
1882:                fillInCommands();
1883:
1884:                if (DEBUG) {
1885:                    Tracing.printTrace(TRACING_COMPONENT,
1886:                            "fill in size: " + model.size()); //$NON-NLS-1$
1887:                }
1888:
1889:                filteredTree.getViewer().setInput(model);
1890:            }
1891:
1892:            /**
1893:             * 
1894:             */
1895:            private void fillInCommands() {
1896:                long startTime = 0L;
1897:                if (DEBUG) {
1898:                    startTime = System.currentTimeMillis();
1899:                }
1900:                if (showAllCheckBox.getSelection()) {
1901:                    final Collection commandIds = commandService
1902:                            .getDefinedCommandIds();
1903:                    final Collection commands = new HashSet();
1904:                    final Iterator commandIdItr = commandIds.iterator();
1905:                    while (commandIdItr.hasNext()) {
1906:                        final String currentCommandId = (String) commandIdItr
1907:                                .next();
1908:                        final Command currentCommand = commandService
1909:                                .getCommand(currentCommandId);
1910:                        try {
1911:                            commands.addAll(ParameterizedCommand
1912:                                    .generateCombinations(currentCommand));
1913:                        } catch (final NotDefinedException e) {
1914:                            // It is safe to just ignore undefined commands.
1915:                        }
1916:                    }
1917:
1918:                    // Remove duplicates.
1919:                    Iterator i = bindingModel.iterator();
1920:                    while (i.hasNext()) {
1921:                        commands.remove(((Binding) i.next())
1922:                                .getParameterizedCommand());
1923:                    }
1924:
1925:                    commandModel.addAll(commands);
1926:                } else {
1927:                    commandModel.clear();
1928:                }
1929:
1930:                if (DEBUG) {
1931:                    final long elapsedTime = System.currentTimeMillis()
1932:                            - startTime;
1933:                    Tracing.printTrace(TRACING_COMPONENT, "fillInCommands in " //$NON-NLS-1$
1934:                            + elapsedTime + "ms"); //$NON-NLS-1$
1935:                }
1936:            }
1937:
1938:            /*
1939:             * (non-Javadoc)
1940:             * 
1941:             * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
1942:             */
1943:            public final void init(final IWorkbench workbench) {
1944:                bindingService = (IBindingService) workbench
1945:                        .getService(IBindingService.class);
1946:                commandImageService = (ICommandImageService) workbench
1947:                        .getService(ICommandImageService.class);
1948:                commandService = (ICommandService) workbench
1949:                        .getService(ICommandService.class);
1950:                contextService = (IContextService) workbench
1951:                        .getService(IContextService.class);
1952:            }
1953:
1954:            /**
1955:             * Updates the interface as the key sequence has changed. This finds the
1956:             * selected item. If the selected item is a binding, then it updates the
1957:             * binding -- either by updating a user binding, or doing the deletion
1958:             * marker dance with a system binding. If the selected item is a
1959:             * parameterized command, then a binding is created based on the data
1960:             * controls.
1961:             */
1962:            private final void keySequenceChanged() {
1963:                long startTime = 0L;
1964:                if (DEBUG) {
1965:                    startTime = System.currentTimeMillis();
1966:                }
1967:
1968:                final KeySequence keySequence = keySequenceText
1969:                        .getKeySequence();
1970:                if (!keySequence.isComplete()) {
1971:                    return;
1972:                }
1973:
1974:                if ((keySequence == null) || (keySequence.isEmpty())) {
1975:                    ISelection selection = filteredTree.getViewer()
1976:                            .getSelection();
1977:                    if (selection instanceof  IStructuredSelection) {
1978:                        IStructuredSelection structuredSelection = (IStructuredSelection) selection;
1979:                        final Object node = structuredSelection
1980:                                .getFirstElement();
1981:                        if (node instanceof  KeyBinding) {
1982:                            bindingRemove((KeyBinding) node);
1983:                        }
1984:                    }
1985:                    return;
1986:                }
1987:
1988:                ISelection selection = filteredTree.getViewer().getSelection();
1989:                if (selection instanceof  IStructuredSelection) {
1990:                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
1991:                    final Object node = structuredSelection.getFirstElement();
1992:                    if (node != null) {
1993:                        final Object object = node;
1994:                        selection = whenCombo.getSelection();
1995:                        final String contextId;
1996:                        if (selection instanceof  IStructuredSelection) {
1997:                            structuredSelection = (IStructuredSelection) selection;
1998:                            final Object firstElement = structuredSelection
1999:                                    .getFirstElement();
2000:                            if (firstElement == null) {
2001:                                contextId = IContextIds.CONTEXT_ID_WINDOW;
2002:                            } else {
2003:                                contextId = ((Context) firstElement).getId();
2004:                            }
2005:                        } else {
2006:                            contextId = IContextIds.CONTEXT_ID_WINDOW;
2007:                        }
2008:                        if (object instanceof  KeyBinding) {
2009:                            KeyBinding keyBinding = (KeyBinding) object;
2010:                            if (!keyBinding.getContextId().equals(contextId)
2011:                                    || !keyBinding.getKeySequence().equals(
2012:                                            keySequence)) {
2013:                                final KeyBinding binding = new KeyBinding(
2014:                                        keySequence, keyBinding
2015:                                                .getParameterizedCommand(),
2016:                                        getSchemeId(), contextId, null, null,
2017:                                        null, Binding.USER);
2018:
2019:                                ArrayList extraSystemDeletes = new ArrayList();
2020:                                if (keyBinding.getType() == Binding.USER) {
2021:                                    localChangeManager
2022:                                            .removeBinding(keyBinding);
2023:                                } else {
2024:                                    // TODO This should be the user's personal scheme.
2025:                                    Collection previousConflictMatches = (Collection) localChangeManager
2026:                                            .getActiveBindingsDisregardingContext()
2027:                                            .get(
2028:                                                    keyBinding
2029:                                                            .getTriggerSequence());
2030:                                    KeyBinding deleteBinding = new KeyBinding(
2031:                                            keyBinding.getKeySequence(), null,
2032:                                            keyBinding.getSchemeId(),
2033:                                            keyBinding.getContextId(), null,
2034:                                            null, null, Binding.USER);
2035:                                    localChangeManager
2036:                                            .addBinding(deleteBinding);
2037:                                    if (previousConflictMatches != null) {
2038:                                        Iterator i = previousConflictMatches
2039:                                                .iterator();
2040:                                        while (i.hasNext()) {
2041:                                            Binding b = (Binding) i.next();
2042:                                            if (b != keyBinding
2043:                                                    && deletes(deleteBinding, b)) {
2044:                                                extraSystemDeletes.add(b);
2045:                                            }
2046:                                        }
2047:                                    }
2048:                                }
2049:                                localChangeManager.addBinding(binding);
2050:                                // update the model
2051:                                bindingModel.remove(keyBinding);
2052:                                bindingModel.add(binding);
2053:                                if (!extraSystemDeletes.isEmpty()) {
2054:                                    Iterator i = extraSystemDeletes.iterator();
2055:                                    while (i.hasNext()) {
2056:                                        KeyBinding b = (KeyBinding) i.next();
2057:                                        KeyBinding newBinding = new KeyBinding(
2058:                                                b.getKeySequence(),
2059:                                                b.getParameterizedCommand(), b
2060:                                                        .getSchemeId(), b
2061:                                                        .getContextId(), null,
2062:                                                null, null, Binding.USER);
2063:                                        localChangeManager
2064:                                                .addBinding(newBinding);
2065:
2066:                                        bindingModel.remove(b);
2067:                                        bindingModel.add(newBinding);
2068:                                    }
2069:                                }
2070:                                updateConflicts(keyBinding);
2071:                                updateConflicts(binding);
2072:                                // end update the model
2073:                                update();
2074:                                filteredTree.getViewer().setSelection(
2075:                                        new StructuredSelection(binding), true);
2076:                            }
2077:                        } else if (object instanceof  ParameterizedCommand) {
2078:                            // TODO This should use the user's personal scheme.
2079:                            final KeyBinding binding = new KeyBinding(
2080:                                    keySequence, (ParameterizedCommand) object,
2081:                                    getSchemeId(), contextId, null, null, null,
2082:                                    Binding.USER);
2083:                            localChangeManager.addBinding(binding);
2084:                            // update the model
2085:                            // end update the model
2086:                            bindingModel.add(binding);
2087:                            commandModel.remove(object);
2088:                            updateConflicts(binding);
2089:                            update();
2090:
2091:                            filteredTree.getViewer().setSelection(
2092:                                    new StructuredSelection(binding), true);
2093:                        }
2094:                    }
2095:                }
2096:                if (DEBUG) {
2097:                    final long elapsedTime = System.currentTimeMillis()
2098:                            - startTime;
2099:                    Tracing.printTrace(TRACING_COMPONENT,
2100:                            "keySequenceChanged in " //$NON-NLS-1$
2101:                                    + elapsedTime + "ms"); //$NON-NLS-1$
2102:                }
2103:            }
2104:
2105:            /**
2106:             * Logs the given exception, and opens an error dialog saying that something
2107:             * went wrong. The exception is assumed to have something to do with the
2108:             * preference store.
2109:             * 
2110:             * @param exception
2111:             *            The exception to be logged; must not be <code>null</code>.
2112:             */
2113:            private final void logPreferenceStoreException(
2114:                    final Throwable exception) {
2115:                final String message = NewKeysPreferenceMessages.PreferenceStoreError_Message;
2116:                String exceptionMessage = exception.getMessage();
2117:                if (exceptionMessage == null) {
2118:                    exceptionMessage = message;
2119:                }
2120:                final IStatus status = new Status(IStatus.ERROR,
2121:                        WorkbenchPlugin.PI_WORKBENCH, 0, exceptionMessage,
2122:                        exception);
2123:                WorkbenchPlugin.log(message, status);
2124:                StatusUtil.handleStatus(message, exception, StatusManager.SHOW);
2125:            }
2126:
2127:            protected final void performDefaults() {
2128:
2129:                // Ask the user to confirm
2130:                final String title = NewKeysPreferenceMessages.RestoreDefaultsMessageBoxText;
2131:                final String message = NewKeysPreferenceMessages.RestoreDefaultsMessageBoxMessage;
2132:                final boolean confirmed = MessageDialog.openConfirm(getShell(),
2133:                        title, message);
2134:
2135:                if (confirmed) {
2136:                    // Fix the scheme in the local changes.
2137:                    final String defaultSchemeId = bindingService
2138:                            .getDefaultSchemeId();
2139:                    final Scheme defaultScheme = localChangeManager
2140:                            .getScheme(defaultSchemeId);
2141:                    try {
2142:                        localChangeManager.setActiveScheme(defaultScheme);
2143:                    } catch (final NotDefinedException e) {
2144:                        // At least we tried....
2145:                    }
2146:
2147:                    // Fix the bindings in the local changes.
2148:                    final Binding[] currentBindings = localChangeManager
2149:                            .getBindings();
2150:                    final int currentBindingsLength = currentBindings.length;
2151:                    final Set trimmedBindings = new HashSet();
2152:                    for (int i = 0; i < currentBindingsLength; i++) {
2153:                        final Binding binding = currentBindings[i];
2154:                        if (binding.getType() != Binding.USER) {
2155:                            trimmedBindings.add(binding);
2156:                        }
2157:                    }
2158:                    final Binding[] trimmedBindingArray = (Binding[]) trimmedBindings
2159:                            .toArray(new Binding[trimmedBindings.size()]);
2160:                    localChangeManager.setBindings(trimmedBindingArray);
2161:
2162:                    // Apply the changes.
2163:                    try {
2164:                        bindingService.savePreferences(defaultScheme,
2165:                                trimmedBindingArray);
2166:                    } catch (final IOException e) {
2167:                        logPreferenceStoreException(e);
2168:                    }
2169:                    long startTime = 0L;
2170:                    if (DEBUG) {
2171:                        startTime = System.currentTimeMillis();
2172:                    }
2173:                    busyRefillTree();
2174:                    if (DEBUG) {
2175:                        final long elapsedTime = System.currentTimeMillis()
2176:                                - startTime;
2177:                        Tracing.printTrace(TRACING_COMPONENT,
2178:                                "performDefaults:model in " //$NON-NLS-1$
2179:                                        + elapsedTime + "ms"); //$NON-NLS-1$
2180:                    }
2181:                }
2182:
2183:                setScheme(localChangeManager.getActiveScheme());
2184:
2185:                super .performDefaults();
2186:            }
2187:
2188:            /**
2189:             * We're re-filling the  entire tree, both bindings and commands.  It's
2190:             * loud.
2191:             */
2192:            private void busyRefillTree() {
2193:                if (bindingModel == null) {
2194:                    // we haven't really been created yet.
2195:                    return;
2196:                }
2197:                BusyIndicator.showWhile(filteredTree.getViewer().getTree()
2198:                        .getDisplay(), new Runnable() {
2199:                    public void run() {
2200:                        try {
2201:                            filteredTree.getViewer().getTree().setRedraw(false);
2202:
2203:                            bindingModel.clear();
2204:                            commandModel.clear();
2205:                            Collection comeBack = localChangeManager
2206:                                    .getActiveBindingsDisregardingContextFlat();
2207:                            bindingModel.addAll(comeBack);
2208:
2209:                            // showAllCheckBox.setSelection(false);
2210:                            fillInCommands();
2211:                        } finally {
2212:                            filteredTree.getViewer().getTree().setRedraw(true);
2213:                        }
2214:                    }
2215:                });
2216:                updateDataControls();
2217:            }
2218:
2219:            public final boolean performOk() {
2220:                // Save the preferences.
2221:                try {
2222:                    bindingService.savePreferences(localChangeManager
2223:                            .getActiveScheme(), localChangeManager
2224:                            .getBindings());
2225:                } catch (final IOException e) {
2226:                    logPreferenceStoreException(e);
2227:                }
2228:                saveState(getDialogSettings());
2229:                return super .performOk();
2230:            }
2231:
2232:            /**
2233:             * Handles the selection event on the add binding button. This adds a new
2234:             * binding based on the current selection.
2235:             * 
2236:             * @param event
2237:             *            Ignored.
2238:             */
2239:            private final void selectAddBindingButton(final SelectionEvent event) {
2240:                long startTime = 0L;
2241:                if (DEBUG) {
2242:                    startTime = System.currentTimeMillis();
2243:                }
2244:
2245:                // Check to make sure we've got a selection.
2246:                final TreeViewer viewer = filteredTree.getViewer();
2247:                final ISelection selection = viewer.getSelection();
2248:                if (!(selection instanceof  IStructuredSelection)) {
2249:                    return;
2250:                }
2251:
2252:                final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
2253:                final Object firstElement = structuredSelection
2254:                        .getFirstElement();
2255:                final Object value = firstElement;
2256:                if (value instanceof  KeyBinding) {
2257:                    bindingAdd((KeyBinding) value);
2258:                } else if (value instanceof  ParameterizedCommand) {
2259:                    bindingText.setFocus();
2260:                }
2261:
2262:                if (DEBUG) {
2263:                    final long elapsedTime = System.currentTimeMillis()
2264:                            - startTime;
2265:                    Tracing.printTrace(TRACING_COMPONENT,
2266:                            "selectAddBindingButton in " //$NON-NLS-1$
2267:                                    + elapsedTime + "ms"); //$NON-NLS-1$
2268:                }
2269:            }
2270:
2271:            /**
2272:             * Handles the selection event on the remove binding button. This removes
2273:             * the selected binding.
2274:             * 
2275:             * @param event
2276:             *            Ignored.
2277:             */
2278:            private final void selectRemoveBindingButton(
2279:                    final SelectionEvent event) {
2280:                long startTime = 0L;
2281:                if (DEBUG) {
2282:                    startTime = System.currentTimeMillis();
2283:                }
2284:                // Check to make sure we've got a selection.
2285:                final TreeViewer viewer = filteredTree.getViewer();
2286:                final ISelection selection = viewer.getSelection();
2287:                if (!(selection instanceof  IStructuredSelection)) {
2288:                    return;
2289:                }
2290:
2291:                final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
2292:                final Object firstElement = structuredSelection
2293:                        .getFirstElement();
2294:                final Object value = firstElement;
2295:                if (value instanceof  KeyBinding) {
2296:                    bindingRemove((KeyBinding) value);
2297:                } else if (value == markedParameterizedCommand) {
2298:                    commandModel.remove(markedParameterizedCommand);
2299:                    markedParameterizedCommand = null;
2300:                    markedContextId = null;
2301:                    update();
2302:                }
2303:                if (DEBUG) {
2304:                    final long elapsedTime = System.currentTimeMillis()
2305:                            - startTime;
2306:                    Tracing.printTrace(TRACING_COMPONENT,
2307:                            "selectRemoveBindingButton in " //$NON-NLS-1$
2308:                                    + elapsedTime + "ms"); //$NON-NLS-1$
2309:                }
2310:            }
2311:
2312:            private final void selectRestoreBindingButton(
2313:                    final SelectionEvent event) {
2314:                long startTime = 0L;
2315:                if (DEBUG) {
2316:                    startTime = System.currentTimeMillis();
2317:                }
2318:                // Check to make sure we've got a selection.
2319:                final TreeViewer viewer = filteredTree.getViewer();
2320:                final ISelection selection = viewer.getSelection();
2321:                if (!(selection instanceof  IStructuredSelection)) {
2322:                    return;
2323:                }
2324:
2325:                final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
2326:                final Object firstElement = structuredSelection
2327:                        .getFirstElement();
2328:                final Object value = firstElement;
2329:                if (value instanceof  KeyBinding) {
2330:                    bindingRestore((KeyBinding) value);
2331:                } else if (value instanceof  ParameterizedCommand) {
2332:                    bindingRestore((ParameterizedCommand) value, true);
2333:                }
2334:                if (DEBUG) {
2335:                    final long elapsedTime = System.currentTimeMillis()
2336:                            - startTime;
2337:                    Tracing.printTrace(TRACING_COMPONENT,
2338:                            "selectRestoreBindingButton in " //$NON-NLS-1$
2339:                                    + elapsedTime + "ms"); //$NON-NLS-1$
2340:                }
2341:            }
2342:
2343:            /**
2344:             * Handles a selection event on the scheme combo. If the scheme has changed,
2345:             * then the local change manager is updated, and the page's contents are
2346:             * updated as well.
2347:             * 
2348:             * @param event
2349:             *            The selection event; must not be <code>null</code>.
2350:             */
2351:            private final void selectSchemeCombo(
2352:                    final SelectionChangedEvent event) {
2353:                final ISelection selection = event.getSelection();
2354:                if (selection instanceof  IStructuredSelection) {
2355:                    final Object firstElement = ((IStructuredSelection) selection)
2356:                            .getFirstElement();
2357:                    if (firstElement instanceof  Scheme) {
2358:                        final Scheme newScheme = (Scheme) firstElement;
2359:                        if (newScheme != localChangeManager.getActiveScheme()) {
2360:                            try {
2361:                                localChangeManager.setActiveScheme(newScheme);
2362:                                busyRefillTree();
2363:                            } catch (final NotDefinedException e) {
2364:                                // TODO The scheme wasn't valid.
2365:                            }
2366:                        }
2367:                    }
2368:                }
2369:            }
2370:
2371:            /**
2372:             * If the row has changed, then update the data controls.
2373:             */
2374:            private final void selectTreeRow(final SelectionChangedEvent event) {
2375:                updateDataControls();
2376:            }
2377:
2378:            /**
2379:             * Sets the currently selected scheme. Setting the scheme always triggers an
2380:             * update of the underlying widgets.
2381:             * 
2382:             * @param scheme
2383:             *            The scheme to select; may be <code>null</code>.
2384:             */
2385:            private final void setScheme(final Scheme scheme) {
2386:                schemeCombo.setSelection(new StructuredSelection(scheme));
2387:            }
2388:
2389:            /**
2390:             * Updates all of the controls on this preference page in response to a user
2391:             * interaction.
2392:             */
2393:            private final void update() {
2394:                updateTree();
2395:                updateDataControls();
2396:            }
2397:
2398:            /**
2399:             * Updates the data controls to match the current selection, if any.
2400:             */
2401:            private final void updateDataControls() {
2402:                final ISelection selection = filteredTree.getViewer()
2403:                        .getSelection();
2404:                if (selection instanceof  IStructuredSelection) {
2405:                    final IStructuredSelection structuredSelection = (IStructuredSelection) selection;
2406:                    final Object node = structuredSelection.getFirstElement();
2407:                    if (node != null) {
2408:                        final Object object = node;
2409:                        if (object instanceof  KeyBinding) {
2410:                            final KeyBinding binding = (KeyBinding) object;
2411:                            try {
2412:                                commandNameValueLabel.setText(binding
2413:                                        .getParameterizedCommand().getName());
2414:                                String description = binding
2415:                                        .getParameterizedCommand().getCommand()
2416:                                        .getDescription();
2417:                                if (description == null) {
2418:                                    description = Util.ZERO_LENGTH_STRING;
2419:                                }
2420:                                descriptionValueText.setText(description);
2421:                            } catch (final NotDefinedException e) {
2422:                                // It's probably okay to just let this one slide.
2423:                            }
2424:                            whenCombo.setSelection(new StructuredSelection(
2425:                                    contextService.getContext(binding
2426:                                            .getContextId())));
2427:                            keySequenceText.setKeySequence(binding
2428:                                    .getKeySequence());
2429:
2430:                        } else if (object instanceof  ParameterizedCommand) {
2431:                            final ParameterizedCommand command = (ParameterizedCommand) object;
2432:                            try {
2433:                                commandNameValueLabel
2434:                                        .setText(command.getName());
2435:                                String description = command.getCommand()
2436:                                        .getDescription();
2437:                                if (description == null) {
2438:                                    description = Util.ZERO_LENGTH_STRING;
2439:                                }
2440:                                descriptionValueText.setText(description);
2441:                            } catch (final NotDefinedException e) {
2442:                                // It's probably okay to just let this one slide.
2443:                            }
2444:                            keySequenceText.clear();
2445:                            if (command == markedParameterizedCommand) {
2446:                                whenCombo.setSelection(new StructuredSelection(
2447:                                        contextService
2448:                                                .getContext(markedContextId)));
2449:                            } else {
2450:                                whenCombo
2451:                                        .setSelection(new StructuredSelection(
2452:                                                contextService
2453:                                                        .getContext(IContextIds.CONTEXT_ID_WINDOW)));
2454:                            }
2455:                        }
2456:                    } else {
2457:                        commandNameValueLabel.setText(""); //$NON-NLS-1$
2458:                        descriptionValueText.setText(""); //$NON-NLS-1$
2459:                        keySequenceText.clear();
2460:                        whenCombo.setSelection(null);
2461:                    }
2462:                }
2463:            }
2464:
2465:            private final void updateTree() {
2466:                long startTime = 0L;
2467:                if (DEBUG) {
2468:                    startTime = System.currentTimeMillis();
2469:                }
2470:
2471:                final TreeViewer viewer = filteredTree.getViewer();
2472:
2473:                // Add the marked parameterized command, if any.
2474:                if (markedParameterizedCommand != null) {
2475:                    commandModel.add(markedParameterizedCommand);
2476:                    markedParameterizedCommand = null;
2477:                }
2478:
2479:                // Repack all of the columns.
2480:                final Tree tree = viewer.getTree();
2481:                final TreeColumn[] columns = tree.getColumns();
2482:
2483:                columns[BindingLabelProvider.COLUMN_COMMAND].setWidth(240);
2484:                columns[BindingLabelProvider.COLUMN_TRIGGER_SEQUENCE]
2485:                        .setWidth(130);
2486:                columns[BindingLabelProvider.COLUMN_WHEN].setWidth(130);
2487:                columns[BindingLabelProvider.COLUMN_CATEGORY].setWidth(130);
2488:                columns[BindingLabelProvider.COLUMN_USER].setWidth(50);
2489:
2490:                if (DEBUG) {
2491:                    final long elapsedTime = System.currentTimeMillis()
2492:                            - startTime;
2493:                    Tracing.printTrace(TRACING_COMPONENT, "Refreshed page in " //$NON-NLS-1$
2494:                            + elapsedTime + "ms"); //$NON-NLS-1$
2495:                }
2496:            }
2497:
2498:            /**
2499:             * Save the state of the receiver.
2500:             * 
2501:             * @param dialogSettings
2502:             */
2503:            public void saveState(IDialogSettings dialogSettings) {
2504:                if (dialogSettings == null) {
2505:                    return;
2506:                }
2507:                dialogSettings.put(TAG_FIELD, showAllCheckBox.getSelection());
2508:                dialogSettings.put(TAG_FILTER_ACTION_SETS,
2509:                        filterActionSetContexts);
2510:                dialogSettings.put(TAG_FILTER_INTERNAL, filterInternalContexts);
2511:                dialogSettings.put(TAG_FILTER_UNCAT, filteredTree
2512:                        .isFilteringCategories());
2513:            }
2514:
2515:            protected IDialogSettings getDialogSettings() {
2516:                IDialogSettings workbenchSettings = WorkbenchPlugin
2517:                        .getDefault().getDialogSettings();
2518:
2519:                IDialogSettings settings = workbenchSettings
2520:                        .getSection(TAG_DIALOG_SECTION);
2521:
2522:                if (settings == null) {
2523:                    settings = workbenchSettings
2524:                            .addNewSection(TAG_DIALOG_SECTION);
2525:                }
2526:                return settings;
2527:            }
2528:
2529:            protected Object[] getContexts() {
2530:
2531:                Context[] contexts = contextService.getDefinedContexts();
2532:                List filteredContexts = new ArrayList();
2533:                try {
2534:                    if (filterActionSetContexts) {
2535:                        for (int i = 0; i < contexts.length; i++) {
2536:                            String parentId = contexts[i].getParentId();
2537:                            boolean check = false;
2538:                            if (contexts[i].getId().equalsIgnoreCase(
2539:                                    CONTEXT_ID_ACTION_SETS)) {
2540:                                check = true;
2541:                            }
2542:                            while (parentId != null) {
2543:                                if (parentId
2544:                                        .equalsIgnoreCase(CONTEXT_ID_ACTION_SETS)) {
2545:                                    check = true;
2546:                                }
2547:                                parentId = contextService.getContext(parentId)
2548:                                        .getParentId();
2549:                            }
2550:                            if (!check) {
2551:                                filteredContexts.add(contexts[i]);
2552:                            }
2553:                        }
2554:                    } else {
2555:                        filteredContexts.addAll(Arrays.asList(contexts));
2556:                    }
2557:
2558:                    if (filterInternalContexts) {
2559:                        for (int i = 0; i < filteredContexts.size(); i++) {
2560:                            if (((Context) filteredContexts.get(i)).getId()
2561:                                    .indexOf(CONTEXT_ID_INTERNAL) != -1) {
2562:                                filteredContexts.remove(i);
2563:                            }
2564:                        }
2565:                    }
2566:
2567:                } catch (NotDefinedException e) {
2568:                    return contexts;
2569:                }
2570:
2571:                return filteredContexts.toArray();
2572:            }
2573:
2574:            private void updateWhenCombo() {
2575:                ISelection selection = filteredTree.getViewer().getSelection();
2576:                if (selection instanceof  IStructuredSelection) {
2577:                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
2578:                    Object node = structuredSelection.getFirstElement();
2579:                    if (node != null) {
2580:                        final Object object = node;
2581:                        selection = whenCombo.getSelection();
2582:                        final String contextId;
2583:                        if (selection instanceof  IStructuredSelection) {
2584:                            structuredSelection = (IStructuredSelection) selection;
2585:                            final Object firstElement = structuredSelection
2586:                                    .getFirstElement();
2587:                            if (firstElement == null) {
2588:                                contextId = IContextIds.CONTEXT_ID_WINDOW;
2589:                            } else {
2590:                                contextId = ((Context) firstElement).getId();
2591:                            }
2592:                        } else {
2593:                            contextId = IContextIds.CONTEXT_ID_WINDOW;
2594:                        }
2595:                        if (object instanceof  KeyBinding) {
2596:                            KeyBinding keyBinding = (KeyBinding) object;
2597:                            if (!keyBinding.getContextId().equals(contextId)) {
2598:                                final KeyBinding binding = new KeyBinding(
2599:                                        keyBinding.getKeySequence(), keyBinding
2600:                                                .getParameterizedCommand(),
2601:                                        getSchemeId(), contextId, null, null,
2602:                                        null, Binding.USER);
2603:
2604:                                if (keyBinding.getType() == Binding.USER) {
2605:                                    localChangeManager
2606:                                            .removeBinding(keyBinding);
2607:                                } else {
2608:                                    localChangeManager
2609:                                            .addBinding(new KeyBinding(
2610:                                                    keyBinding.getKeySequence(),
2611:                                                    null, keyBinding
2612:                                                            .getSchemeId(),
2613:                                                    keyBinding.getContextId(),
2614:                                                    null, null, null,
2615:                                                    Binding.USER));
2616:                                }
2617:                                localChangeManager.addBinding(binding);
2618:                                // update the model
2619:                                bindingModel.remove(keyBinding);
2620:                                bindingModel.add(binding);
2621:                                updateConflicts(keyBinding);
2622:                                updateConflicts(binding);
2623:                                // end update the model
2624:                                update();
2625:                                filteredTree.getViewer().setSelection(
2626:                                        new StructuredSelection(binding), true);
2627:                            }
2628:                        }
2629:                    }
2630:                }
2631:            }
2632:
2633:            /*
2634:             * (non-Javadoc)
2635:             * 
2636:             * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
2637:             */
2638:            public void applyData(Object data) {
2639:                if (data instanceof  Binding && filteredTree != null) {
2640:                    filteredTree.getViewer().setSelection(
2641:                            new StructuredSelection(data), true);
2642:                }
2643:            }
2644:
2645:            public String getSchemeId() {
2646:                ISelection sel = schemeCombo.getSelection();
2647:                if (sel instanceof  IStructuredSelection) {
2648:                    Object o = ((IStructuredSelection) sel).getFirstElement();
2649:                    if (o instanceof  Scheme) {
2650:                        return ((Scheme) o).getId();
2651:                    }
2652:                }
2653:                return IBindingService.DEFAULT_DEFAULT_ACTIVE_SCHEME_ID;
2654:            }
2655:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.