Source Code Cross Referenced for FeatureTableControl.java in  » GIS » udig-1.1 » net » refractions » udig » ui » 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 » GIS » udig 1.1 » net.refractions.udig.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package net.refractions.udig.ui;
0002:
0003:        import java.lang.reflect.Array;
0004:        import java.util.Collection;
0005:        import java.util.Collections;
0006:        import java.util.Comparator;
0007:        import java.util.List;
0008:        import java.util.Set;
0009:        import java.util.concurrent.CopyOnWriteArraySet;
0010:        import java.util.regex.Pattern;
0011:        import java.util.regex.PatternSyntaxException;
0012:
0013:        import net.refractions.udig.core.IProvider;
0014:        import net.refractions.udig.internal.ui.Trace;
0015:        import net.refractions.udig.internal.ui.UiPlugin;
0016:        import net.refractions.udig.ui.internal.Messages;
0017:
0018:        import org.eclipse.core.runtime.IAdaptable;
0019:        import org.eclipse.core.runtime.IProgressMonitor;
0020:        import org.eclipse.jface.action.MenuManager;
0021:        import org.eclipse.jface.dialogs.MessageDialogWithToggle;
0022:        import org.eclipse.jface.preference.IPreferenceStore;
0023:        import org.eclipse.jface.viewers.CellEditor;
0024:        import org.eclipse.jface.viewers.ColumnWeightData;
0025:        import org.eclipse.jface.viewers.IBaseLabelProvider;
0026:        import org.eclipse.jface.viewers.ICellEditorListener;
0027:        import org.eclipse.jface.viewers.ICellEditorValidator;
0028:        import org.eclipse.jface.viewers.ICellModifier;
0029:        import org.eclipse.jface.viewers.IContentProvider;
0030:        import org.eclipse.jface.viewers.ISelection;
0031:        import org.eclipse.jface.viewers.ISelectionChangedListener;
0032:        import org.eclipse.jface.viewers.ISelectionProvider;
0033:        import org.eclipse.jface.viewers.StructuredSelection;
0034:        import org.eclipse.jface.viewers.TableLayout;
0035:        import org.eclipse.jface.viewers.TableViewer;
0036:        import org.eclipse.jface.viewers.TextCellEditor;
0037:        import org.eclipse.swt.SWT;
0038:        import org.eclipse.swt.graphics.Color;
0039:        import org.eclipse.swt.widgets.Composite;
0040:        import org.eclipse.swt.widgets.Control;
0041:        import org.eclipse.swt.widgets.Display;
0042:        import org.eclipse.swt.widgets.Event;
0043:        import org.eclipse.swt.widgets.Listener;
0044:        import org.eclipse.swt.widgets.Menu;
0045:        import org.eclipse.swt.widgets.Table;
0046:        import org.eclipse.swt.widgets.TableColumn;
0047:        import org.eclipse.swt.widgets.Text;
0048:        import org.eclipse.ui.part.PageBook;
0049:        import org.geotools.feature.AttributeType;
0050:        import org.geotools.feature.Feature;
0051:        import org.geotools.feature.FeatureCollection;
0052:        import org.geotools.feature.FeatureType;
0053:        import org.geotools.filter.FidFilter;
0054:
0055:        import com.vividsolutions.jts.geom.Geometry;
0056:
0057:        /**
0058:         * A TreeViewer control for viewing a table of Feature attributes.
0059:         * <p>
0060:         * The object is used by using a FeatureCollection. In this case the control hangs on to a reference
0061:         * to the FeatureCollection and populates the table entries directory from it. This method results
0062:         * in a single page containing all features.
0063:         * </p>
0064:         * <p>
0065:         * If the FeatureCollection implements the {@link IAdaptable} interface and adapts to
0066:         * {@link ICellModifier} then the table is editable. The {@link ICellModifier} is used to modify the
0067:         * features. The Column properties passed to the {@link ICellModifier} are the attribute name of the
0068:         * attribute being modified.
0069:         * </p>
0070:         * <p>
0071:         * If the FeatureCollection implements the {@link IAdaptable} interface and adapts to
0072:         * {@link CellEditor[]} then the cell editors will be used to edit the cells. This is optional for
0073:         * editing. By default a {@link TextCellEditor} is used for editing most cells, and an
0074:         * {@link AttributeValidator} is used to validate the new values. The first column is for the fid
0075:         * column and will not be used since FIDS are assigned by the datastore and can not be modified. The
0076:         * number of Items the array (this is the same for the cell editor validators and cell editor
0077:         * listeners) must be either the number of attributes in the feature type or the number of
0078:         * attributes + 1 (one for the FID column). If the number of editors it Attributes+1 then the first
0079:         * element in the array will not be used as it is assumed to be a placeholder for the fid column.
0080:         * </p>
0081:         * <p>
0082:         * If the FeatureCollection implements the {@link IAdaptable} interface and adapts to
0083:         * {@link ICellEditorValidator[]} then the validators will be used to validate the cells.
0084:         * </p>
0085:         * <p>
0086:         * If the FeatureCollection implements the {@link IAdaptable} interface and adapts to
0087:         * {@link ICellEditorListener[]} then the listeners will be added to the {@link CellEditor}s.
0088:         * </p>
0089:         * 
0090:         * @author jdeolive
0091:         * @author jeichar
0092:         * @since 0.3
0093:         */
0094:        public class FeatureTableControl implements  ISelectionProvider {
0095:
0096:            public static final String FEATURE_ID_COLUMN_PROPERTY = "FeatureIDProperty"; //$NON-NLS-1$
0097:
0098:            public static final Object ERROR_COLUMN_PROPERTY = "ErrorProperty"; //$NON-NLS-1$
0099:
0100:            public static final Object LOADING = new Object();
0101:
0102:            /** results per page * */
0103:            private int pageSize = 10; // XXX: actual put this as a user pref
0104:
0105:            /** table viewer control * */
0106:            private TableViewer tableViewer;
0107:
0108:            private PageBook book;
0109:
0110:            private Text message;
0111:
0112:            FeatureCollection features;
0113:
0114:            private final IProvider<IProgressMonitor> progressMonitorProvider;
0115:
0116:            private FeatureTableSelectionProvider selectionProvider;
0117:
0118:            private Color messageBackground;
0119:
0120:            private Color messageForeground;
0121:
0122:            private Set<IFeatureTableLoadingListener> loadingListeners = new CopyOnWriteArraySet<IFeatureTableLoadingListener>();
0123:
0124:            private Comparator<Feature> currentComparator;
0125:
0126:            private MenuManager contextMenu;
0127:
0128:            /**
0129:             * Construct <code>FeatureTableControl</code>.
0130:             * <p>
0131:             * Must call setFeatures before use.
0132:             * </p>
0133:             */
0134:            public FeatureTableControl() {
0135:                this (ProgressManager.instance());
0136:            }
0137:
0138:            /**
0139:             * Construct a <code>FeatureTableControl</code>.
0140:             * 
0141:             * @param monitorProvider a provider that will provider progress monitors for displaying loading
0142:             *        information.
0143:             * @param fReader The FeatureReader that returns the actual features.
0144:             * @param resPerPage Results per page to be shown in the table.
0145:             */
0146:            public FeatureTableControl(Composite parent,
0147:                    FeatureCollection features) {
0148:                this (ProgressManager.instance(), parent, features);
0149:            }
0150:
0151:            /**
0152:             * Construct <code>FeatureTableControl</code>.
0153:             * <p>
0154:             * Must call setFeatures before use.
0155:             * </p>
0156:             * 
0157:             * @param monitorProvider a provider that will provider progress monitors for displaying loading
0158:             *        information.
0159:             */
0160:            public FeatureTableControl(
0161:                    final IProvider<IProgressMonitor> monitorProvider) {
0162:                this .progressMonitorProvider = monitorProvider;
0163:                this .selectionProvider = new FeatureTableSelectionProvider(
0164:                        this , ProgressManager.instance());
0165:            }
0166:
0167:            /**
0168:             * Construct a <code>FeatureTableControl</code>.
0169:             * 
0170:             * @param monitorProvider a provider that will provider progress monitors for displaying loading
0171:             *        information.
0172:             * @param fReader The FeatureReader that returns the actual features.
0173:             * @param resPerPage Results per page to be shown in the table.
0174:             */
0175:            public FeatureTableControl(
0176:                    final IProvider<IProgressMonitor> monitorProvider,
0177:                    Composite parent, FeatureCollection features) {
0178:                this (monitorProvider);
0179:                this .features = features;
0180:                createTableControl(parent);
0181:            }
0182:
0183:            /**
0184:             * Sets the number of features viewed in the table per page.
0185:             * 
0186:             * @param resPerPage positive integer.
0187:             */
0188:            public void setPageSize(int resPerPage) {
0189:                this .pageSize = resPerPage;
0190:            }
0191:
0192:            /**
0193:             * Returns the number of features viewed in the table per page.
0194:             * 
0195:             * @return positive integer.
0196:             */
0197:            public int getPageSize() {
0198:                return pageSize;
0199:            }
0200:
0201:            /**
0202:             * Returns the control representing the table control.
0203:             * 
0204:             * @return The internal table viewer control.
0205:             */
0206:            public Control getControl() {
0207:                return book;
0208:            }
0209:
0210:            public void dispose() {
0211:                disposeTableViewer();
0212:            }
0213:
0214:            /**
0215:             * Creates the table control.
0216:             * 
0217:             * @param parent The to be parent of the control.
0218:             */
0219:            public void createTableControl(Composite parent) {
0220:                showWarning(parent.getDisplay());
0221:                book = new PageBook(parent, SWT.NONE);
0222:                message = new Text(book, SWT.WRAP);
0223:                messageBackground = message.getBackground();
0224:                messageForeground = message.getForeground();
0225:                createTableViewer(book);
0226:            }
0227:
0228:            /**
0229:             * Key for indicating whether the warning should be displayed.  false if the warning is displayed
0230:             */
0231:            public static final String CACHING_WARNING = "FEATURE_TABLE_CACHING_IN_MEMORY_WARNING"; //$NON-NLS-1$
0232:
0233:            /**
0234:             * Indicates that all attribute types will be searched by the select method
0235:             * @see #select(String, String[], boolean)
0236:             */
0237:            public static final String[] ALL = new String[0];
0238:
0239:            private static final boolean SHOW_PATH = false;
0240:
0241:            private void showWarning(Display display) {
0242:
0243:                IPreferenceStore preferenceStore = UiPlugin.getDefault()
0244:                        .getPreferenceStore();
0245:                if (!preferenceStore.getBoolean(CACHING_WARNING)) {
0246:                    MessageDialogWithToggle dialog = MessageDialogWithToggle
0247:                            .openWarning(
0248:                                    display.getActiveShell(),
0249:                                    Messages.FeatureTableControl_warningTitle,
0250:                                    Messages.FeatureTableControl_warningMessage,
0251:                                    Messages.FeatureTableControl_warningToggle,
0252:                                    false, null, null);
0253:                    preferenceStore.setValue(CACHING_WARNING, dialog
0254:                            .getToggleState());
0255:
0256:                }
0257:
0258:            }
0259:
0260:            /**
0261:             * Updates the table control with the current set of features.
0262:             * <p>
0263:             * This method will ensure that the column information gets updated
0264:             * </p>
0265:             */
0266:            public void update() {
0267:                checkWidget();
0268:                if (tableViewer != null) {
0269:                    tableViewer.setInput(features);
0270:                    tableViewer.getTable().clearAll();
0271:                }
0272:            }
0273:
0274:            /**
0275:             * Creates the table control itself.
0276:             * 
0277:             * @param parent
0278:             */
0279:            protected void createTableViewer(Composite parent) {
0280:                int style = SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.H_SCROLL
0281:                        | SWT.V_SCROLL;
0282:                if (tableViewer != null) {
0283:                    disposeTableViewer();
0284:                }
0285:                final Table table = new Table(parent, style);
0286:                table.setLinesVisible(true);
0287:                TableLayout layout = new TableLayout();
0288:                table.setLayout(layout);
0289:
0290:                FeatureTableContentProvider ftp = new FeatureTableContentProvider(
0291:                        this , this .progressMonitorProvider);
0292:                FeatureTableLabelProvider flp = new FeatureTableLabelProvider(
0293:                        this );
0294:                tableViewer = new TableViewer(table);
0295:
0296:                tableViewer.setContentProvider(ftp);
0297:                tableViewer.setLabelProvider(flp);
0298:
0299:                // create columns after tableViewer is created because Column listeners need to access the
0300:                // tableViewer.
0301:                createAttributeColumns(table, tableViewer, layout);
0302:                table.setHeaderVisible(true);
0303:
0304:                addSelectionListener(table);
0305:                if (features instanceof  IAdaptable
0306:                        && ((IAdaptable) features)
0307:                                .getAdapter(ICellModifier.class) != null) {
0308:
0309:                    IAdaptable adaptable = (IAdaptable) features;
0310:                    FeatureType schema = features.getSchema();
0311:                    int attributeCount = schema.getAttributeCount();
0312:                    setCellEditors(adaptable, attributeCount);
0313:
0314:                    setCellValidators(adaptable);
0315:                    addCellEditorListeners(adaptable);
0316:                    tableViewer.setCellModifier((ICellModifier) adaptable
0317:                            .getAdapter(ICellModifier.class));
0318:
0319:                    String[] properties = new String[attributeCount + 1];
0320:                    for (int i = 0; i < properties.length; i++) {
0321:                        if (i == 0)
0322:                            properties[i] = FEATURE_ID_COLUMN_PROPERTY;
0323:                        else {
0324:                            properties[i] = schema.getAttributeType(i - 1)
0325:                                    .getName();
0326:                        }
0327:                    }
0328:                    tableViewer.setColumnProperties(properties);
0329:                }
0330:                if (contextMenu != null) {
0331:                    Menu menu = contextMenu.createContextMenu(tableViewer
0332:                            .getControl());
0333:                    tableViewer.getControl().setMenu(menu);
0334:                }
0335:                book.showPage(tableViewer.getControl());
0336:
0337:                UiPlugin
0338:                        .trace(
0339:                                Trace.FEATURE_TABLE,
0340:                                getClass(),
0341:                                "createTableViewer(): showing table View", SHOW_PATH ? new Exception() : null); //$NON-NLS-1$
0342:
0343:                if (features != null) {
0344:                    tableViewer.setInput(features);
0345:                }
0346:
0347:            }
0348:
0349:            private void addSelectionListener(final Table table) {
0350:                // We are not using default selection provided by the table because it is too slow
0351:                // so I am doing my own listening and based on which items are selected and what
0352:                // keys are down I am simulating the selection behaviour.
0353:                table.addListener(SWT.MouseDown, new Listener() {
0354:
0355:                    int lastIndex = -1;
0356:
0357:                    public void handleEvent(Event e) {
0358:
0359:                        int index = table.getSelectionIndex();
0360:                        FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
0361:                                .getContentProvider();
0362:                        Collection<String> selectionFids = selectionProvider
0363:                                .getSelectionFids();
0364:
0365:                        table.deselect(index);
0366:                        if ((e.stateMask & SWT.MOD2) != 0 && lastIndex != -1) {
0367:                            if (lastIndex == index)
0368:                                return;
0369:                            handleSelecteRange(table, index, provider,
0370:                                    selectionFids);
0371:                        } else if ((e.stateMask & SWT.MOD1) != 0) {
0372:                            handleXORSelect(table, index, provider,
0373:                                    selectionFids);
0374:                        } else {
0375:                            if (lastIndex == index)
0376:                                return;
0377:                            handleDefault(table, index, provider, selectionFids);
0378:                        }
0379:
0380:                        selectionProvider.notifyListeners();
0381:                    }
0382:
0383:                    private void handleDefault(final Table table, int index,
0384:                            FeatureTableContentProvider provider,
0385:                            Collection<String> selectionFids) {
0386:                        if (index == -1) {
0387:                            selectionFids.clear();
0388:                            table.clearAll();
0389:                        } else {
0390:                            String fid = provider.features.get(index).getID();
0391:                            selectionFids.clear();
0392:                            selectionFids.add(fid);
0393:                            table.clearAll();
0394:                        }
0395:                        lastIndex = index;
0396:                    }
0397:
0398:                    private void handleXORSelect(final Table table, int index,
0399:                            FeatureTableContentProvider provider,
0400:                            Collection<String> selectionFids) {
0401:                        String fid = provider.features.get(index).getID();
0402:                        if (selectionFids.contains(fid)) {
0403:                            selectionFids.remove(fid);
0404:                        } else {
0405:                            selectionFids.add(fid);
0406:                        }
0407:                        table.clear(index);
0408:                        lastIndex = index;
0409:                    }
0410:
0411:                    private void handleSelecteRange(final Table table,
0412:                            int index, FeatureTableContentProvider provider,
0413:                            Collection<String> selectionFids) {
0414:                        selectionFids.clear();
0415:
0416:                        int low = Math.min(lastIndex, index);
0417:                        int high = Math.max(lastIndex, index);
0418:                        List<Feature> toAdd = provider.features.subList(low,
0419:                                high + 1);
0420:                        boolean foundUnselectedItem = false;
0421:                        int i = low;
0422:                        for (Feature feature : toAdd) {
0423:                            if (selectionFids.add(feature.getID())) {
0424:                                foundUnselectedItem = true;
0425:                            }
0426:
0427:                            i++;
0428:                        }
0429:                        if (foundUnselectedItem)
0430:                            table.clearAll();
0431:                    }
0432:
0433:                });
0434:            }
0435:
0436:            private void disposeTableViewer() {
0437:                if (tableViewer == null)
0438:                    return;
0439:                IContentProvider contentProvider = tableViewer
0440:                        .getContentProvider();
0441:                if (contentProvider != null)
0442:                    contentProvider.dispose();
0443:                IBaseLabelProvider labelProvider = tableViewer
0444:                        .getLabelProvider();
0445:                if (labelProvider != null)
0446:                    labelProvider.dispose();
0447:                Control control = tableViewer.getControl();
0448:                if (control != null)
0449:                    control.dispose();
0450:                tableViewer = null;
0451:            }
0452:
0453:            private void setCellEditors(IAdaptable adaptable, int attributeCount) {
0454:                if (adaptable.getAdapter(CellEditor[].class) != null) {
0455:                    CellEditor[] editors = (CellEditor[]) adaptable
0456:                            .getAdapter(Array.class);
0457:                    if (editors.length < attributeCount) {
0458:                        UiPlugin
0459:                                .log(
0460:                                        "not enough cell editors for feature type so not used", new Exception()); //$NON-NLS-1$
0461:                        createCellEditors();
0462:                    } else {
0463:                        CellEditor[] copy = new CellEditor[editors.length + 1];
0464:                        if (editors.length == attributeCount) {
0465:                            // there is an editor for each attribute. First element in copy if for the
0466:                            // fid column (which is not editable).
0467:                            System.arraycopy(editors, 0, copy, 1,
0468:                                    attributeCount);
0469:                        } else {
0470:
0471:                            // ignore 1st element in editors because it is for the FID column which is read
0472:                            // only.
0473:                            System.arraycopy(editors, 1, copy, 1,
0474:                                    attributeCount);
0475:
0476:                        }
0477:                        tableViewer.setCellEditors(copy);
0478:                    }
0479:                } else {
0480:                    createCellEditors();
0481:                }
0482:            }
0483:
0484:            private void addCellEditorListeners(IAdaptable adaptable) {
0485:                CellEditor[] editors = tableViewer.getCellEditors();
0486:                // offset is usually 1 but if the number of validators==number of attributes then the offset
0487:                // is 0
0488:                // because the first column is the FID column which doesn't have a listener.
0489:                int offset = 1;
0490:
0491:                ICellEditorListener[] listener = null;
0492:                if (adaptable.getAdapter(ICellEditorListener[].class) != null) {
0493:                    listener = (ICellEditorListener[]) adaptable
0494:                            .getAdapter(ICellEditorListener[].class);
0495:                    int attributeCount = features.getSchema()
0496:                            .getAttributeCount();
0497:                    if (listener.length < attributeCount) {
0498:                        UiPlugin
0499:                                .log(
0500:                                        "not enough cell editors for feature type so not used", new Exception()); //$NON-NLS-1$
0501:                        return;
0502:                    } else if (listener.length == attributeCount + 1) {
0503:                        offset = 0;
0504:                    }
0505:                }
0506:
0507:                for (int i = 0; i < editors.length - offset; i++) {
0508:                    final CellEditor editor = editors[i + offset];
0509:                    if (editor == null)
0510:                        continue;
0511:                    if (listener != null && listener[i] != null)
0512:                        editor.addListener(listener[i]);
0513:                    editor.addListener(new DisplayErrorCellListener(editor));
0514:                }
0515:            }
0516:
0517:            private void setCellValidators(IAdaptable adaptable) {
0518:                CellEditor[] editors = tableViewer.getCellEditors();
0519:                FeatureType schema = features.getSchema();
0520:                // offset is usually 1 but if the number of validators==number of attributes then the offset
0521:                // is 0
0522:                // because the first column is the FID column which doesn't have a listener.
0523:                int offset = 1;
0524:
0525:                ICellEditorValidator[] validators = null;
0526:                if (adaptable.getAdapter(ICellEditorValidator[].class) != null) {
0527:                    validators = (ICellEditorValidator[]) adaptable
0528:                            .getAdapter(ICellEditorValidator[].class);
0529:                    int attributeCount = features.getSchema()
0530:                            .getAttributeCount();
0531:                    if (validators.length < attributeCount) {
0532:                        UiPlugin
0533:                                .log(
0534:                                        "not enough cell editors for feature type so not used", new Exception()); //$NON-NLS-1$
0535:                        validators = null;
0536:                    } else if (validators.length == attributeCount) {
0537:                        offset = 0;
0538:                    }
0539:                }
0540:
0541:                for (int i = 0; i < editors.length - offset; i++) {
0542:                    CellEditor editor = editors[i + offset];
0543:                    if (editor == null)
0544:                        continue;
0545:                    if (validators != null && validators[i] != null)
0546:                        editor.setValidator(validators[i]);
0547:                    else
0548:                        editor.setValidator(new AttributeValidator(schema
0549:                                .getAttributeType(i), schema));
0550:                }
0551:            }
0552:
0553:            @SuppressWarnings("unchecked")
0554:            private void createCellEditors() {
0555:                FeatureType schema = features.getSchema();
0556:                org.eclipse.jface.viewers.CellEditor[] editors = new org.eclipse.jface.viewers.CellEditor[schema
0557:                        .getAttributeCount() + 1];
0558:
0559:                for (int i = 0; i < schema.getAttributeCount(); i++) {
0560:                    AttributeType aType = schema.getAttributeType(i);
0561:                    Class<? extends Object> concreteType = aType.getType();
0562:                    Composite control = (Composite) tableViewer.getControl();
0563:                    if (concreteType.isAssignableFrom(String.class)) {
0564:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0565:                                control, String.class);
0566:                        editors[i + 1] = textCellEditor;
0567:                    } else if (concreteType.isAssignableFrom(Integer.class)) {
0568:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0569:                                control, Integer.class);
0570:                        editors[i + 1] = textCellEditor;
0571:                    } else if (concreteType.isAssignableFrom(Double.class)) {
0572:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0573:                                control, Double.class);
0574:                        editors[i + 1] = textCellEditor;
0575:                    } else if (concreteType.isAssignableFrom(Float.class)) {
0576:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0577:                                control, Float.class);
0578:                        editors[i + 1] = textCellEditor;
0579:
0580:                    } else if (concreteType.isAssignableFrom(Boolean.class)) {
0581:                        BooleanCellEditor textCellEditor = new BooleanCellEditor(
0582:                                control);
0583:                        editors[i + 1] = textCellEditor;
0584:
0585:                    } else if (concreteType.isAssignableFrom(Character.class)) {
0586:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0587:                                control, Character.class);
0588:                        editors[i + 1] = textCellEditor;
0589:
0590:                    }
0591:                    // else if( concreteType.isAssignableFrom(Date.class)){
0592:                    // WarningCellEditor textCellEditor = new WarningCellEditor(control, "The Date type does
0593:                    // not yet have a editor, please make a bug report for this Attribute Type");
0594:                    // editors[i+1]=textCellEditor;
0595:                    //                
0596:                    // }
0597:                    else if (concreteType.isAssignableFrom(Byte.class)) {
0598:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0599:                                control, Byte.class);
0600:                        editors[i + 1] = textCellEditor;
0601:
0602:                    } else if (concreteType.isAssignableFrom(Short.class)) {
0603:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0604:                                control, Short.class);
0605:                        editors[i + 1] = textCellEditor;
0606:
0607:                    } else if (concreteType.isAssignableFrom(Long.class)) {
0608:                        BasicTypeCellEditor textCellEditor = new BasicTypeCellEditor(
0609:                                control, Long.class);
0610:                        editors[i + 1] = textCellEditor;
0611:
0612:                    } else {
0613:                        WarningCellEditor textCellEditor = new WarningCellEditor(
0614:                                control,
0615:                                Messages.FeatureTableControl_noEditor1
0616:                                        + concreteType.getSimpleName()
0617:                                        + Messages.FeatureTableControl_noEditor2);
0618:                        editors[i + 1] = textCellEditor;
0619:                    }
0620:                }
0621:                tableViewer.setCellEditors(editors);
0622:            }
0623:
0624:            private void createAttributeColumns(final Table table,
0625:                    TableViewer viewer, TableLayout layout) {
0626:
0627:                if (features == null) {
0628:                    TableColumn column = new TableColumn(table, SWT.CENTER
0629:                            | SWT.BORDER);
0630:                    column.setText(Messages.FeatureTableControl_1);
0631:                    layout.addColumnData(new ColumnWeightData(1));
0632:                } else {
0633:
0634:                    FeatureType schema = features.getSchema();
0635:
0636:                    TableColumn column = new TableColumn(table, SWT.CENTER
0637:                            | SWT.BORDER);
0638:                    column.setText("FID"); //$NON-NLS-1$
0639:                    layout.addColumnData(new ColumnWeightData(1, 150, true));
0640:                    column.setMoveable(true);
0641:
0642:                    column.addListener(SWT.Selection,
0643:                            new AttributeColumnSortListener(this ,
0644:                                    FEATURE_ID_COLUMN_PROPERTY));
0645:
0646:                    for (int i = 0; i < schema.getAttributeCount(); i++) {
0647:                        AttributeType aType = schema.getAttributeType(i);
0648:                        column = new TableColumn(table, SWT.CENTER | SWT.BORDER);
0649:                        if (Geometry.class.isAssignableFrom(aType.getType())) { // was aType.isGeometry()
0650:                            // jg: wot is this maddness? jd: paul said so
0651:                            column.setText("GEOMETRY"); //$NON-NLS-1$
0652:                        } else
0653:                            column.setText(aType.getName());
0654:
0655:                        layout
0656:                                .addColumnData(new ColumnWeightData(1, 100,
0657:                                        true));
0658:                        column.setMoveable(true);
0659:
0660:                        column.addListener(SWT.Selection,
0661:                                new AttributeColumnSortListener(this , aType
0662:                                        .getName()));
0663:                    }
0664:
0665:                }
0666:            }
0667:
0668:            /**
0669:             * Does nothing.
0670:             * 
0671:             * @see org.eclipse.ui.IWorkbenchPart#setFocus()
0672:             */
0673:            public void setFocus() {
0674:                // do nothing.
0675:            }
0676:
0677:            /**
0678:             * Contents of the current page of features
0679:             * 
0680:             * @return
0681:             */
0682:            public FeatureCollection getFeatures() {
0683:                return features;
0684:            }
0685:
0686:            /** Set up for a single page of content */
0687:            public void setFeatures(FeatureCollection features) {
0688:                checkWidget();
0689:                if (this .features != null && this .features == features)
0690:                    return;
0691:
0692:                this .features = features;
0693:
0694:                createTableViewer(book);
0695:            }
0696:
0697:            private void checkWidget() {
0698:                if (Display.getCurrent() == null)
0699:                    SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
0700:            }
0701:
0702:            /**
0703:             * Don't display nothing :-)
0704:             */
0705:            public void clear() {
0706:                features = null;
0707:                selectionProvider.getSelectionFids().clear();
0708:                update();
0709:            }
0710:
0711:            /**
0712:             * Displays a message.  If text == null or "" then the message is hidden and tableViewer is shown again.
0713:             *
0714:             * @param text message to display
0715:             * @param background color of the background of the text widget.  If null the default color is used
0716:             * @param foreground color of the foreground of the text widget.  If null the default color is used
0717:             */
0718:            public void message(String text, Color background, Color foreground) {
0719:                checkWidget();
0720:                Color background2 = background;
0721:                Color foreground2 = foreground;
0722:                if (background2 == null) {
0723:                    background2 = messageBackground;
0724:                }
0725:                if (foreground2 == null) {
0726:                    foreground2 = messageForeground;
0727:                }
0728:                message.setBackground(background2);
0729:                message.setForeground(foreground2);
0730:                if (text == null || text.trim().length() == 0) {
0731:                    message.setText(""); //$NON-NLS-1$
0732:                    if (tableViewer != null) {
0733:                        book.showPage(tableViewer.getControl());
0734:                        UiPlugin
0735:                                .trace(
0736:                                        Trace.FEATURE_TABLE,
0737:                                        getClass(),
0738:                                        "message(String,Color,Color): showing table View", SHOW_PATH ? new Exception() : null); //$NON-NLS-1$
0739:                    }
0740:                } else {
0741:                    message.setText(text);
0742:                    book.showPage(message);
0743:                    UiPlugin
0744:                            .trace(
0745:                                    Trace.FEATURE_TABLE,
0746:                                    getClass(),
0747:                                    "message(String,Color,Color): showing message", SHOW_PATH ? new Exception() : null); //$NON-NLS-1$
0748:                }
0749:            }
0750:
0751:            /**
0752:             * Displays a message.  If text == null or "" then the message is hidden and tableViewer is shown again.
0753:             *
0754:             * @param text message to display
0755:             */
0756:            public void message(String text) {
0757:                message(text, null, null);
0758:            }
0759:
0760:            /**
0761:             * Returns a selection with a single FidFilter indicating the features selected
0762:             */
0763:            public ISelection getSelection() {
0764:                checkWidget();
0765:                return selectionProvider.getSelection();
0766:            }
0767:
0768:            public void addSelectionChangedListener(
0769:                    ISelectionChangedListener listener) {
0770:                selectionProvider.addSelectionChangedListener(listener);
0771:            }
0772:
0773:            public void removeSelectionChangedListener(
0774:                    ISelectionChangedListener listener) {
0775:                selectionProvider.removeSelectionChangedListener(listener);
0776:            }
0777:
0778:            /**
0779:             * Useable selections are:
0780:             * selection of features, FIDS and Filters/Queries that adapt to a FeatureSource
0781:             */
0782:            public void setSelection(final ISelection newSelection) {
0783:                checkWidget();
0784:                selectionProvider.setSelection(newSelection);
0785:            }
0786:
0787:            /**
0788:             * Sorts the table so that the selection is at the top of the table.
0789:             * 
0790:             * It does not last.  The next selection will not be at the top.
0791:             */
0792:            public void promoteSelection() {
0793:                checkWidget();
0794:                tableViewer.cancelEditing();
0795:
0796:                Table table = tableViewer.getTable();
0797:                table.setSortColumn(null);
0798:
0799:                FidFilter filter = selectionProvider.getFidFilter();
0800:
0801:                sort(new SelectionComparator(filter, SWT.UP, new FIDComparator(
0802:                        SWT.DOWN)), SWT.UP, null);
0803:                table.setTopIndex(0);
0804:            }
0805:
0806:            /**
0807:             * Sorts the features in the tableView.
0808:             *
0809:             * @param comparator comparator to use for the sorting.
0810:             * @param dir the direction to set the column SWT.UP or SWT.DOWN.  
0811:             * If SWT.UP then the table item with index 0 is at the top of the table otherwise 
0812:             * it is at the bottom of the table.
0813:             * @param sortColumn the column that is being sorted
0814:             */
0815:            public void sort(Comparator<Feature> comparator, int dir,
0816:                    TableColumn sortColumn) {
0817:                checkWidget();
0818:
0819:                FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
0820:                        .getContentProvider();
0821:
0822:                boolean sorted = false;
0823:                if (!comparator.equals(currentComparator)) {
0824:                    sorted = true;
0825:                    currentComparator = comparator;
0826:                    Collections.sort(provider.features, currentComparator);
0827:                }
0828:                Table table = tableViewer.getTable();
0829:                if (table.getSortColumn() != sortColumn) {
0830:                    sorted = true;
0831:                    table.setSortColumn(sortColumn);
0832:                    while (Display.getCurrent().readAndDispatch())
0833:                        ;
0834:                }
0835:                if (table.getSortColumn() != null
0836:                        && dir != table.getSortDirection()) {
0837:                    sorted = true;
0838:                    table.setSortDirection(dir);
0839:                    while (Display.getCurrent().readAndDispatch())
0840:                        ;
0841:                }
0842:                if (sorted) {
0843:                    table.deselectAll();
0844:                    table.clearAll();
0845:                }
0846:
0847:            }
0848:
0849:            /**
0850:             * Resorts the table using the last comparator.  This is useful for cases where features have been added to the table
0851:             * @param refreshTable 
0852:             */
0853:            void sort(boolean refreshTable) {
0854:                if (currentComparator == null)
0855:                    return;
0856:
0857:                FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
0858:                        .getContentProvider();
0859:
0860:                Collections.sort(provider.features, currentComparator);
0861:
0862:                tableViewer.getTable().deselectAll();
0863:                if (refreshTable)
0864:                    tableViewer.getTable().clearAll();
0865:            }
0866:
0867:            public TableViewer getViewer() {
0868:                return tableViewer;
0869:            }
0870:
0871:            FeatureTableSelectionProvider getSelectionProvider() {
0872:                return selectionProvider;
0873:            }
0874:
0875:            public void setSelection(StructuredSelection selection,
0876:                    boolean reveal) {
0877:                selectionProvider.setSelection(selection, reveal);
0878:            }
0879:
0880:            public int getSelectionCount() {
0881:                return selectionProvider.getSelectionFids().size();
0882:            }
0883:
0884:            /**
0885:             * select the features found that has the text.  Only the attributes indicated are searched.  
0886:             * If {@link #ALL} is selected then all attributes will be searched
0887:             *
0888:             * @param text text to search for it will first be assumed that it is a reg ex expression
0889:             * @param attributes the attributes to search.  See {@link #ALL}
0890:             * @param selectAll if true all matched features will be selected otherwise just the first feature
0891:             */
0892:            public void select(String text, String[] attributes,
0893:                    boolean selectAll) throws PatternSyntaxException {
0894:
0895:                Pattern pattern;
0896:                try {
0897:                    String pre = text.startsWith("^") ? "" : ".*"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
0898:                    String post = text.startsWith("$") ? "" : ".*"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
0899:                    pattern = Pattern.compile(pre + text + post,
0900:                            Pattern.CASE_INSENSITIVE);
0901:                } catch (IllegalArgumentException e) {
0902:                    try {
0903:                        pattern = Pattern
0904:                                .compile(".*" + convertToLiteral(text) + ".*"); //$NON-NLS-1$//$NON-NLS-2$
0905:                    } catch (IllegalArgumentException e2) {
0906:                        return;
0907:                    }
0908:                }
0909:
0910:                FeatureTableContentProvider provider = (FeatureTableContentProvider) this .tableViewer
0911:                        .getContentProvider();
0912:                List<Feature> toSearch = provider.features;
0913:
0914:                IProgressMonitor progressMonitor = getSelectionProvider().progressMonitor;
0915:                if (progressMonitor != null) {
0916:                    progressMonitor.setCanceled(true);
0917:                }
0918:                getSelectionProvider().getSelectionFids().clear();
0919:                int j = 0;
0920:                int firstMatch = -1;
0921:                OUTER: for (Feature feature : toSearch) {
0922:                    if (searchFeature(feature, pattern, attributes)) {
0923:                        if (firstMatch == -1)
0924:                            firstMatch = j;
0925:                        if (!selectAll)
0926:                            break OUTER;
0927:                    }
0928:                    j++;
0929:                }
0930:
0931:                Table table = tableViewer.getTable();
0932:                if (firstMatch != -1) {
0933:                    // display the selected item
0934:                    table.setTopIndex(firstMatch);
0935:                }
0936:                // trigger a refresh of table
0937:                table.clearAll();
0938:                // tell the world..
0939:                selectionProvider.notifyListeners();
0940:            }
0941:
0942:            private boolean searchFeature(Feature feature, Pattern pattern,
0943:                    String[] attributes) {
0944:                FeatureType featureType = feature.getFeatureType();
0945:                if (attributes == ALL) {
0946:                    for (int i = 0; i < featureType.getAttributeCount(); i++) {
0947:                        if (matches(pattern, feature.getAttribute(i))) {
0948:                            selectionProvider.getSelectionFids().add(
0949:                                    feature.getID());
0950:                            return true;
0951:                        }
0952:                    }
0953:                }
0954:                for (int i = 0; i < attributes.length; i++) {
0955:                    if (matches(pattern, feature.getAttribute(attributes[i]))) {
0956:                        getSelectionProvider().getSelectionFids().add(
0957:                                feature.getID());
0958:                        return true;
0959:
0960:                    }
0961:                }
0962:                return false;
0963:            }
0964:
0965:            private String convertToLiteral(String text) {
0966:                String text2 = text.replace("\\", "\\\\"); //$NON-NLS-1$ //$NON-NLS-2$
0967:                text2 = text2.replace("*", "\\*"); //$NON-NLS-1$ //$NON-NLS-2$
0968:                text2 = text2.replace("+", "\\+"); //$NON-NLS-1$ //$NON-NLS-2$
0969:                text2 = text2.replace(".", "\\."); //$NON-NLS-1$ //$NON-NLS-2$
0970:                text2 = text2.replace("?", "\\?"); //$NON-NLS-1$ //$NON-NLS-2$
0971:                text2 = text2.replace("[", "\\["); //$NON-NLS-1$ //$NON-NLS-2$
0972:                text2 = text2.replace("]", "\\]"); //$NON-NLS-1$ //$NON-NLS-2$
0973:                text2 = text2.replace("^", "\\^"); //$NON-NLS-1$ //$NON-NLS-2$
0974:                text2 = text2.replace("-", "\\-"); //$NON-NLS-1$ //$NON-NLS-2$
0975:                text2 = text2.replace("&", "\\&"); //$NON-NLS-1$ //$NON-NLS-2$
0976:                text2 = text2.replace("(", "\\("); //$NON-NLS-1$ //$NON-NLS-2$
0977:                text2 = text2.replace(")", "\\)"); //$NON-NLS-1$ //$NON-NLS-2$
0978:                text2 = text2.replace("|", "\\|"); //$NON-NLS-1$ //$NON-NLS-2$
0979:                return text2;
0980:            }
0981:
0982:            private boolean matches(Pattern pattern, Object attribute) {
0983:                String stringValue = attribute.toString();
0984:                return pattern.matcher(stringValue).matches();
0985:            }
0986:
0987:            public void addLoadingListener(IFeatureTableLoadingListener listener) {
0988:                loadingListeners.add(listener);
0989:            }
0990:
0991:            public void remove(IFeatureTableLoadingListener listener) {
0992:                loadingListeners.remove(listener);
0993:            }
0994:
0995:            protected void notifyLoadingListeners(LoadingEvent event) {
0996:                this .checkWidget();
0997:                if (event.loading) {
0998:                    if (event.monitor == null)
0999:                        throw new NullPointerException();
1000:                    for (IFeatureTableLoadingListener listener : loadingListeners) {
1001:                        try {
1002:                            listener.loadingStarted(event.monitor);
1003:                        } catch (Throwable e) {
1004:                            UiPlugin.log(listener + " threw an exception", e); //$NON-NLS-1$
1005:                        }
1006:                    }
1007:                } else {
1008:                    for (IFeatureTableLoadingListener listener : loadingListeners) {
1009:                        try {
1010:                            listener.loadingStopped(event.canceled);
1011:                        } catch (Throwable e) {
1012:                            UiPlugin.log(listener + " threw an exception", e); //$NON-NLS-1$
1013:                        }
1014:                    }
1015:                }
1016:            }
1017:
1018:            /**
1019:             * Updates the features that have the same feature ID to match the new feature or adds the features if they are not part of the
1020:             * current collection.  
1021:             *
1022:             * @param features2 the feature collection that contains the modified or new features.  
1023:             */
1024:            public void update(FeatureCollection features2) {
1025:                if (features == null)
1026:                    return; // nothing to update since the table is not in use... Should this be an exception?
1027:                FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
1028:                        .getContentProvider();
1029:                provider.update(features2);
1030:            }
1031:
1032:            /**
1033:             * Checks all the lists, caches, content providers, etc... are consistent with each other. 
1034:             * This is an expensive method so should be called with care.  A test is a good example.
1035:             */
1036:            public void assertInternallyConsistent() {
1037:                if (tableViewer.getContentProvider() != null) {
1038:                    FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
1039:                            .getContentProvider();
1040:                    provider.assertInternallyConsistent();
1041:                }
1042:            }
1043:
1044:            /**
1045:             * Removes the selected features (the features selected by the owning {@link FeatureTableControl}).
1046:             * @return returns a collection of the deleted features
1047:             * 
1048:             * @see #setSelection(ISelection)
1049:             * @see #setSelection(StructuredSelection, boolean)
1050:             */
1051:            public FeatureCollection deleteSelection() {
1052:                FeatureTableContentProvider provider = (FeatureTableContentProvider) tableViewer
1053:                        .getContentProvider();
1054:                return provider.deleteSelection();
1055:            }
1056:
1057:            /**
1058:             * Sets the context Menu used by the table view.  Not menu is used for the message box.
1059:             *
1060:             * @param contextMenu menu manager used for creating the menu.
1061:             */
1062:            public void setMenuManager(MenuManager contextMenu) {
1063:                checkWidget();
1064:                this .contextMenu = contextMenu;
1065:                if (tableViewer != null && tableViewer.getControl() != null) {
1066:                    Menu oldMenu = tableViewer.getControl().getMenu();
1067:                    if (oldMenu != null)
1068:                        oldMenu.dispose();
1069:                    Menu menu = contextMenu.createContextMenu(tableViewer
1070:                            .getControl());
1071:                    tableViewer.getControl().setMenu(menu);
1072:                }
1073:            }
1074:
1075:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.