001: package net.refractions.udig.catalog.internal.ui;
002:
003: import java.io.IOException;
004: import java.util.Iterator;
005:
006: import net.refractions.udig.catalog.CatalogPlugin;
007: import net.refractions.udig.catalog.IGeoResource;
008: import net.refractions.udig.catalog.IService;
009: import net.refractions.udig.catalog.ui.CatalogTreeViewer;
010: import net.refractions.udig.catalog.ui.CatalogUIPlugin;
011: import net.refractions.udig.catalog.ui.StatusLineMessageBoardAdapter;
012: import net.refractions.udig.catalog.ui.internal.Messages;
013: import net.refractions.udig.internal.ui.IDropTargetProvider;
014: import net.refractions.udig.internal.ui.UiPlugin;
015: import net.refractions.udig.ui.ProgressManager;
016: import net.refractions.udig.ui.UDIGDragDropUtilities;
017:
018: import org.eclipse.jface.action.Action;
019: import org.eclipse.jface.action.GroupMarker;
020: import org.eclipse.jface.action.IAction;
021: import org.eclipse.jface.action.IMenuListener;
022: import org.eclipse.jface.action.IMenuManager;
023: import org.eclipse.jface.action.IToolBarManager;
024: import org.eclipse.jface.action.MenuManager;
025: import org.eclipse.jface.action.Separator;
026: import org.eclipse.jface.viewers.ISelection;
027: import org.eclipse.jface.viewers.ISelectionChangedListener;
028: import org.eclipse.jface.viewers.IStructuredSelection;
029: import org.eclipse.jface.viewers.SelectionChangedEvent;
030: import org.eclipse.swt.dnd.DropTargetEvent;
031: import org.eclipse.swt.widgets.Composite;
032: import org.eclipse.swt.widgets.Menu;
033: import org.eclipse.ui.IWorkbenchActionConstants;
034: import org.eclipse.ui.IWorkbenchWindow;
035: import org.eclipse.ui.PlatformUI;
036: import org.eclipse.ui.actions.ActionFactory;
037: import org.eclipse.ui.part.ISetSelectionTarget;
038: import org.eclipse.ui.part.ViewPart;
039: import org.osgi.service.prefs.BackingStoreException;
040:
041: /**
042: * Catalog view for visualization and management if resources.
043: * <p>
044: * This class will be rather heavy on documentation, because it central (literally) to the uDig
045: * applicaiton, and because it is one of the first views we are creating.
046: * </p>
047: * <p>
048: * Of Note:
049: * <ul>
050: * <li>The catalog is strange in that there is only *one*, represent a global registry of all the
051: * data sources in use by any uDig plugins.
052: * <li>
053: * </ul>
054: * </p>
055: * From the requirements document (where CatalogView is known as LocalCatalog): <i>The Local Catalog
056: * serves as a central repository of data and server information.
057: * <p>
058: * Non-Functional Requirements:
059: * <ul>
060: * <li><b>Ease of Data Location </b>, intent is for the user to be separated from the data source;
061: * so they need as little technical knowledge as possible.
062: * <li><b>Security </b>, name/password should be left out of the export/share.
063: * </ul>
064: * </p>
065: * <p>
066: * Functional Requirements:
067: * <ul>
068: * <li><b>Servers </b>, store server connection information for sharing between projects.
069: * <li><b>Data Directories </b>, store data directories for sharing between projects.
070: * <li><b>Metadata </b>, provide access to metadata on Servers/Data Directories.
071: * <li><b>Data Discovery </b>, provide enough information for a user to define a new layer in their
072: * context.
073: * <li><b>Persist Settings </b>, permit exporting and sharing DataStore connection information.
074: * <li><b>DataStores Management </b>, lookup actualized DataStores that are in use.
075: * <li><b>Missing Data </b>, entries referred to by imported projects should be maintained,
076: * allowing the user one location to correct data connection information.
077: * </ul>
078: * </p>
079: * <p>
080: * Catalog View has a strong interaction with the preferences maintained by the local installation
081: * of uDig for the current user.
082: * </p>
083: */
084: public class CatalogView extends ViewPart implements
085: ISetSelectionTarget, IDropTargetProvider {
086:
087: /** <code>VIEW_ID</code> field */
088: public static final String VIEW_ID = "net.refractions.udig.catalog.ui.CatalogView"; //$NON-NLS-1$
089:
090: CatalogTreeViewer treeviewer;
091:
092: Action removeAction; // addAction
093:
094: private Action saveAction;
095: private Action loadAction;
096:
097: /**
098: * Creates the SWT controls for this workbench part.
099: * <p>
100: * The details (from IWorkbenchPart.createPartControl( Composite ))
101: * </p>
102: * <p>
103: * Multi-step process:
104: * <ol>
105: * <li>Create one or more controls within the parent.</li>
106: * <li>Set the parent layout as needed.</li>
107: * <li>Register any global actions with the <code>IActionService</code>. </li>
108: * <li>Register any popup menus with the <code>IActionService</code>. </li>
109: * <li>Register a selection provider with the <code>ISelectionService</code> (optional).</li>
110: * </ol>
111: * </p>
112: *
113: * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
114: * @param parent
115: */
116: public void createPartControl(Composite parent) {
117: // create viewer
118: // treeviewer = new CatalogTreeViewer(parent, false);
119: treeviewer = new CatalogTreeViewer(parent, true);
120: treeviewer.setMessageBoard(new StatusLineMessageBoardAdapter(
121: getViewSite().getActionBars().getStatusLineManager()));
122:
123: UDIGDragDropUtilities.addDragDropSupport(treeviewer, this );
124:
125: getSite().setSelectionProvider(treeviewer);
126: // Create menu and toolbars
127: createActions();
128: createMenu();
129: createToolbar();
130: createContextMenu();
131: // hookGlobalActions();
132:
133: // restore state (from previous session)
134:
135: }
136:
137: private void createContextMenu() {
138: final MenuManager contextMenu = new MenuManager();
139:
140: contextMenu.setRemoveAllWhenShown(true);
141: contextMenu.addMenuListener(new IMenuListener() {
142:
143: public void menuAboutToShow(IMenuManager mgr) {
144: contextMenu.add(new GroupMarker(
145: IWorkbenchActionConstants.MB_ADDITIONS));
146: contextMenu.add(new Separator());
147: contextMenu.add(removeAction);
148: IWorkbenchWindow window = getSite()
149: .getWorkbenchWindow();
150: IAction action = ActionFactory.IMPORT.create(window);
151: contextMenu.add(action);
152: contextMenu.add(new Separator());
153: contextMenu.add(UiPlugin.getDefault()
154: .getOperationMenuFactory().getContextMenu(
155: treeviewer.getSelection()));
156: contextMenu.add(new Separator());
157: contextMenu.add(ActionFactory.EXPORT.create(getSite()
158: .getWorkbenchWindow()));
159: }
160:
161: });
162:
163: // Create menu.
164: Menu menu = contextMenu.createContextMenu(treeviewer
165: .getControl());
166: treeviewer.getControl().setMenu(menu);
167:
168: // Register menu for extension.
169: getSite().registerContextMenu(contextMenu, treeviewer);
170:
171: }
172:
173: private void createActions() {
174: removeAction = new Action() {
175: public void run() {
176: freeDatasource();
177: }
178: };
179:
180: Messages.initAction(removeAction, "action_remove"); //$NON-NLS-1$
181: removeAction.setEnabled(false);
182: removeAction.setImageDescriptor(Images
183: .getDescriptor(ImageConstants.REMOVE_CO));
184: removeAction
185: .setActionDefinitionId("org.eclipse.ui.edit.delete"); //$NON-NLS-1$
186: getViewSite().getActionBars().setGlobalActionHandler(
187: ActionFactory.DELETE.getId(), removeAction);
188: getSite().getKeyBindingService().registerAction(removeAction);
189:
190: PlatformUI.getWorkbench().getHelpSystem().setHelp(removeAction,
191: IHelpContextIds.REMOVE_SERVICE_ACTION);
192:
193: saveAction = new Action(Messages.CatalogView_save_label) {
194: public void run() {
195: try {
196: CatalogPlugin.getDefault().storeToPreferences(
197: ProgressManager.instance().get());
198: } catch (BackingStoreException e) {
199: CatalogPlugin.log(null, e);
200: } catch (IOException e) {
201: CatalogPlugin.log(null, e);
202: }
203: }
204: };
205:
206: loadAction = new Action(Messages.CatalogView_load_label) {
207: public void run() {
208: try {
209: CatalogPlugin.getDefault().restoreFromPreferences();
210: } catch (Exception e) {
211: e.printStackTrace();
212: }
213: }
214: };
215:
216: // Add selection listener.
217: treeviewer
218: .addSelectionChangedListener(new ISelectionChangedListener() {
219: public void selectionChanged(
220: SelectionChangedEvent event) {
221: updateActionEnablement();
222: }
223: });
224: }
225:
226: void registerDatasource() {
227: // Call to wizard here...
228: }
229:
230: void freeDatasource() {
231: // Free selected data source - but only if it is not
232: // in use...
233:
234: IStructuredSelection sel = (IStructuredSelection) treeviewer
235: .getSelection();
236: for (Iterator iter = sel.iterator(); iter.hasNext();) {
237: @SuppressWarnings("all")//$NON-NLS-1$
238: Object o = iter.next();
239: if (o instanceof IService)
240: remove((IService) o);
241: else if (o instanceof IGeoResource)
242: remove((IGeoResource) o);
243: }
244: }
245:
246: private void remove(IService service) {
247: CatalogPlugin.getDefault().getCatalogs()[0].remove(service);
248: }
249:
250: private void remove(IGeoResource service) {
251: try {
252: remove(service.service(null));
253: } catch (IOException e) {
254: CatalogUIPlugin.log(null, e);
255: }
256: }
257:
258: void updateActionEnablement() {
259: IStructuredSelection sel = (IStructuredSelection) treeviewer
260: .getSelection();
261: removeAction.setEnabled(sel.size() > 0);
262: }
263:
264: /**
265: * Create menu with refresh option.
266: */
267: private void createMenu() {
268: IMenuManager mgr = getViewSite().getActionBars()
269: .getMenuManager();
270: mgr.add(saveAction);
271: mgr.add(loadAction);
272: }
273:
274: /**
275: * Create toolbar with new and delete buttons.
276: */
277: private void createToolbar() {
278: IToolBarManager mgr = getViewSite().getActionBars()
279: .getToolBarManager();
280: // mgr.add(addAction);
281:
282: IWorkbenchWindow window = getSite().getWorkbenchWindow();
283: IAction action = ActionFactory.IMPORT.create(window);
284:
285: action.setImageDescriptor(Images
286: .getDescriptor(ImageConstants.PATH_ETOOL
287: + "import_wiz.gif")); //$NON-NLS-1$
288: mgr.add(action);
289:
290: mgr.add(removeAction);
291: }
292:
293: /**
294: * Asks this view take focus within the workbench.
295: * <p>
296: * From IWorkbenchPart: Clients should not call this method (the workbench calls this method at
297: * appropriate times). To have the workbench activate a part, use
298: * <code>IWorkbenchPage.activate(IWorkbenchPart) instead</code>.
299: * </p>
300: * <p>
301: * Used to set the focus to the appropriate control, for us that is the treeviewer. But if we
302: * were smart we could send the user off to a search field or something they actually need (like
303: * a broken datastore) based on context.
304: * </p>
305: */
306: public void setFocus() {
307: treeviewer.getControl().setFocus();
308: }
309:
310: /**
311: * @return Returns the treeviewer.
312: */
313: public CatalogTreeViewer getTreeviewer() {
314: return treeviewer;
315: }
316:
317: /*
318: * (non-Javadoc)
319: *
320: * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
321: */
322: public void selectReveal(ISelection selection) {
323: treeviewer.setSelection(selection);
324: }
325:
326: public Object getTarget(DropTargetEvent event) {
327: return this;
328: }
329: }
|