| 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2009, 2016 Ericsson |
| 3 | * |
| 4 | * All rights reserved. This program and the accompanying materials are |
| 5 | * made available under the terms of the Eclipse Public License v1.0 which |
| 6 | * accompanies this distribution, and is available at |
| 7 | * http://www.eclipse.org/legal/epl-v10.html |
| 8 | * |
| 9 | * Contributors: |
| 10 | * Francois Chouinard - Initial API and implementation |
| 11 | * Bernd Hufmann - Added possibility to pin view |
| 12 | * Marc-Andre Laperle - Support for view alignment |
| 13 | *******************************************************************************/ |
| 14 | |
| 15 | package org.eclipse.tracecompass.tmf.ui.views; |
| 16 | |
| 17 | import org.eclipse.jface.action.IToolBarManager; |
| 18 | import org.eclipse.jface.action.Separator; |
| 19 | import org.eclipse.swt.events.ControlAdapter; |
| 20 | import org.eclipse.swt.events.ControlEvent; |
| 21 | import org.eclipse.swt.widgets.Composite; |
| 22 | import org.eclipse.tracecompass.internal.tmf.ui.views.TimeAlignViewsAction; |
| 23 | import org.eclipse.tracecompass.internal.tmf.ui.views.TmfAlignmentSynchronizer; |
| 24 | import org.eclipse.tracecompass.tmf.core.component.ITmfComponent; |
| 25 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignal; |
| 26 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; |
| 27 | import org.eclipse.ui.IActionBars; |
| 28 | import org.eclipse.ui.IPartListener; |
| 29 | import org.eclipse.ui.IViewSite; |
| 30 | import org.eclipse.ui.IWorkbenchActionConstants; |
| 31 | import org.eclipse.ui.IWorkbenchPart; |
| 32 | import org.eclipse.ui.part.ViewPart; |
| 33 | |
| 34 | /** |
| 35 | * Basic abstract TMF view class implementation. |
| 36 | * |
| 37 | * It registers any sub class to the signal manager for receiving and sending |
| 38 | * TMF signals. |
| 39 | * |
| 40 | * @author Francois Chouinard |
| 41 | */ |
| 42 | public abstract class TmfView extends ViewPart implements ITmfComponent { |
| 43 | |
| 44 | private final String fName; |
| 45 | /** This allows us to keep track of the view sizes */ |
| 46 | private Composite fParentComposite; |
| 47 | private ControlAdapter fControlListener; |
| 48 | private static final TmfAlignmentSynchronizer TIME_ALIGNMENT_SYNCHRONIZER = new TmfAlignmentSynchronizer(); |
| 49 | |
| 50 | /** |
| 51 | * Action class for pinning of TmfView. |
| 52 | */ |
| 53 | protected PinTmfViewAction fPinAction; |
| 54 | private static TimeAlignViewsAction fAlignViewsAction; |
| 55 | |
| 56 | // ------------------------------------------------------------------------ |
| 57 | // Constructor |
| 58 | // ------------------------------------------------------------------------ |
| 59 | |
| 60 | /** |
| 61 | * Constructor. Creates a TMF view and registers to the signal manager. |
| 62 | * |
| 63 | * @param viewName |
| 64 | * A view name |
| 65 | */ |
| 66 | public TmfView(String viewName) { |
| 67 | super(); |
| 68 | fName = viewName; |
| 69 | TmfSignalManager.register(this); |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * Disposes this view and de-registers itself from the signal manager |
| 74 | */ |
| 75 | @Override |
| 76 | public void dispose() { |
| 77 | TmfSignalManager.deregister(this); |
| 78 | |
| 79 | /* Workaround for Bug 490400: Clear the action bars */ |
| 80 | IActionBars bars = getViewSite().getActionBars(); |
| 81 | bars.getToolBarManager().removeAll(); |
| 82 | bars.getMenuManager().removeAll(); |
| 83 | |
| 84 | super.dispose(); |
| 85 | } |
| 86 | |
| 87 | // ------------------------------------------------------------------------ |
| 88 | // ITmfComponent |
| 89 | // ------------------------------------------------------------------------ |
| 90 | |
| 91 | @Override |
| 92 | public String getName() { |
| 93 | return fName; |
| 94 | } |
| 95 | |
| 96 | @Override |
| 97 | public void broadcast(TmfSignal signal) { |
| 98 | TmfSignalManager.dispatchSignal(signal); |
| 99 | } |
| 100 | |
| 101 | @Override |
| 102 | public void broadcastAsync(TmfSignal signal) { |
| 103 | TmfSignalManager.dispatchSignalAsync(signal); |
| 104 | } |
| 105 | |
| 106 | // ------------------------------------------------------------------------ |
| 107 | // View pinning support |
| 108 | // ------------------------------------------------------------------------ |
| 109 | |
| 110 | /** |
| 111 | * Returns whether the pin flag is set. |
| 112 | * For example, this flag can be used to ignore time synchronization signals from other TmfViews. |
| 113 | * |
| 114 | * @return pin flag |
| 115 | */ |
| 116 | public boolean isPinned() { |
| 117 | return ((fPinAction != null) && (fPinAction.isChecked())); |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * Method adds a pin action to the TmfView. The pin action allows to toggle the <code>fIsPinned</code> flag. |
| 122 | * For example, this flag can be used to ignore time synchronization signals from other TmfViews. |
| 123 | */ |
| 124 | protected void contributePinActionToToolBar() { |
| 125 | if (fPinAction == null) { |
| 126 | fPinAction = new PinTmfViewAction(); |
| 127 | |
| 128 | IToolBarManager toolBarManager = getViewSite().getActionBars() |
| 129 | .getToolBarManager(); |
| 130 | toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| 131 | toolBarManager.add(fPinAction); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | @Override |
| 136 | public void createPartControl(final Composite parent) { |
| 137 | fParentComposite = parent; |
| 138 | if (this instanceof ITmfTimeAligned) { |
| 139 | contributeAlignViewsActionToToolbar(); |
| 140 | |
| 141 | fControlListener = new ControlAdapter() { |
| 142 | @Override |
| 143 | public void controlResized(ControlEvent e) { |
| 144 | TIME_ALIGNMENT_SYNCHRONIZER.handleViewResized(TmfView.this); |
| 145 | } |
| 146 | }; |
| 147 | parent.addControlListener(fControlListener); |
| 148 | |
| 149 | getSite().getPage().addPartListener(new IPartListener() { |
| 150 | @Override |
| 151 | public void partOpened(IWorkbenchPart part) { |
| 152 | // do nothing |
| 153 | } |
| 154 | |
| 155 | @Override |
| 156 | public void partDeactivated(IWorkbenchPart part) { |
| 157 | // do nothing |
| 158 | } |
| 159 | |
| 160 | @Override |
| 161 | public void partClosed(IWorkbenchPart part) { |
| 162 | if (part == TmfView.this && fControlListener != null && !fParentComposite.isDisposed()) { |
| 163 | fParentComposite.removeControlListener(fControlListener); |
| 164 | fControlListener = null; |
| 165 | getSite().getPage().removePartListener(this); |
| 166 | TIME_ALIGNMENT_SYNCHRONIZER.handleViewClosed(TmfView.this); |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | @Override |
| 171 | public void partBroughtToTop(IWorkbenchPart part) { |
| 172 | // do nothing |
| 173 | } |
| 174 | |
| 175 | @Override |
| 176 | public void partActivated(IWorkbenchPart part) { |
| 177 | // do nothing |
| 178 | } |
| 179 | }); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | private void contributeAlignViewsActionToToolbar() { |
| 184 | if (fAlignViewsAction == null) { |
| 185 | fAlignViewsAction = new TimeAlignViewsAction(); |
| 186 | } |
| 187 | |
| 188 | IToolBarManager toolBarManager = getViewSite().getActionBars() |
| 189 | .getToolBarManager(); |
| 190 | toolBarManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); |
| 191 | toolBarManager.add(fAlignViewsAction); |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * Returns the parent control of the view |
| 196 | * |
| 197 | * @return the parent control |
| 198 | * |
| 199 | * @since 1.0 |
| 200 | */ |
| 201 | public Composite getParentComposite() { |
| 202 | return fParentComposite; |
| 203 | } |
| 204 | |
| 205 | /** |
| 206 | * Return the Eclipse view ID in the format <Primary ID>:<Secondary ID> or |
| 207 | * simply <Primary ID> if secondary ID is null |
| 208 | * |
| 209 | * @return This view's view ID |
| 210 | * @since 2.2 |
| 211 | */ |
| 212 | protected String getViewId() { |
| 213 | IViewSite viewSite = getViewSite(); |
| 214 | String secondaryId = viewSite.getSecondaryId(); |
| 215 | if (secondaryId == null) { |
| 216 | return viewSite.getId(); |
| 217 | } |
| 218 | return viewSite.getId() + ':' + secondaryId; |
| 219 | } |
| 220 | } |