001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright � 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.pm.graphic;
051:
052: import java.awt.Color;
053: import java.awt.Cursor;
054: import java.awt.Dimension;
055: import java.awt.Font;
056: import java.awt.Point;
057: import java.awt.event.ActionEvent;
058: import java.awt.event.ActionListener;
059: import java.awt.event.KeyAdapter;
060: import java.awt.event.KeyEvent;
061: import java.awt.event.MouseEvent;
062: import java.io.Serializable;
063: import java.util.ArrayList;
064:
065: import javax.swing.AbstractAction;
066: import javax.swing.AbstractButton;
067: import javax.swing.Action;
068: import javax.swing.BorderFactory;
069: import javax.swing.JButton;
070: import javax.swing.JComponent;
071: import javax.swing.JPanel;
072: import javax.swing.JPopupMenu;
073: import javax.swing.JTabbedPane;
074: import javax.swing.JToolBar;
075: import javax.swing.JToolTip;
076: import javax.swing.event.ChangeEvent;
077: import javax.swing.event.ChangeListener;
078:
079: import org.apache.batik.util.gui.resource.ButtonFactory;
080: import org.apache.batik.util.gui.resource.JToolbarSeparator;
081:
082: import com.jgoodies.forms.builder.DefaultFormBuilder;
083: import com.jgoodies.forms.layout.CellConstraints;
084: import com.jgoodies.forms.layout.FormLayout;
085: import com.projity.help.HelpUtil;
086: import com.projity.menu.HyperLinkToolTip;
087: import com.projity.menu.MenuActionConstants;
088: import com.projity.menu.MenuManager;
089: import com.projity.pm.graphic.frames.DocumentFrame;
090: import com.projity.pm.graphic.frames.GraphicManager;
091: import com.projity.strings.Messages;
092: import com.projity.util.Environment;
093:
094: public class TabbedNavigation implements MenuActionConstants,
095: Serializable {
096: private static final long serialVersionUID = -270788624568075685L;
097: ExtTabbedPane tabbedPane;
098: MenuManager menuManager;
099: ArrayList actions = new ArrayList();
100: int oldSelected = -1;
101: DocumentFrame currentFrame;
102: private JToolBar currentBar = null;
103: private static int eventNum = 0;
104: private JPopupMenu trackingPopup = null;
105:
106: private class ExtTabbedPane extends JTabbedPane {
107: private static final long serialVersionUID = 7993870683783896098L;
108:
109: ExtTabbedPane() {
110: setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
111: final Font normal = new Font("Verdana", 1, 11);
112: setFont(normal);
113: setBorder(BorderFactory.createEmptyBorder());
114:
115: addChangeListener(new ChangeListener() {
116: public void stateChanged(ChangeEvent e) {
117: int i = getSelectedIndex();
118: AbstractAction ac = null;
119: if (oldSelected != -1) {
120: JComponent old = (JComponent) tabbedPane
121: .getComponentAt(oldSelected);
122: if (old instanceof JToolBar)
123: removeFilterToolBar((JToolBar) old);
124: ac = (AbstractAction) actions.get(i);
125: ac.actionPerformed(new ActionEvent(this ,
126: eventNum++, "click"));
127: tabbedPane.setForegroundAt(oldSelected,
128: Color.BLACK);
129: JComponent selectedComponent = (JComponent) tabbedPane
130: .getSelectedComponent();
131: if (selectedComponent instanceof JToolBar)
132: addFilterToolBar((JToolBar) selectedComponent);
133: }
134: tabbedPane.setForegroundAt(i, Color.WHITE);
135: oldSelected = i;
136: }
137:
138: });
139: GraphicManager.getInstance().getLafManager().setUI(this );
140: }
141:
142: public void updateUI() {
143: // ignore it since i set it explicitly in ctor and would give exception when clickin on tab due to fade issue above
144: }
145:
146: }
147:
148: public JComponent createContentPanel(MenuManager menuManager,
149: JToolBar toolbar, int group, int tabPlacement,
150: boolean addFilterButtons) {
151: this .menuManager = menuManager;
152: menuManager.add(this );
153: boolean top = (tabPlacement == JTabbedPane.TOP);
154: int height = top ? 45 : 15;
155: FormLayout layout = new FormLayout("p:grow", "fill:" + height
156: + "dlu:grow");
157: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
158: CellConstraints cc = new CellConstraints();
159: builder.setBorder(BorderFactory.createEmptyBorder());
160: tabbedPane = new ExtTabbedPane();
161: tabbedPane.setTabPlacement(tabPlacement);
162: int tabCount = 0;
163: int groupCount = 0;
164: for (int i = 0; i < toolbar.getComponentCount(); i++) {
165: Object obj = toolbar.getComponent(i);
166: if (obj instanceof JToolbarSeparator)
167: groupCount++;
168: if (!(obj instanceof AbstractButton))
169: continue;
170: if (group != -1 && group != groupCount)
171: continue;
172: AbstractButton b = (AbstractButton) obj;
173: Action action = b.getAction();
174: JComponent component;
175: if (top)
176: component = createSubPanel(action, addFilterButtons);
177: else
178: component = dummy();
179: component.setBorder(BorderFactory.createEmptyBorder());
180: if (Environment.isNewLook() && !Environment.isNewLaf())
181: component.setOpaque(false);
182: String text = HyperLinkToolTip.extractTip(b
183: .getToolTipText());
184: tabbedPane.addTab(text, component);
185: tabbedPane.setToolTipTextAt(tabCount, text); // don't use version with F1
186: actions.add(action);
187: tabCount++;
188: }
189: builder.add(tabbedPane);
190: JComponent c = builder.getPanel();
191: c.setBorder(BorderFactory.createEmptyBorder());
192:
193: return c;
194: }
195:
196: private JPanel dummy() {
197: JPanel dummy = new JPanel();
198: dummy.setSize(dummy.getSize().width, 0);
199:
200: return dummy;
201: }
202:
203: private JComponent createSubPanel(Action action,
204: boolean addFilterButtons) {
205: String toolBarName = null;
206: boolean taskMenu = false;
207: if (action == menuManager.getActionFromId(ACTION_GANTT)) {
208: toolBarName = "GanttToolBar";
209: taskMenu = true;
210: } else if (action == menuManager
211: .getActionFromId(ACTION_TRACKING_GANTT)) {
212: toolBarName = "TrackingGanttToolBar";
213: taskMenu = true;
214: } else if (action == menuManager
215: .getActionFromId(ACTION_TASK_USAGE_DETAIL)) {
216: toolBarName = "TaskUsageDetailToolBar";
217: } else if (action == menuManager
218: .getActionFromId(ACTION_RESOURCE_USAGE_DETAIL)) {
219: toolBarName = "ResourceUsageDetailToolBar";
220: } else if (action == menuManager
221: .getActionFromId(ACTION_NETWORK))
222: toolBarName = "NetworkToolBar";
223: else if (action == menuManager.getActionFromId(ACTION_WBS))
224: toolBarName = "WBSToolBar";
225: else if (action == menuManager.getActionFromId(ACTION_RBS))
226: toolBarName = "RBSToolBar";
227: else if (action == menuManager
228: .getActionFromId(ACTION_RESOURCES))
229: toolBarName = "ResourceToolBar";
230: else if (action == menuManager.getActionFromId(ACTION_REPORT))
231: toolBarName = "ReportToolBar";
232: if (toolBarName == null)
233: return dummy();
234: JToolBar toolBar = menuManager.getToolBar(toolBarName);
235: toolBar.setFloatable(false);
236: if (taskMenu) {
237: toolBar.addSeparator(new Dimension(20, 20));
238: final JComponent tracking = tracking();
239: toolBar.add(tracking);
240:
241: HelpUtil.addDocHelp(tracking, "Tracking_Menu");
242:
243: // toolBar.add(menuManager.getMenu(MenuManager.SF_MENU));
244: }
245: toolBar.addSeparator(new Dimension(40, 20));
246: // String viewName = menuManager.getStringFromAction(action);
247: // if (addFilterButtons)
248: // FilterToolBarManager.getInstance().addButtons(toolBar,menuManager,viewName);
249:
250: return toolBar;
251: }
252:
253: private JComponent tracking() {
254: final JButton p = new JButton(Messages
255: .getString("Spreadsheet.Task.tracking"), IconManager
256: .getIcon("print.down")) {
257: public Point getToolTipLocation(MouseEvent event) { // the tip MUST be touching the button if html because you can click on links
258: if (getToolTipText().startsWith("<html>"))
259: return new Point(0, getHeight() - 2);
260: else
261: return super .getToolTipLocation(event);
262: }
263:
264: public JToolTip createToolTip() {
265: if (getToolTipText().startsWith("<html>")) {
266: JToolTip tip = new HyperLinkToolTip();
267: tip.setComponent(this );
268: return tip;
269: } else {
270: return super .createToolTip();
271: }
272: }
273:
274: };
275:
276: p.setHorizontalTextPosition(AbstractButton.LEADING);
277: String name = "SFTracking";
278: String s = menuManager.getString(name
279: + ButtonFactory.TOOLTIP_SUFFIX);
280: if (s != null) {
281: String help = menuManager.getStringOrNull(name
282: + ButtonFactory.HELP_SUFFIX);
283: String demo = menuManager.getStringOrNull(name
284: + ButtonFactory.DEMO_SUFFIX);
285: String doc = menuManager.getStringOrNull(name
286: + ButtonFactory.DOC_SUFFIX);
287: if (doc != null)
288: s = HyperLinkToolTip.helpTipText(s, help, demo, doc);
289: p.setToolTipText(s);
290: }
291: p.addActionListener(new ActionListener() {
292:
293: public void actionPerformed(ActionEvent e) {
294: if (trackingPopup == null)
295: trackingPopup = menuManager
296: .getPopupMenu("SFTracking");
297: trackingPopup.show(p, 0, p.getHeight());
298: }
299: });
300: return p;
301:
302: }
303:
304: public void setActivatedView(String viewId, boolean enable) {
305: if (!enable)
306: return;
307: int index = indexOfViewId(viewId);
308: if (index != -1 && index != tabbedPane.getSelectedIndex()) {
309: tabbedPane.setSelectedIndex(index);
310: }
311: }
312:
313: private void dumpTabNames() {
314: for (int i = 0; i < tabbedPane.getTabCount(); i++)
315: System.out.println("tab " + i + " title: "
316: + tabbedPane.getTitleAt(i) + "action "
317: + actions.get(i).hashCode());
318: }
319:
320: private int indexOfViewId(String viewId) {
321: Object action = menuManager.getActionFromId(viewId);
322: for (int i = 0; i < tabbedPane.getTabCount(); i++)
323: if (actions.get(i) == action)
324: return i;
325: return -1;
326: }
327:
328: private void addFilterToolBar(JToolBar bar) {
329: if (currentFrame != null) {
330: currentBar = bar;
331: currentFrame.getFilterToolBarManager().addButtons(bar);
332: }
333: }
334:
335: private void removeFilterToolBar(JToolBar bar) {
336: if (currentFrame != null) {
337: currentFrame.getFilterToolBarManager().removeButtons(bar);
338: }
339: }
340:
341: public void setCurrentFrame(DocumentFrame currentFrame) {
342: if (this .currentFrame != null)
343: removeFilterToolBar(currentBar);
344: this .currentFrame = currentFrame;
345: initFilterToolBar();
346: }
347:
348: public void initFilterToolBar() {
349: JComponent selectedComponent = (JComponent) tabbedPane
350: .getSelectedComponent();
351: if (selectedComponent instanceof JToolBar)
352: addFilterToolBar((JToolBar) selectedComponent);
353: }
354:
355: }
|