4173b9241acc4ded0a58f0f0b6b94e60aab14ecf
[public/netxms.git] / src / java / netxms-eclipse / NetworkMaps / src / org / netxms / ui / eclipse / networkmaps / views / AbstractNetworkMapView.java
1 /**
2 * NetXMS - open source network management system
3 * Copyright (C) 2003-2015 Victor Kirhenshtein
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 package org.netxms.ui.eclipse.networkmaps.views;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Set;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.IConfigurationElement;
31 import org.eclipse.core.runtime.IExtensionRegistry;
32 import org.eclipse.core.runtime.Platform;
33 import org.eclipse.draw2d.ManhattanConnectionRouter;
34 import org.eclipse.draw2d.geometry.Dimension;
35 import org.eclipse.draw2d.geometry.Point;
36 import org.eclipse.gef4.zest.core.viewers.AbstractZoomableViewer;
37 import org.eclipse.gef4.zest.core.viewers.IZoomableWorkbenchPart;
38 import org.eclipse.gef4.zest.core.widgets.Graph;
39 import org.eclipse.gef4.zest.core.widgets.GraphConnection;
40 import org.eclipse.gef4.zest.core.widgets.GraphNode;
41 import org.eclipse.gef4.zest.layouts.LayoutAlgorithm;
42 import org.eclipse.gef4.zest.layouts.algorithms.CompositeLayoutAlgorithm;
43 import org.eclipse.gef4.zest.layouts.algorithms.GridLayoutAlgorithm;
44 import org.eclipse.gef4.zest.layouts.algorithms.RadialLayoutAlgorithm;
45 import org.eclipse.gef4.zest.layouts.algorithms.SpringLayoutAlgorithm;
46 import org.eclipse.gef4.zest.layouts.algorithms.TreeLayoutAlgorithm;
47 import org.eclipse.jface.action.Action;
48 import org.eclipse.jface.action.GroupMarker;
49 import org.eclipse.jface.action.IContributionItem;
50 import org.eclipse.jface.action.IMenuListener;
51 import org.eclipse.jface.action.IMenuManager;
52 import org.eclipse.jface.action.IToolBarManager;
53 import org.eclipse.jface.action.MenuManager;
54 import org.eclipse.jface.action.Separator;
55 import org.eclipse.jface.commands.ActionHandler;
56 import org.eclipse.jface.dialogs.IDialogSettings;
57 import org.eclipse.jface.preference.IPreferenceStore;
58 import org.eclipse.jface.viewers.DoubleClickEvent;
59 import org.eclipse.jface.viewers.IDoubleClickListener;
60 import org.eclipse.jface.viewers.ISelection;
61 import org.eclipse.jface.viewers.ISelectionChangedListener;
62 import org.eclipse.jface.viewers.ISelectionProvider;
63 import org.eclipse.jface.viewers.IStructuredSelection;
64 import org.eclipse.jface.viewers.SelectionChangedEvent;
65 import org.eclipse.jface.viewers.StructuredSelection;
66 import org.eclipse.swt.SWT;
67 import org.eclipse.swt.dnd.Clipboard;
68 import org.eclipse.swt.dnd.ImageTransfer;
69 import org.eclipse.swt.dnd.Transfer;
70 import org.eclipse.swt.events.DisposeEvent;
71 import org.eclipse.swt.events.DisposeListener;
72 import org.eclipse.swt.graphics.Image;
73 import org.eclipse.swt.layout.FillLayout;
74 import org.eclipse.swt.widgets.Composite;
75 import org.eclipse.swt.widgets.Display;
76 import org.eclipse.swt.widgets.Menu;
77 import org.eclipse.ui.IActionBars;
78 import org.eclipse.ui.IViewSite;
79 import org.eclipse.ui.IWorkbenchActionConstants;
80 import org.eclipse.ui.IWorkbenchPage;
81 import org.eclipse.ui.PartInitException;
82 import org.eclipse.ui.PlatformUI;
83 import org.eclipse.ui.contexts.IContextService;
84 import org.eclipse.ui.handlers.IHandlerService;
85 import org.eclipse.ui.part.ViewPart;
86 import org.netxms.client.NXCSession;
87 import org.netxms.client.SessionListener;
88 import org.netxms.client.SessionNotification;
89 import org.netxms.client.maps.MapLayoutAlgorithm;
90 import org.netxms.client.maps.MapObjectDisplayMode;
91 import org.netxms.client.maps.NetworkMapLink;
92 import org.netxms.client.maps.NetworkMapPage;
93 import org.netxms.client.maps.configs.DCIImageConfiguration;
94 import org.netxms.client.maps.configs.SingleDciConfig;
95 import org.netxms.client.maps.elements.NetworkMapDCIContainer;
96 import org.netxms.client.maps.elements.NetworkMapDCIImage;
97 import org.netxms.client.maps.elements.NetworkMapElement;
98 import org.netxms.client.maps.elements.NetworkMapObject;
99 import org.netxms.client.objects.AbstractObject;
100 import org.netxms.client.objects.Dashboard;
101 import org.netxms.client.objects.NetworkMap;
102 import org.netxms.ui.eclipse.actions.RefreshAction;
103 import org.netxms.ui.eclipse.console.resources.GroupMarkers;
104 import org.netxms.ui.eclipse.console.resources.SharedIcons;
105 import org.netxms.ui.eclipse.networkmaps.Activator;
106 import org.netxms.ui.eclipse.networkmaps.Messages;
107 import org.netxms.ui.eclipse.networkmaps.algorithms.ExpansionAlgorithm;
108 import org.netxms.ui.eclipse.networkmaps.algorithms.ManualLayout;
109 import org.netxms.ui.eclipse.networkmaps.api.ObjectDoubleClickHandler;
110 import org.netxms.ui.eclipse.networkmaps.views.helpers.BendpointEditor;
111 import org.netxms.ui.eclipse.networkmaps.views.helpers.ExtendedGraphViewer;
112 import org.netxms.ui.eclipse.networkmaps.views.helpers.LinkDciValueProvider;
113 import org.netxms.ui.eclipse.networkmaps.views.helpers.MapContentProvider;
114 import org.netxms.ui.eclipse.networkmaps.views.helpers.MapLabelProvider;
115 import org.netxms.ui.eclipse.objectbrowser.api.ObjectContextMenu;
116 import org.netxms.ui.eclipse.shared.ConsoleSharedData;
117 import org.netxms.ui.eclipse.tools.CommandBridge;
118 import org.netxms.ui.eclipse.tools.FilteringMenuManager;
119 import org.netxms.ui.eclipse.tools.MessageDialogHelper;
120
121 /**
122 * Base class for network map views
123 */
124 public abstract class AbstractNetworkMapView extends ViewPart implements ISelectionProvider, IZoomableWorkbenchPart
125 {
126 protected static final int LAYOUT_SPRING = 0;
127 protected static final int LAYOUT_RADIAL = 1;
128 protected static final int LAYOUT_HTREE = 2;
129 protected static final int LAYOUT_VTREE = 3;
130 protected static final int LAYOUT_SPARSE_VTREE = 4;
131
132 private static final String[] layoutAlgorithmNames = {
133 Messages.get().AbstractNetworkMapView_LayoutSpring,
134 Messages.get().AbstractNetworkMapView_LayoutRadial,
135 Messages.get().AbstractNetworkMapView_LayoutHorzTree,
136 Messages.get().AbstractNetworkMapView_LayoutVertTree,
137 Messages.get().AbstractNetworkMapView_LayoutSparseVertTree
138 };
139 private static final String[] connectionRouterNames = { Messages.get().AbstractNetworkMapView_RouterDirect, Messages.get().AbstractNetworkMapView_RouterManhattan };
140
141 private static final int SELECTION_EMPTY = 0;
142 private static final int SELECTION_MIXED = 1;
143 private static final int SELECTION_OBJECTS = 2;
144 private static final int SELECTION_ELEMENTS = 3;
145 private static final int SELECTION_LINKS = 4;
146
147 protected NXCSession session;
148 protected AbstractObject rootObject;
149 protected NetworkMapPage mapPage;
150 protected ExtendedGraphViewer viewer;
151 protected MapLabelProvider labelProvider;
152 protected MapLayoutAlgorithm layoutAlgorithm = MapLayoutAlgorithm.SPRING;
153 protected int routingAlgorithm = NetworkMapLink.ROUTING_DIRECT;
154 protected boolean allowManualLayout = false; // True if manual layout can be switched on
155 protected boolean automaticLayoutEnabled = true; // Current layout mode - automatic or manual
156 protected boolean alwaysFitLayout = false;
157 protected boolean disableGeolocationBackground = false;
158
159 protected Action actionRefresh;
160 protected Action actionShowStatusIcon;
161 protected Action actionShowStatusBackground;
162 protected Action actionShowStatusFrame;
163 protected Action actionZoomIn;
164 protected Action actionZoomOut;
165 protected Action actionZoomFit;
166 protected Action[] actionZoomTo;
167 protected Action[] actionSetAlgorithm;
168 protected Action[] actionSetRouter;
169 protected Action actionAlwaysFitLayout;
170 protected Action actionEnableAutomaticLayout;
171 protected Action actionSaveLayout;
172 protected Action actionOpenDrillDownObject;
173 protected Action actionFiguresIcons;
174 protected Action actionFiguresSmallLabels;
175 protected Action actionFiguresLargeLabels;
176 protected Action actionFiguresStatusIcons;
177 protected Action actionShowGrid;
178 protected Action actionAlignToGrid;
179 protected Action actionSnapToGrid;
180 protected Action actionShowObjectDetails;
181 protected Action actionCopyImage;
182 protected Action actionHideLinkLabels;
183 protected Action actionHideLinks;
184 protected Action actionSelectAllObjects;
185
186 private String viewId;
187 private IStructuredSelection currentSelection = new StructuredSelection(new Object[0]);
188 private Set<ISelectionChangedListener> selectionListeners = new HashSet<ISelectionChangedListener>();
189 private BendpointEditor bendpointEditor = null;
190 private SessionListener sessionListener;
191 private List<DoubleClickHandlerData> doubleClickHandlers = new ArrayList<DoubleClickHandlerData>(0);
192 private LinkDciValueProvider dciValueProvider;
193
194 /*
195 * (non-Javadoc)
196 *
197 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
198 */
199 @Override
200 public void init(IViewSite site) throws PartInitException
201 {
202 super.init(site);
203
204 dciValueProvider = LinkDciValueProvider.getInstance();
205
206 final IPreferenceStore ps = Activator.getDefault().getPreferenceStore();
207 disableGeolocationBackground = ps.getBoolean("DISABLE_GEOLOCATION_BACKGROUND"); //$NON-NLS-1$
208
209 session = (NXCSession)ConsoleSharedData.getSession();
210 String[] parts = site.getSecondaryId().split("&"); //$NON-NLS-1$
211 rootObject = session.findObjectById(Long.parseLong((parts.length > 0) ? parts[0] : site.getSecondaryId()));
212 if (rootObject == null)
213 throw new PartInitException(Messages.get().AbstractNetworkMapView_RootObjectNotFound);
214
215 viewId = site.getId() + "."; //$NON-NLS-1$
216 viewId += (parts.length > 0) ? parts[0] : site.getSecondaryId();
217
218 parseSecondaryId(parts);
219 }
220
221 /**
222 * Parse secondary ID (already splitted by & characters). Intended to be overrided in subclasses.
223 *
224 * @param parts secondary ID divided at & characters
225 * @throws PartInitException
226 */
227 protected void parseSecondaryId(String[] parts) throws PartInitException
228 {
229 }
230
231 /**
232 * Build map page containing data to display. Should be implemented in derived classes.
233 */
234 protected abstract void buildMapPage();
235
236 /*
237 * (non-Javadoc)
238 *
239 * @see org.eclipse.ui.part.ViewPart#createPartControl(org.eclipse.swt.widgets.Composite)
240 */
241 @Override
242 public final void createPartControl(Composite parent)
243 {
244 FillLayout layout = new FillLayout();
245 parent.setLayout(layout);
246
247 viewer = new ExtendedGraphViewer(parent, SWT.NONE);
248 viewer.setContentProvider(new MapContentProvider(viewer));
249 labelProvider = new MapLabelProvider(viewer);
250 viewer.setLabelProvider(labelProvider);
251 viewer.setBackgroundColor(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB());
252
253 IDialogSettings settings = Activator.getDefault().getDialogSettings();
254 try
255 {
256 alwaysFitLayout = settings.getBoolean(viewId + ".alwaysFitLayout"); //$NON-NLS-1$
257 }
258 catch(Exception e)
259 {
260 }
261
262 // Zoom level restore and save
263 try
264 {
265 viewer.zoomTo(settings.getDouble(viewId + ".zoom")); //$NON-NLS-1$
266 }
267 catch(NumberFormatException e)
268 {
269 }
270 viewer.getGraphControl().addDisposeListener(new DisposeListener() {
271 @Override
272 public void widgetDisposed(DisposeEvent e)
273 {
274 IDialogSettings settings = Activator.getDefault().getDialogSettings();
275 settings.put(viewId + ".zoom", viewer.getZoom()); //$NON-NLS-1$
276 }
277 });
278
279 getSite().setSelectionProvider(this);
280
281 ISelectionChangedListener listener = new ISelectionChangedListener() {
282 @Override
283 public void selectionChanged(SelectionChangedEvent e)
284 {
285 if (bendpointEditor != null)
286 {
287 bendpointEditor.stop();
288 bendpointEditor = null;
289 }
290
291 currentSelection = transformSelection(e.getSelection());
292
293 if (currentSelection.size() == 1)
294 {
295 int selectionType = analyzeSelection(currentSelection);
296 if (selectionType == SELECTION_OBJECTS)
297 {
298 AbstractObject object = (AbstractObject)currentSelection.getFirstElement();
299 actionOpenDrillDownObject.setEnabled(object.getDrillDownObjectId() != 0);
300 }
301 else
302 {
303 actionOpenDrillDownObject.setEnabled(false);
304 if (selectionType == SELECTION_LINKS)
305 {
306 NetworkMapLink link = (NetworkMapLink)currentSelection.getFirstElement();
307 if (link.getRouting() == NetworkMapLink.ROUTING_BENDPOINTS)
308 {
309 bendpointEditor = new BendpointEditor(link,
310 (GraphConnection)viewer.getGraphControl().getSelection().get(0), viewer);
311 }
312 }
313 }
314 }
315 else
316 {
317 actionOpenDrillDownObject.setEnabled(false);
318 }
319
320 if (selectionListeners.isEmpty())
321 return;
322
323 SelectionChangedEvent event = new SelectionChangedEvent(AbstractNetworkMapView.this, currentSelection);
324 for(ISelectionChangedListener l : selectionListeners)
325 {
326 l.selectionChanged(event);
327 }
328 }
329 };
330 viewer.addPostSelectionChangedListener(listener);
331
332 viewer.addDoubleClickListener(new IDoubleClickListener() {
333 @Override
334 public void doubleClick(DoubleClickEvent event)
335 {
336 int selectionType = analyzeSelection(currentSelection);
337 if (selectionType == SELECTION_OBJECTS)
338 {
339 AbstractObject object = (AbstractObject)currentSelection.getFirstElement();
340
341 for(DoubleClickHandlerData h : doubleClickHandlers)
342 {
343 if ((h.enabledFor == null) || (h.enabledFor.isInstance(object)))
344 {
345 if (h.handler.onDoubleClick(object))
346 {
347 return;
348 }
349 }
350 }
351 }
352
353 // Default behavior
354 actionOpenDrillDownObject.run();
355 }
356 });
357
358 sessionListener = new SessionListener() {
359 @Override
360 public void notificationHandler(final SessionNotification n)
361 {
362 if (n.getCode() == SessionNotification.OBJECT_CHANGED)
363 {
364 viewer.getControl().getDisplay().asyncExec(new Runnable() {
365 @Override
366 public void run()
367 {
368 onObjectChange((AbstractObject)n.getObject());
369 }
370 });
371 }
372 }
373 };
374 session.addListener(sessionListener);
375
376 createActions();
377 contributeToActionBars();
378 createPopupMenu();
379
380 if (automaticLayoutEnabled)
381 {
382 setLayoutAlgorithm(layoutAlgorithm, true);
383 }
384 else
385 {
386 viewer.setLayoutAlgorithm(new ManualLayout());
387 }
388
389 activateContext();
390 registerDoubleClickHandlers();
391 setupMapControl();
392 refreshMap();
393 }
394
395 /**
396 * Called from createPartControl to allow subclasses to do additional map setup. Subclasses
397 * should override this method instead of createPartControl. Default implementation do nothing.
398 */
399 protected void setupMapControl()
400 {
401 }
402
403 /**
404 * Activate context
405 */
406 private void activateContext()
407 {
408 IContextService contextService = (IContextService)getSite().getService(IContextService.class);
409 if (contextService != null)
410 {
411 contextService.activateContext("org.netxms.ui.eclipse.networkmaps.context.NetworkMaps"); //$NON-NLS-1$
412 }
413 }
414
415 /**
416 * Register double click handlers
417 */
418 private void registerDoubleClickHandlers()
419 {
420 // Read all registered extensions and create handlers
421 final IExtensionRegistry reg = Platform.getExtensionRegistry();
422 IConfigurationElement[] elements = reg
423 .getConfigurationElementsFor("org.netxms.ui.eclipse.networkmaps.objectDoubleClickHandlers"); //$NON-NLS-1$
424 for(int i = 0; i < elements.length; i++)
425 {
426 try
427 {
428 final DoubleClickHandlerData h = new DoubleClickHandlerData();
429 h.handler = (ObjectDoubleClickHandler)elements[i].createExecutableExtension("class"); //$NON-NLS-1$
430 h.priority = safeParseInt(elements[i].getAttribute("priority")); //$NON-NLS-1$
431 final String className = elements[i].getAttribute("enabledFor"); //$NON-NLS-1$
432 try
433 {
434 h.enabledFor = (className != null) ? Class.forName(className) : null;
435 }
436 catch(Exception e)
437 {
438 h.enabledFor = null;
439 }
440 doubleClickHandlers.add(h);
441 }
442 catch(CoreException e)
443 {
444 e.printStackTrace();
445 }
446 }
447
448 // Sort handlers by priority
449 Collections.sort(doubleClickHandlers, new Comparator<DoubleClickHandlerData>() {
450 @Override
451 public int compare(DoubleClickHandlerData arg0, DoubleClickHandlerData arg1)
452 {
453 return arg0.priority - arg1.priority;
454 }
455 });
456 }
457
458 /**
459 * Do full map refresh
460 */
461 protected void refreshMap()
462 {
463 buildMapPage();
464 viewer.setInput(mapPage);
465 viewer.setSelection(StructuredSelection.EMPTY);
466 }
467
468 /**
469 * Replace current map page with new one
470 *
471 * @param page new map page
472 */
473 protected void replaceMapPage(final NetworkMapPage page, Display display)
474 {
475 display.asyncExec(new Runnable() {
476 @Override
477 public void run()
478 {
479 mapPage = page;
480 addDciToRequestList();
481 viewer.setInput(mapPage);
482 }
483 });
484 }
485
486 /**
487 * Set layout algorithm for map
488 *
489 * @param alg Layout algorithm
490 * @param forceChange
491 */
492 protected void setLayoutAlgorithm(MapLayoutAlgorithm alg, boolean forceChange)
493 {
494 if (alg == MapLayoutAlgorithm.MANUAL)
495 {
496 if (!automaticLayoutEnabled)
497 return; // manual layout already
498
499 automaticLayoutEnabled = false;
500 // TODO: rewrite, enum value should not be used as index
501 actionSetAlgorithm[layoutAlgorithm.getValue()].setChecked(false);
502 actionEnableAutomaticLayout.setChecked(false);
503 return;
504 }
505
506 if (automaticLayoutEnabled && (alg == layoutAlgorithm) && !forceChange)
507 return; // nothing to change
508
509 if (!automaticLayoutEnabled)
510 {
511 actionEnableAutomaticLayout.setChecked(true);
512 automaticLayoutEnabled = true;
513 }
514
515 LayoutAlgorithm algorithm;
516
517 switch(alg)
518 {
519 case SPRING:
520 algorithm = new SpringLayoutAlgorithm();
521 break;
522 case RADIAL:
523 algorithm = new RadialLayoutAlgorithm();
524 break;
525 case HTREE:
526 algorithm = new TreeLayoutAlgorithm(TreeLayoutAlgorithm.LEFT_RIGHT);
527 break;
528 case VTREE:
529 algorithm = new TreeLayoutAlgorithm(TreeLayoutAlgorithm.TOP_DOWN);
530 break;
531 case SPARSE_VTREE:
532 algorithm = new TreeLayoutAlgorithm(TreeLayoutAlgorithm.TOP_DOWN);
533 ((TreeLayoutAlgorithm)algorithm).setNodeSpace(new Dimension(100, 100));
534 break;
535 default:
536 algorithm = new GridLayoutAlgorithm();
537 break;
538 }
539
540 viewer.setLayoutAlgorithm(alwaysFitLayout ? algorithm : new CompositeLayoutAlgorithm(new LayoutAlgorithm[] { algorithm, new ExpansionAlgorithm() }));
541
542 actionSetAlgorithm[layoutAlgorithm.getValue()].setChecked(false);
543 layoutAlgorithm = alg;
544 actionSetAlgorithm[layoutAlgorithm.getValue()].setChecked(true);
545 }
546
547 /**
548 * Update stored object positions with actual positions read from graph control
549 */
550 protected void updateObjectPositions()
551 {
552 Graph graph = viewer.getGraphControl();
553 List<?> nodes = graph.getNodes();
554 for(Object o : nodes)
555 {
556 if (o instanceof GraphNode)
557 {
558 Object data = ((GraphNode)o).getData();
559 if (data instanceof NetworkMapElement)
560 {
561 Point loc = ((GraphNode)o).getLocation();
562 Dimension size = ((GraphNode)o).getSize();
563 ((NetworkMapElement)data).setLocation(loc.x + (size.width + 1) / 2, loc.y + (size.height + 1) / 2);
564 }
565 }
566 }
567 }
568
569 /**
570 * Set manual layout mode
571 */
572 protected void setManualLayout()
573 {
574 updateObjectPositions();
575
576 automaticLayoutEnabled = false;
577 viewer.setLayoutAlgorithm(new ManualLayout(), true);
578
579 for(int i = 0; i < actionSetAlgorithm.length; i++)
580 actionSetAlgorithm[i].setEnabled(false);
581 actionSaveLayout.setEnabled(true);
582 }
583
584 /**
585 * Set automatic layout mode
586 */
587 protected void setAutomaticLayout()
588 {
589 automaticLayoutEnabled = true;
590 setLayoutAlgorithm(layoutAlgorithm, true);
591
592 for(int i = 0; i < actionSetAlgorithm.length; i++)
593 actionSetAlgorithm[i].setEnabled(true);
594 actionSaveLayout.setEnabled(false);
595 }
596
597 /**
598 * Create actions
599 */
600 protected void createActions()
601 {
602 final IHandlerService handlerService = (IHandlerService)getSite().getService(IHandlerService.class);
603
604 actionRefresh = new RefreshAction(this) {
605 @Override
606 public void run()
607 {
608 refreshMap();
609 }
610 };
611
612 actionShowStatusBackground = new Action(Messages.get().AbstractNetworkMapView_ShowStatusBkgnd, Action.AS_CHECK_BOX) {
613 @Override
614 public void run()
615 {
616 labelProvider.setShowStatusBackground(!labelProvider.isShowStatusBackground());
617 setChecked(labelProvider.isShowStatusBackground());
618 updateObjectPositions();
619 saveLayout();
620 viewer.refresh();
621 }
622 };
623 actionShowStatusBackground.setChecked(labelProvider.isShowStatusBackground());
624 actionShowStatusBackground.setEnabled(labelProvider.getObjectFigureType() == MapObjectDisplayMode.ICON);
625
626 actionShowStatusIcon = new Action(Messages.get().AbstractNetworkMapView_ShowStatusIcon, Action.AS_CHECK_BOX) {
627 @Override
628 public void run()
629 {
630 labelProvider.setShowStatusIcons(!labelProvider.isShowStatusIcons());
631 setChecked(labelProvider.isShowStatusIcons());
632 updateObjectPositions();
633 saveLayout();
634 viewer.refresh();
635 }
636 };
637 actionShowStatusIcon.setChecked(labelProvider.isShowStatusIcons());
638 actionShowStatusIcon.setEnabled(labelProvider.getObjectFigureType() == MapObjectDisplayMode.ICON);
639
640 actionShowStatusFrame = new Action(Messages.get().AbstractNetworkMapView_ShowStatusFrame, Action.AS_CHECK_BOX) {
641 @Override
642 public void run()
643 {
644 labelProvider.setShowStatusFrame(!labelProvider.isShowStatusFrame());
645 setChecked(labelProvider.isShowStatusFrame());
646 updateObjectPositions();
647 saveLayout();
648 viewer.refresh();
649 }
650 };
651 actionShowStatusFrame.setChecked(labelProvider.isShowStatusFrame());
652 actionShowStatusFrame.setEnabled(labelProvider.getObjectFigureType() == MapObjectDisplayMode.ICON);
653
654 actionZoomIn = new Action(Messages.get().AbstractNetworkMapView_ZoomIn, SharedIcons.ZOOM_IN) {
655 @Override
656 public void run()
657 {
658 viewer.zoomIn();
659 }
660 };
661 actionZoomIn.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.ZoomIn"); //$NON-NLS-1$
662 actionZoomIn.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.ZoomIn"); //$NON-NLS-1$
663 handlerService.activateHandler(actionZoomIn.getActionDefinitionId(), new ActionHandler(actionZoomIn));
664
665 actionZoomOut = new Action(Messages.get().AbstractNetworkMapView_ZoomOut, SharedIcons.ZOOM_OUT) {
666 @Override
667 public void run()
668 {
669 viewer.zoomOut();
670 }
671 };
672 actionZoomOut.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.ZoomOut"); //$NON-NLS-1$
673 actionZoomOut.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.ZoomOut"); //$NON-NLS-1$
674 handlerService.activateHandler(actionZoomOut.getActionDefinitionId(), new ActionHandler(actionZoomOut));
675
676 actionZoomFit = new Action(Messages.get().AbstractNetworkMapView_ZoomFit, Activator.getImageDescriptor("icons/fit.png")) { //$NON-NLS-1$
677 @Override
678 public void run()
679 {
680 viewer.zoomFit();
681 }
682 };
683 actionZoomFit.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.ZoomToFit"); //$NON-NLS-1$
684 actionZoomFit.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.ZoomToFit"); //$NON-NLS-1$
685 handlerService.activateHandler(actionZoomFit.getActionDefinitionId(), new ActionHandler(actionZoomFit));
686
687 actionZoomTo = viewer.createZoomActions(handlerService);
688
689 actionSetAlgorithm = new Action[layoutAlgorithmNames.length];
690 for(int i = 0; i < layoutAlgorithmNames.length; i++)
691 {
692 final MapLayoutAlgorithm alg = MapLayoutAlgorithm.getByValue(i);
693 actionSetAlgorithm[i] = new Action(layoutAlgorithmNames[i], Action.AS_RADIO_BUTTON) {
694 @Override
695 public void run()
696 {
697 setLayoutAlgorithm(alg, true);
698 viewer.setInput(mapPage);
699 }
700 };
701 actionSetAlgorithm[i].setChecked(layoutAlgorithm.getValue() == i);
702 actionSetAlgorithm[i].setEnabled(automaticLayoutEnabled);
703 }
704
705 actionAlwaysFitLayout = new Action(Messages.get().AbstractNetworkMapView_AlwaysFitLayout, Action.AS_CHECK_BOX) {
706 @Override
707 public void run()
708 {
709 alwaysFitLayout = actionAlwaysFitLayout.isChecked();
710 setLayoutAlgorithm(layoutAlgorithm, true);
711 IDialogSettings settings = Activator.getDefault().getDialogSettings();
712 settings.put(viewId + ".alwaysFitLayout", alwaysFitLayout); //$NON-NLS-1$
713 }
714 };
715 actionAlwaysFitLayout.setChecked(alwaysFitLayout);
716
717 actionSetRouter = new Action[connectionRouterNames.length];
718 for(int i = 0; i < connectionRouterNames.length; i++)
719 {
720 final int alg = i + 1;
721 actionSetRouter[i] = new Action(connectionRouterNames[i], Action.AS_RADIO_BUTTON) {
722 @Override
723 public void run()
724 {
725 setConnectionRouter(alg, true);
726 }
727 };
728 actionSetRouter[i].setChecked(routingAlgorithm == alg);
729 }
730
731 actionEnableAutomaticLayout = new Action(Messages.get().AbstractNetworkMapView_EnableAutoLayout, Action.AS_CHECK_BOX) {
732 @Override
733 public void run()
734 {
735 if (automaticLayoutEnabled)
736 {
737 setManualLayout();
738 }
739 else
740 {
741 setAutomaticLayout();
742 }
743 setChecked(automaticLayoutEnabled);
744 }
745 };
746 actionEnableAutomaticLayout.setChecked(automaticLayoutEnabled);
747
748 actionSaveLayout = new Action(Messages.get().AbstractNetworkMapView_SaveLayout) {
749 @Override
750 public void run()
751 {
752 updateObjectPositions();
753 saveLayout();
754 }
755 };
756 actionSaveLayout.setImageDescriptor(SharedIcons.SAVE);
757 actionSaveLayout.setEnabled(!automaticLayoutEnabled);
758
759 actionOpenDrillDownObject = new Action("Open drill-down object") {
760 @Override
761 public void run()
762 {
763 openDrillDownObject();
764 }
765 };
766 actionOpenDrillDownObject.setEnabled(false);
767
768 actionFiguresIcons = new Action(Messages.get().AbstractNetworkMapView_Icons, Action.AS_RADIO_BUTTON) {
769 @Override
770 public void run()
771 {
772 setObjectDisplayMode(MapObjectDisplayMode.ICON, true);
773 }
774 };
775
776 actionFiguresSmallLabels = new Action(Messages.get().AbstractNetworkMapView_SmallLabels, Action.AS_RADIO_BUTTON) {
777 @Override
778 public void run()
779 {
780 setObjectDisplayMode(MapObjectDisplayMode.SMALL_LABEL, true);
781 }
782 };
783
784 actionFiguresLargeLabels = new Action(Messages.get().AbstractNetworkMapView_LargeLabels, Action.AS_RADIO_BUTTON) {
785 @Override
786 public void run()
787 {
788 setObjectDisplayMode(MapObjectDisplayMode.LARGE_LABEL, true);
789 }
790 };
791
792 actionFiguresStatusIcons = new Action(Messages.get().AbstractNetworkMapView_StatusIcons, Action.AS_RADIO_BUTTON) {
793 @Override
794 public void run()
795 {
796 setObjectDisplayMode(MapObjectDisplayMode.STATUS, true);
797 }
798 };
799
800 actionShowGrid = new Action(Messages.get().AbstractNetworkMapView_ShowGrid, Action.AS_CHECK_BOX) {
801 @Override
802 public void run()
803 {
804 viewer.showGrid(actionShowGrid.isChecked());
805 }
806 };
807 actionShowGrid.setImageDescriptor(Activator.getImageDescriptor("icons/grid.png")); //$NON-NLS-1$
808 actionShowGrid.setChecked(viewer.isGridVisible());
809 actionShowGrid.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.ShowGrid"); //$NON-NLS-1$
810 actionShowGrid.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.ShowGrid"); //$NON-NLS-1$
811 handlerService.activateHandler(actionShowGrid.getActionDefinitionId(), new ActionHandler(actionShowGrid));
812
813 actionSnapToGrid = new Action(Messages.get().AbstractNetworkMapView_SnapToGrid, Action.AS_CHECK_BOX) {
814 @Override
815 public void run()
816 {
817 viewer.setSnapToGrid(actionSnapToGrid.isChecked());
818 }
819 };
820 actionSnapToGrid.setImageDescriptor(Activator.getImageDescriptor("icons/snap_to_grid.png")); //$NON-NLS-1$
821 actionSnapToGrid.setChecked(viewer.isSnapToGrid());
822
823 actionAlignToGrid = new Action(Messages.get().AbstractNetworkMapView_AlignToGrid, Activator.getImageDescriptor("icons/align_to_grid.gif")) { //$NON-NLS-1$
824 @Override
825 public void run()
826 {
827 viewer.alignToGrid(false);
828 updateObjectPositions();
829 }
830 };
831 actionAlignToGrid.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.AlignToGrid"); //$NON-NLS-1$
832 actionAlignToGrid.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.AlignToGrid"); //$NON-NLS-1$
833 handlerService.activateHandler(actionAlignToGrid.getActionDefinitionId(), new ActionHandler(actionAlignToGrid));
834
835 actionShowObjectDetails = new Action(Messages.get().AbstractNetworkMapView_ShowObjDetails) {
836 @Override
837 public void run()
838 {
839 showObjectDetails();
840 }
841 };
842
843 actionCopyImage = new Action(Messages.get().AbstractNetworkMapView_CopyToClipboard, SharedIcons.COPY) {
844 @Override
845 public void run()
846 {
847 Image image = viewer.takeSnapshot();
848 ImageTransfer imageTransfer = ImageTransfer.getInstance();
849 final Clipboard clipboard = new Clipboard(viewer.getControl().getDisplay());
850 clipboard.setContents(new Object[] { image.getImageData() }, new Transfer[] { imageTransfer });
851 }
852 };
853
854 actionHideLinkLabels = new Action(Messages.get().AbstractNetworkMapView_HideLinkLabels, Action.AS_CHECK_BOX) {
855 @Override
856 public void run()
857 {
858 labelProvider.setConnectionLabelsVisible(!actionHideLinkLabels.isChecked());
859 viewer.refresh(true);
860 }
861 };
862 actionHideLinkLabels.setImageDescriptor(Activator.getImageDescriptor("icons/hide_link.png")); //$NON-NLS-1$
863
864 actionHideLinks = new Action(Messages.get().AbstractNetworkMapView_HideLinks, Action.AS_CHECK_BOX) {
865 @Override
866 public void run()
867 {
868 labelProvider.setConnectionsVisible(!actionHideLinks.isChecked());
869 viewer.refresh(true);
870 }
871 };
872 actionHideLinks.setImageDescriptor(Activator.getImageDescriptor("icons/hide_net_link.png")); //$NON-NLS-1$
873
874 actionSelectAllObjects = new Action(Messages.get().AbstractNetworkMapView_SelectAllObjects) {
875 @Override
876 public void run()
877 {
878 viewer.setSelection(new StructuredSelection(mapPage.getObjectElements()));
879 }
880 };
881 actionSelectAllObjects.setId("org.netxms.ui.eclipse.networkmaps.localActions.AbstractMap.SelectAllObjects"); //$NON-NLS-1$
882 actionSelectAllObjects.setActionDefinitionId("org.netxms.ui.eclipse.networkmaps.localCommands.AbstractMap.SelectAllObjects"); //$NON-NLS-1$
883 handlerService.activateHandler(actionSelectAllObjects.getActionDefinitionId(), new ActionHandler(actionSelectAllObjects));
884 }
885
886 /**
887 * Create "Layout" submenu
888 *
889 * @return
890 */
891 protected IContributionItem createLayoutSubmenu()
892 {
893 MenuManager layout = new MenuManager(Messages.get().AbstractNetworkMapView_Layout);
894 if (allowManualLayout)
895 {
896 layout.add(actionEnableAutomaticLayout);
897 }
898 layout.add(actionAlwaysFitLayout);
899 layout.add(new Separator());
900 for(int i = 0; i < actionSetAlgorithm.length; i++)
901 layout.add(actionSetAlgorithm[i]);
902 if (allowManualLayout)
903 {
904 layout.add(new Separator());
905 layout.add(actionSaveLayout);
906 }
907 return layout;
908 }
909
910 /**
911 * Create "Routing" submenu
912 *
913 * @return
914 */
915 protected IContributionItem createRoutingSubmenu()
916 {
917 MenuManager submenu = new MenuManager(Messages.get().AbstractNetworkMapView_Routing);
918 for(int i = 0; i < actionSetRouter.length; i++)
919 submenu.add(actionSetRouter[i]);
920 return submenu;
921 }
922
923 /**
924 * Fill action bars
925 */
926 private void contributeToActionBars()
927 {
928 IActionBars bars = getViewSite().getActionBars();
929 fillLocalPullDown(bars.getMenuManager());
930 fillLocalToolBar(bars.getToolBarManager());
931 }
932
933 /**
934 * Fill local pull-down menu
935 *
936 * @param manager
937 */
938 protected void fillLocalPullDown(IMenuManager manager)
939 {
940 MenuManager zoom = new MenuManager(Messages.get().AbstractNetworkMapView_Zoom);
941 for(int i = 0; i < actionZoomTo.length; i++)
942 zoom.add(actionZoomTo[i]);
943
944 MenuManager figureType = new MenuManager(Messages.get().AbstractNetworkMapView_DisplayObjectAs);
945 figureType.add(actionFiguresIcons);
946 figureType.add(actionFiguresSmallLabels);
947 figureType.add(actionFiguresLargeLabels);
948 figureType.add(actionFiguresStatusIcons);
949
950 manager.add(actionShowStatusBackground);
951 manager.add(actionShowStatusIcon);
952 manager.add(actionShowStatusFrame);
953 manager.add(new Separator());
954 manager.add(createLayoutSubmenu());
955 manager.add(createRoutingSubmenu());
956 manager.add(figureType);
957 manager.add(new Separator());
958 manager.add(actionZoomIn);
959 manager.add(actionZoomOut);
960 manager.add(actionZoomFit);
961 manager.add(zoom);
962 manager.add(new Separator());
963 manager.add(actionAlignToGrid);
964 manager.add(actionSnapToGrid);
965 manager.add(actionShowGrid);
966 manager.add(new Separator());
967 manager.add(actionHideLinkLabels);
968 manager.add(actionHideLinks);
969 manager.add(new Separator());
970 manager.add(actionCopyImage);
971 manager.add(new Separator());
972 manager.add(actionSelectAllObjects);
973 manager.add(new Separator());
974 manager.add(actionRefresh);
975 }
976
977 /**
978 * Fill local tool bar
979 *
980 * @param manager
981 */
982 protected void fillLocalToolBar(IToolBarManager manager)
983 {
984 manager.add(actionZoomIn);
985 manager.add(actionZoomOut);
986 manager.add(actionZoomFit);
987 manager.add(new Separator());
988 manager.add(actionAlignToGrid);
989 manager.add(actionSnapToGrid);
990 manager.add(actionShowGrid);
991 manager.add(new Separator());
992 manager.add(actionHideLinkLabels);
993 manager.add(actionHideLinks);
994 manager.add(new Separator());
995 if (allowManualLayout)
996 {
997 manager.add(actionSaveLayout);
998 }
999 manager.add(actionCopyImage);
1000 manager.add(new Separator());
1001 manager.add(actionRefresh);
1002 }
1003
1004 /**
1005 * Create popup menu for map
1006 */
1007 private void createPopupMenu()
1008 {
1009 // Create menu manager.
1010 MenuManager menuMgr = new FilteringMenuManager(Activator.PLUGIN_ID);
1011 menuMgr.setRemoveAllWhenShown(true);
1012 menuMgr.addMenuListener(new IMenuListener() {
1013 public void menuAboutToShow(IMenuManager manager)
1014 {
1015 int selType = analyzeSelection(currentSelection);
1016 switch(selType)
1017 {
1018 case SELECTION_EMPTY:
1019 fillMapContextMenu(manager);
1020 break;
1021 case SELECTION_OBJECTS:
1022 fillObjectContextMenu(manager);
1023 break;
1024 case SELECTION_ELEMENTS:
1025 fillElementContextMenu(manager);
1026 break;
1027 case SELECTION_LINKS:
1028 fillLinkContextMenu(manager);
1029 break;
1030 }
1031 }
1032 });
1033
1034 // Create menu.
1035 Menu menu = menuMgr.createContextMenu(viewer.getControl());
1036 viewer.getControl().setMenu(menu);
1037
1038 // Register menu for extension.
1039 getSite().registerContextMenu(menuMgr, this);
1040 }
1041
1042 /**
1043 * Fill context menu for map object
1044 *
1045 * @param manager Menu manager
1046 */
1047 protected void fillObjectContextMenu(IMenuManager manager)
1048 {
1049 manager.add(actionOpenDrillDownObject);
1050 manager.add(new Separator());
1051 ObjectContextMenu.fill(manager, getSite(), this);
1052 if (currentSelection.size() == 1)
1053 {
1054 manager.insertAfter(GroupMarkers.MB_PROPERTIES, actionShowObjectDetails);
1055 }
1056 }
1057
1058 /**
1059 * Fill context menu for map element
1060 *
1061 * @param manager Menu manager
1062 */
1063 protected void fillElementContextMenu(IMenuManager manager)
1064 {
1065 }
1066
1067 /**
1068 * Fill context menu for link between objects
1069 *
1070 * @param manager Menu manager
1071 */
1072 protected void fillLinkContextMenu(IMenuManager manager)
1073 {
1074 }
1075
1076 /**
1077 * Fill context menu for map view
1078 *
1079 * @param manager Menu manager
1080 */
1081 protected void fillMapContextMenu(IMenuManager manager)
1082 {
1083 MenuManager zoom = new MenuManager(Messages.get().AbstractNetworkMapView_Zoom);
1084 for(int i = 0; i < actionZoomTo.length; i++)
1085 zoom.add(actionZoomTo[i]);
1086
1087 MenuManager figureType = new MenuManager(Messages.get().AbstractNetworkMapView_DisplayObjectAs);
1088 figureType.add(actionFiguresIcons);
1089 figureType.add(actionFiguresSmallLabels);
1090 figureType.add(actionFiguresLargeLabels);
1091 figureType.add(actionFiguresStatusIcons);
1092
1093 manager.add(actionShowStatusBackground);
1094 manager.add(actionShowStatusIcon);
1095 manager.add(actionShowStatusFrame);
1096 manager.add(new Separator());
1097 manager.add(createLayoutSubmenu());
1098 manager.add(createRoutingSubmenu());
1099 manager.add(figureType);
1100 manager.add(new Separator());
1101 manager.add(actionZoomIn);
1102 manager.add(actionZoomOut);
1103 manager.add(actionZoomFit);
1104 manager.add(zoom);
1105 manager.add(new Separator());
1106 manager.add(actionAlignToGrid);
1107 manager.add(actionSnapToGrid);
1108 manager.add(actionShowGrid);
1109 manager.add(new Separator());
1110 manager.add(actionHideLinkLabels);
1111 manager.add(actionHideLinks);
1112 manager.add(new Separator());
1113 manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
1114 manager.add(new Separator());
1115 manager.add(actionSelectAllObjects);
1116 manager.add(new Separator());
1117 manager.add(actionRefresh);
1118 }
1119
1120 /**
1121 * Tests if given selection contains only NetXMS objects
1122 *
1123 * @param selection
1124 * @return
1125 */
1126 @SuppressWarnings("rawtypes")
1127 private int analyzeSelection(IStructuredSelection selection)
1128 {
1129 if (selection.isEmpty())
1130 return SELECTION_EMPTY;
1131
1132 Iterator it = selection.iterator();
1133 Object first = it.next();
1134 int type;
1135 Class firstClass;
1136 if (first instanceof AbstractObject)
1137 {
1138 type = SELECTION_OBJECTS;
1139 firstClass = AbstractObject.class;
1140 }
1141 else if (first instanceof NetworkMapElement)
1142 {
1143 type = SELECTION_ELEMENTS;
1144 firstClass = NetworkMapElement.class;
1145 }
1146 else if (first instanceof NetworkMapLink)
1147 {
1148 type = SELECTION_LINKS;
1149 firstClass = NetworkMapLink.class;
1150 }
1151 else
1152 {
1153 return SELECTION_MIXED;
1154 }
1155
1156 while(it.hasNext())
1157 {
1158 final Object o = it.next();
1159 if (!firstClass.isInstance(o))
1160 return SELECTION_MIXED;
1161 }
1162 return type;
1163 }
1164
1165 /**
1166 * Called by session listener when NetXMS object was changed.
1167 *
1168 * @param object changed NetXMS object
1169 */
1170 protected void onObjectChange(final AbstractObject object)
1171 {
1172 NetworkMapObject element = mapPage.findObjectElement(object.getObjectId());
1173 if (element != null)
1174 viewer.refresh(element, true);
1175
1176 List<NetworkMapLink> links = mapPage.findLinksWithStatusObject(object.getObjectId());
1177 if (links != null)
1178 {
1179 for(NetworkMapLink l : links)
1180 viewer.refresh(l);
1181 addDciToRequestList();
1182 }
1183
1184 if (object.getObjectId() == rootObject.getObjectId())
1185 rootObject = object;
1186 }
1187
1188 /**
1189 * Called when map layout has to be saved. Object positions already updated when this method is called. Default implementation
1190 * does nothing.
1191 */
1192 protected void saveLayout()
1193 {
1194 }
1195
1196 /*
1197 * (non-Javadoc)
1198 *
1199 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
1200 */
1201 @Override
1202 public void setFocus()
1203 {
1204 viewer.getControl().setFocus();
1205 }
1206
1207 /*
1208 * (non-Javadoc)
1209 *
1210 * @see org.eclipse.ui.part.WorkbenchPart#dispose()
1211 */
1212 @Override
1213 public void dispose()
1214 {
1215 if (sessionListener != null)
1216 session.removeListener(sessionListener);
1217 if (labelProvider != null)
1218 {
1219 IDialogSettings settings = Activator.getDefault().getDialogSettings();
1220 settings.put(viewId + ".objectFigureType", labelProvider.getObjectFigureType().ordinal()); //$NON-NLS-1$
1221 }
1222 removeDciFromRequestList();
1223 super.dispose();
1224 }
1225
1226 /*
1227 * (non-Javadoc)
1228 *
1229 * @see
1230 * org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
1231 */
1232 @Override
1233 public void addSelectionChangedListener(ISelectionChangedListener listener)
1234 {
1235 selectionListeners.add(listener);
1236 }
1237
1238 /**
1239 * Transform viewer's selection to form usable by another plugins by extracting NetXMS objects from map elements.
1240 *
1241 * @param viewerSelection viewer's selection
1242 * @return selection containing only NetXMS objects
1243 */
1244 @SuppressWarnings("rawtypes")
1245 private IStructuredSelection transformSelection(ISelection viewerSelection)
1246 {
1247 IStructuredSelection selection = (IStructuredSelection)viewerSelection;
1248 if (selection.isEmpty())
1249 return selection;
1250
1251 List<Object> objects = new ArrayList<Object>();
1252 Iterator it = selection.iterator();
1253 while(it.hasNext())
1254 {
1255 Object element = it.next();
1256 if (element instanceof NetworkMapObject)
1257 {
1258 AbstractObject object = session.findObjectById(((NetworkMapObject)element).getObjectId());
1259 if (object != null)
1260 {
1261 objects.add(object);
1262 }
1263 else
1264 {
1265 // Fix for issue NX-24
1266 // If object not found, add map element to selection
1267 // This will allow removal of unknown objects from map
1268 objects.add(element);
1269 }
1270 }
1271 else if (isSelectableElement(element))
1272 {
1273 objects.add(element);
1274 }
1275 }
1276
1277 return new StructuredSelection(objects.toArray());
1278 }
1279
1280 /**
1281 * Tests if given map element is selectable. Default implementation always returns false.
1282 *
1283 * @param element element to test
1284 * @return true if given element is selectable
1285 */
1286 protected boolean isSelectableElement(Object element)
1287 {
1288 return false;
1289 }
1290
1291 /*
1292 * (non-Javadoc)
1293 *
1294 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
1295 */
1296 @Override
1297 public ISelection getSelection()
1298 {
1299 return currentSelection;
1300 }
1301
1302 /*
1303 * (non-Javadoc)
1304 *
1305 * @see
1306 * org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener
1307 * )
1308 */
1309 @Override
1310 public void removeSelectionChangedListener(ISelectionChangedListener listener)
1311 {
1312 selectionListeners.remove(listener);
1313 }
1314
1315 /*
1316 * (non-Javadoc)
1317 *
1318 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
1319 */
1320 @Override
1321 public void setSelection(ISelection selection)
1322 {
1323 }
1324
1325 /*
1326 * (non-Javadoc)
1327 *
1328 * @see org.eclipse.gef4.zest.core.viewers.IZoomableWorkbenchPart#getZoomableViewer()
1329 */
1330 @Override
1331 public AbstractZoomableViewer getZoomableViewer()
1332 {
1333 return viewer;
1334 }
1335
1336 /**
1337 * Open drill-down object for currently selected object
1338 */
1339 private void openDrillDownObject()
1340 {
1341 if (currentSelection == null)
1342 return;
1343
1344 Object object = currentSelection.getFirstElement();
1345 if (object instanceof AbstractObject)
1346 {
1347 long objectId = (object instanceof NetworkMap) ? ((AbstractObject)object).getObjectId() : ((AbstractObject)object).getDrillDownObjectId();
1348 if (objectId != 0)
1349 {
1350 Object test = session.findObjectById(objectId);
1351 if (test instanceof NetworkMap)
1352 {
1353 try
1354 {
1355 getSite().getPage().showView(PredefinedMap.ID, Long.toString(objectId), IWorkbenchPage.VIEW_ACTIVATE);
1356 }
1357 catch(PartInitException e)
1358 {
1359 MessageDialogHelper.openError(getSite().getShell(), Messages.get().AbstractNetworkMapView_Error, String.format("Cannot open drill-down object view: %s", e.getMessage()));
1360 }
1361 }
1362 if (test instanceof Dashboard)
1363 {
1364 try
1365 {
1366 getSite().getPage().showView("org.netxms.ui.eclipse.dashboard.views.DashboardView", Long.toString(objectId), IWorkbenchPage.VIEW_ACTIVATE);
1367 }
1368 catch(PartInitException e)
1369 {
1370 MessageDialogHelper.openError(getSite().getShell(), Messages.get().AbstractNetworkMapView_Error, String.format("Cannot open drill-down object view: %s", e.getMessage()));
1371 }
1372 }
1373 }
1374 }
1375 }
1376
1377 /**
1378 * Set map default connection routing algorithm
1379 *
1380 * @param routingAlgorithm
1381 */
1382 public void setConnectionRouter(int routingAlgorithm, boolean doSave)
1383 {
1384 switch(routingAlgorithm)
1385 {
1386 case NetworkMapLink.ROUTING_MANHATTAN:
1387 this.routingAlgorithm = NetworkMapLink.ROUTING_MANHATTAN;
1388 viewer.getGraphControl().setRouter(new ManhattanConnectionRouter());
1389 break;
1390 default:
1391 this.routingAlgorithm = NetworkMapLink.ROUTING_DIRECT;
1392 viewer.getGraphControl().setRouter(null);
1393 break;
1394 }
1395 for(int i = 0; i < actionSetRouter.length; i++)
1396 actionSetRouter[i].setChecked(routingAlgorithm == (i + 1));
1397 if (doSave)
1398 {
1399 updateObjectPositions();
1400 saveLayout();
1401 }
1402 viewer.refresh();
1403 }
1404
1405 /**
1406 * Show details for selected object
1407 */
1408 private void showObjectDetails()
1409 {
1410 if ((currentSelection.size() != 1) || !(currentSelection.getFirstElement() instanceof AbstractObject))
1411 return;
1412
1413 AbstractObject object = (AbstractObject)currentSelection.getFirstElement();
1414 try
1415 {
1416 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
1417 .showView("org.netxms.ui.eclipse.objectview.view.tabbed_object_view"); //$NON-NLS-1$
1418 CommandBridge.getInstance().execute("TabbedObjectView/changeObject", object.getObjectId());
1419 }
1420 catch(PartInitException e)
1421 {
1422 MessageDialogHelper.openError(getSite().getShell(), Messages.get().AbstractNetworkMapView_Error,
1423 String.format(Messages.get().AbstractNetworkMapView_OpenObjDetailsError, e.getLocalizedMessage()));
1424 }
1425 }
1426
1427 /**
1428 * @param string
1429 * @return
1430 */
1431 private static int safeParseInt(String string)
1432 {
1433 if (string == null)
1434 return 65535;
1435 try
1436 {
1437 return Integer.parseInt(string);
1438 }
1439 catch(NumberFormatException e)
1440 {
1441 return 65535;
1442 }
1443 }
1444
1445 /**
1446 * Internal data for object double click handlers
1447 */
1448 private class DoubleClickHandlerData
1449 {
1450 ObjectDoubleClickHandler handler;
1451 int priority;
1452 Class<?> enabledFor;
1453 }
1454
1455 /**
1456 * Goes thought all links and trys to add to request list required DCIs.
1457 */
1458 protected void addDciToRequestList()
1459 {
1460 Collection<NetworkMapLink> linkList = mapPage.getLinks();
1461 for (NetworkMapLink item : linkList)
1462 {
1463 if(item.hasDciData())
1464 {
1465 for (SingleDciConfig value :item.getDciAsList())
1466 {
1467 if(value.type == SingleDciConfig.ITEM)
1468 {
1469 dciValueProvider.addDci(value.getNodeId(), value.dciId, mapPage);
1470 }
1471 else
1472 {
1473 dciValueProvider.addDci(value.getNodeId(), value.dciId, value.column, value.instance, mapPage);
1474 }
1475 }
1476 }
1477 }
1478 Collection<NetworkMapElement> mapElements = mapPage.getElements();
1479 for (NetworkMapElement element : mapElements)
1480 {
1481 if(element instanceof NetworkMapDCIContainer)
1482 {
1483 NetworkMapDCIContainer item = (NetworkMapDCIContainer)element;
1484 if(item.hasDciData())
1485 {
1486 for (SingleDciConfig value : item.getObjectDCIArray())
1487 {
1488 if(value.type == SingleDciConfig.ITEM)
1489 {
1490 dciValueProvider.addDci(value.getNodeId(), value.dciId, mapPage);
1491 }
1492 else
1493 {
1494 dciValueProvider.addDci(value.getNodeId(), value.dciId, value.column, value.instance, mapPage);
1495 }
1496 }
1497 }
1498 }
1499
1500 if(element instanceof NetworkMapDCIImage)
1501 {
1502 NetworkMapDCIImage item = (NetworkMapDCIImage)element;
1503 DCIImageConfiguration config = item.getImageOptions();
1504 SingleDciConfig value = config.getDci();
1505 if(value.type == SingleDciConfig.ITEM)
1506 {
1507 dciValueProvider.addDci(value.getNodeId(), value.dciId, mapPage);
1508 }
1509 else
1510 {
1511 dciValueProvider.addDci(value.getNodeId(), value.dciId, value.column, value.instance, mapPage);
1512 }
1513 }
1514 }
1515 }
1516
1517 /**
1518 * Removes DCIs from request list
1519 */
1520 protected void removeDciFromRequestList()
1521 {
1522 Collection<NetworkMapLink> linkList = mapPage.getLinks();
1523 for (NetworkMapLink item : linkList)
1524 {
1525 if(item.hasDciData())
1526 {
1527 dciValueProvider.removeDcis(mapPage);
1528 }
1529 }
1530 }
1531
1532 /**
1533 * @param mode
1534 * @param saveLayout
1535 */
1536 protected void setObjectDisplayMode(MapObjectDisplayMode mode, boolean saveLayout)
1537 {
1538 labelProvider.setObjectFigureType(mode);
1539 if (saveLayout)
1540 {
1541 updateObjectPositions();
1542 saveLayout();
1543 }
1544 viewer.refresh(true);
1545 actionShowStatusBackground.setEnabled(mode == MapObjectDisplayMode.ICON);
1546 actionShowStatusFrame.setEnabled(mode == MapObjectDisplayMode.ICON);
1547 actionShowStatusIcon.setEnabled(mode == MapObjectDisplayMode.ICON);
1548 actionFiguresIcons.setChecked(labelProvider.getObjectFigureType() == MapObjectDisplayMode.ICON);
1549 actionFiguresSmallLabels.setChecked(labelProvider.getObjectFigureType() == MapObjectDisplayMode.SMALL_LABEL);
1550 actionFiguresLargeLabels.setChecked(labelProvider.getObjectFigureType() == MapObjectDisplayMode.LARGE_LABEL);
1551 actionFiguresStatusIcons.setChecked(labelProvider.getObjectFigureType() == MapObjectDisplayMode.STATUS);
1552 }
1553 }