1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  *
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright(c) 1999 - 2001 by Sun Microsystems, Inc.
26  * All rights reserved.
27  *
28  * pmHelpDetailPanel.java
29  * View a help article
30  */
31 
32 package com.sun.admin.pm.client;
33 
34 import java.awt.*;
35 import java.awt.event.*;
36 import java.util.*;
37 import java.io.*;
38 import java.net.URL;
39 import javax.swing.JPanel;
40 import javax.swing.border.*;
41 import javax.swing.event.*;
42 import javax.swing.*;
43 
44 import com.sun.admin.pm.server.*;
45 
46 class pmHelpLoc {
47     public pmHelpItem item;
48     public Point pos;
49 
pmHelpLoc(pmHelpItem i)50     public pmHelpLoc(pmHelpItem i) {
51         this(i, new Point(0, 0));
52     }
53 
pmHelpLoc(pmHelpItem i, Point p)54     public pmHelpLoc(pmHelpItem i, Point p) {
55         item = i;
56         pos = p;
57     }
58 
pmHelpLoc()59     public pmHelpLoc() {
60         this(null, new Point(0, 0));
61     }
62 }
63 
64 public class pmHelpDetailPanel extends JPanel {
65 
66     pmHelpController controller;
67     pmHelpSeeAlsoPanel seeAlsoPanel;
68     pmHelpViewPanel viewPanel;
69 
70     pmHelpLoc history[];
71     int historyIndex;
72     int historyLast;
73 
74     static final int MAX_HISTORY_ITEMS = 101;
75 
pmHelpDetailPanel(pmHelpController ctrl)76     public pmHelpDetailPanel(pmHelpController ctrl) {
77 
78         controller = ctrl;
79 
80         // build subpanels
81         seeAlsoPanel = new pmHelpSeeAlsoPanel(this);
82         viewPanel = new pmHelpViewPanel(this);
83 
84         // lay out top panel
85         this.setLayout(new GridBagLayout());
86         GridBagConstraints c = new GridBagConstraints();
87 
88         c.insets = new Insets(5, 5, 5, 5);
89 
90         c.gridwidth = GridBagConstraints.REMAINDER;
91 
92         c.gridx = 0;
93         c.gridy = 0;
94 
95         c.gridheight = 2;    // GridBagConstraints.REMAINDER;
96         c.fill = GridBagConstraints.BOTH;
97         c.weightx = 1.0;
98         c.weighty = 6.0;
99         c.insets = new Insets(5, 5, 0, 5);
100         this.add(viewPanel, c);
101 
102         c.gridy = GridBagConstraints.RELATIVE;
103         // c.gridheight = GridBagConstraints.REMAINDER;
104         c.gridheight = 0;
105         c.weighty = 0.0;
106         c.weightx = 1.0;
107         c.fill = GridBagConstraints.BOTH;
108         c.anchor = GridBagConstraints.WEST;
109         c.insets = new Insets(0, 5, 5, 5);
110         this.add(seeAlsoPanel, c);
111 
112         this.setBorder(BorderFactory.createEtchedBorder());
113 
114         history = new pmHelpLoc[MAX_HISTORY_ITEMS];
115         historyIndex = 0;
116         historyLast = 0;
117 
118         // manage focus when we are tabbed or un-tabbed
119         controller.outerPanel.addChangeListener(new ChangeListener() {
120             public void stateChanged(ChangeEvent e) {
121                 JTabbedPane tp = (JTabbedPane) e.getSource();
122                 Debug.info("HELP:  Tab event!");
123                 if (!(tp.getSelectedComponent() instanceof
124                        com.sun.admin.pm.client.pmHelpDetailPanel)) {
125                     Debug.info("HELP:  Tab event: resetting default");
126                     /*
127                      * controller.frame.getRootPane().
128                      * setDefaultButton(
129                      *		controller.frame.dismiss);
130                      */
131                     if (controller.frame.dismiss != null)
132                         controller.frame.dismiss.
133                             setAsDefaultButton();
134                 }
135             }
136         });
137 
138         addFocusListener(new FocusAdapter() {
139             public void focusGained(FocusEvent e) {
140                 Debug.info("HELP:  detailPanel gained focus");
141                 if (controller.frame.dismiss != null)
142                     controller.frame.dismiss.
143                         setAsDefaultButton();
144 
145             }
146         });
147     }
148 
149     // ask parent controller to show item
showItem(String tag)150     public void showItem(String tag) {
151         controller.showHelpItem(tag);
152     }
153 
showHistoryBackItem()154     public void showHistoryBackItem() {
155         Debug.message("HELP:  showHistoryBackItem: index = " +
156                       historyIndex + " last = " +
157                       historyLast +
158                       "\n\thistory = " +
159                       history);
160 
161         // assuming item already visible, preserve its position
162         history[historyIndex].pos = viewPanel.getPos();
163 
164         Debug.info("back: pos is " + history[historyIndex].pos);
165 
166         if (historyIndex > 1) {
167             pmHelpLoc l = history [--historyIndex];
168             pmHelpItem item = l.item;
169             Point p = l.pos;
170             loadItem(item, p);
171         }
172         viewPanel.setNavButtons(historyIndex, historyLast);
173     }
174 
showHistoryForwardItem()175     public void showHistoryForwardItem() {
176         Debug.message("HELP:  showHistoryForwardItem: index = " +
177                       historyIndex +
178                       " last = " + historyLast +
179                       "\n\thistory = " + history);
180 
181         // assuming already an item visible, preserve its position
182         history[historyIndex].pos = viewPanel.getPos();
183 
184         Debug.info("HELP:  fwd: pos is " + history[historyIndex].pos);
185 
186         if (historyIndex < historyLast) {
187             pmHelpLoc l = history [++historyIndex];
188             pmHelpItem item = l.item;
189             Point p = l.pos;
190             loadItem(item, p);
191         }
192         viewPanel.setNavButtons(historyIndex, historyLast);
193     }
194 
195 
196     /*
197      * load the help item
198      * internal
199      */
loadItem(pmHelpItem item)200     protected pmHelpItem loadItem(pmHelpItem item) {
201         return loadItem(item, new Point(0, 0));
202     }
203 
loadItem(pmHelpItem item, Point pos)204     protected pmHelpItem loadItem(pmHelpItem item, Point pos) {
205         Debug.message("HELP:  View: loadItem " + item.tag);
206         seeAlsoPanel.setItems(item.seealso);
207 
208         Debug.info("loadItem: pos is " + pos);
209 
210         viewPanel.setItem(item.title, item.content);
211         viewPanel.setPos(pos);
212         return item;
213     }
214 
215 
216     /*
217      * load the help item corresponding to the specified tag
218      * external - called from helpController
219      *		note that this is how see-also items are loadedes
220      */
loadItemForTag(String tag)221     public pmHelpItem loadItemForTag(String tag) {
222 
223         pmHelpItem item;
224 
225         if (tag == null ||
226             (item = pmHelpRepository.helpItemForTag(tag)) == null) {
227             Debug.warning("HELP:  View: item not found");
228             loadEmptyItem(tag);
229             return null;
230         }
231 
232         Debug.info("loadItem(before): index = " + historyIndex +
233                    ", last = " + historyLast);
234 
235         // if there's already an item visible, preserve its position
236         if (historyIndex != 0 && historyLast != 0)
237             history[historyIndex].pos = viewPanel.getPos();
238 
239         loadItem(item);
240 
241         Debug.info("HELP:  loadItemForTag: index = " + historyIndex +
242                    " last = " + historyLast + "\n\thistory = " +
243                    history);
244 
245         /*
246          * make the new item the latest in history.
247          * if the history length is maxed out, the new item
248          * will replace the item that's currently last.
249          */
250 
251         if (historyIndex < history.length - 1) {
252             // init pos to 0,0
253             history [++historyIndex] = new pmHelpLoc(item);
254         } else {
255             // replace last item
256             history [historyIndex] = new pmHelpLoc(item);
257         }
258         historyLast = historyIndex;
259 
260         viewPanel.setNavButtons(historyIndex, historyLast);
261 
262         Debug.info("loadItem(after): index = " + historyIndex +
263                    ", last = " + historyLast);
264         return item;
265     }
266 
loadEmptyItem(String itm)267     private void loadEmptyItem(String itm) {
268         String msg = new String(
269             pmUtility.getResource("Item.not.found:") + itm);
270         viewPanel.setItem(msg, new pmHelpContent(
271             pmUtility.getResource("No.information.available.")));
272         seeAlsoPanel.setItems(null);
273     }
274 
275 }
276 
277 
278 
279 class pmHelpSeeAlsoPanel extends JPanel {
280 
281     pmHelpDetailPanel parentPanel = null;
282     Vector seeAlsoItems = null;
283     JComboBox theComboBox = null;
284     pmButton selectButton = null;
285 
layoutBox()286     private void layoutBox() {
287 
288         JPanel p = new JPanel();
289         p.setLayout(new BorderLayout(5, 0));
290 
291         p.add(new JPanel(), "North");
292         p.add(new JPanel(), "South");
293 
294         p.add(new JLabel(
295             pmUtility.getResource("See.also:")), "West");
296 
297         theComboBox = new JComboBox();
298 
299         Font f = theComboBox.getFont();
300         Font fb = new Font(f.getName(), f.PLAIN, f.getSize());
301         theComboBox.setFont(fb);
302 
303         theComboBox.setPreferredSize(
304             new Dimension(200, theComboBox.getPreferredSize().height));
305         theComboBox.setMinimumSize(
306             new Dimension(20, theComboBox.getPreferredSize().height));
307         theComboBox.setMaximumSize(
308             new Dimension(300, theComboBox.getPreferredSize().height));
309         theComboBox.setEnabled(false);
310 
311 	/*
312 	 * theComboBox.addActionListener(new ActionListener() {
313 	 *    public void actionPerformed(ActionEvent e) {
314 	 *	JComboBox src = (JComboBox) e.getSource();
315 	 *	System.out.println("Combo: action = " +
316 	 *			e.getActionCommand());
317 	 *	System.out.println("Combo: mod = " +
318 	 *			e.getModifiers());
319 	 *	System.out.println("Combo: param = " +
320 	 *			e.paramString());
321 	 *	System.out.println("Combo: item = " +
322 	 *			src.getSelectedItem());
323 	 *    }
324 	 * });
325 	 */
326 
327         p.add(theComboBox, "Center");
328 
329         selectButton = new pmButton(
330             pmUtility.getResource("Show"));
331         selectButton.setMnemonic(
332             pmUtility.getIntResource("Show.mnemonic"));
333         selectButton.setEnabled(false);
334 
335         p.add(selectButton, "East");
336         selectButton.addActionListener(new ActionListener() {
337             public void actionPerformed(ActionEvent e) {
338                 pmHelpItem i = (pmHelpItem) theComboBox.getSelectedItem();
339                 Debug.message("HELP:  got button: item is " + i);
340                 // parentPanel.loadItemForTag(i.tag);
341                 parentPanel.showItem(i.tag);
342             }
343         });
344 
345         JPanel pp = new JPanel();
346         pp.setLayout(new BorderLayout(5, 0));
347         pp.add(p, "Center");
348 
349         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
350         this.add(Box.createHorizontalStrut(10));
351         this.add(pp);
352         this.add(Box.createHorizontalStrut(10));
353         this.add(Box.createHorizontalGlue());
354 
355     }
356 
pmHelpSeeAlsoPanel(pmHelpDetailPanel p)357     public pmHelpSeeAlsoPanel(pmHelpDetailPanel p) {
358         parentPanel = p;
359         layoutBox();
360         this.setBorder(BorderFactory.createEtchedBorder());
361     }
362 
363 
364     /*
365      * set the titles of the pmHelpItems whose tags are
366      * passed into see-also combo box
367      */
setItems(Vector tags)368     public void setItems(Vector tags) {
369         clearItems();
370 
371         if (tags == null)
372             return;
373 
374         Enumeration e = tags.elements();
375         while (e.hasMoreElements()) {
376             pmHelpItem i =
377                 pmHelpRepository.helpItemForTag((String) e.nextElement());
378             if (i != null)
379                 theComboBox.addItem(i);
380         }
381 
382         selectButton.setEnabled(true);
383         theComboBox.setEnabled(true);
384 
385 
386         // repaint();
387     }
388 
389 
clearItems()390     public void clearItems() {
391         if (theComboBox.getItemCount() > 0)
392             theComboBox.removeAllItems();
393         selectButton.setEnabled(false);
394         theComboBox.setEnabled(false);
395     }
396 
397 }
398 
399 
400 class pmHelpViewPanel extends JPanel {
401     // JTextArea helpView;
402     JEditorPane helpView;
403     JScrollPane scrollPane;
404     pmHelpHelpOnPanel titlePanel;
405     pmHelpDetailPanel parentPanel;
406     pmButton backButton;
407     pmButton forwardButton;
408 
pmHelpViewPanel(pmHelpDetailPanel par)409     public pmHelpViewPanel(pmHelpDetailPanel par) {
410         parentPanel = par;
411 
412         // helpView = new JTextArea(10, 32);
413         // helpView.setLineWrap(true);
414 
415         helpView = new JEditorPane();
416 
417         helpView.setContentType("text/html");
418         helpView.setEditable(false);
419         helpView.setEnabled(false);
420         helpView.setDisabledTextColor(Color.blue);
421 
422         scrollPane = new JScrollPane(helpView);
423 
424         this.setLayout(new GridBagLayout());
425         GridBagConstraints c = new GridBagConstraints();
426         c.insets = new Insets(5, 10, 5, 10);
427         c.gridwidth = GridBagConstraints.REMAINDER;
428 
429         c.gridx = 0;
430         c.gridy = 0;
431 
432         c.gridheight = 1;
433         c.fill = GridBagConstraints.HORIZONTAL;
434         c.weightx = 1.0;
435         // c.weighty = 1.0;
436         c.weighty = 0.05;
437 
438         titlePanel = new pmHelpHelpOnPanel();
439         this.add(titlePanel, c);
440 
441         c.gridy = 1;
442         c.gridheight = 1;
443 
444         c.gridwidth = GridBagConstraints.REMAINDER;
445         c.weightx = 1.0;
446         c.weighty = 6.0;
447         c.fill = GridBagConstraints.BOTH;
448         c.insets = new Insets(5, 10, 5, 10);
449         // c.insets = new Insets(5, 5, 5, 5); // NEW
450         this.add(scrollPane, c);
451 
452         this.setBorder(BorderFactory.createEtchedBorder());
453 
454         /*
455          */
456         try {
457             helpView.setPage(new URL("file:///test.html"));
458         } catch (Exception x) {
459             Debug.info("setPage caught: " + x);
460         }
461         /*
462          */
463 
464         // navigation buttons
465         JPanel p = new JPanel();
466         p.setLayout(new GridBagLayout());
467         GridBagConstraints pc = new GridBagConstraints();
468         // pc.insets = new Insets(2, 2, 2, 2);
469         // pc.fill = GridBagConstraints.HORIZONTAL;
470         pc.weightx = 1.0;
471         pc.weighty = 1.0;
472         pc.gridx = 0;
473         pc.anchor = GridBagConstraints.WEST;
474 
475         backButton = new pmButton(
476             pmUtility.getResource("Back"));
477         backButton.setMnemonic(
478             pmUtility.getIntResource("Back.mnemonic"));
479         p.add(backButton, pc);
480         backButton.setEnabled(false);
481         backButton.setDefaultCapable(false);
482         backButton.addActionListener(new  ActionListener() {
483             public void actionPerformed(ActionEvent e) {
484                 parentPanel.showHistoryBackItem();
485             }
486         });
487 
488 
489         pc.gridx = 1;
490         pc.anchor = GridBagConstraints.EAST;
491 
492         forwardButton = new pmButton(
493             pmUtility.getResource("Forward"));
494         forwardButton.setMnemonic(
495             pmUtility.getIntResource("Forward.mnemonic"));
496         p.add(forwardButton, pc);
497         forwardButton.setEnabled(false);
498         forwardButton.setDefaultCapable(false);
499         forwardButton.addActionListener(new  ActionListener() {
500             public void actionPerformed(ActionEvent e) {
501                 parentPanel.showHistoryForwardItem();
502             }
503         });
504 
505         c.gridy = GridBagConstraints.RELATIVE;
506         c.gridheight = 1;    // GridBagConstraints.REMAINDER;
507         c.gridwidth = GridBagConstraints.REMAINDER;
508         c.weightx = 1.0;
509         // c.weighty = 1.0;
510 	c.weighty = 0.05;	// NEW
511 
512         c.fill = GridBagConstraints.BOTH;
513         c.insets = new Insets(0, 10, 5, 10);
514         // c.insets = new Insets(0, 10, 5, 10);
515         c.insets = new Insets(5, 10, 5, 10);
516         // NEW
517 
518         add(p, c);
519 
520     }
521 
522 
setItem(String title, pmHelpContent content)523     public void setItem(String title, pmHelpContent content) {
524         helpView.setText(content.getText());
525         // scrollPane.getViewport().setViewPosition(new Point(0, 0));
526         titlePanel.helpTopic.setText(title);
527     }
528 
setPos(Point p)529     public void setPos(Point p) {
530         scrollPane.getViewport().setViewPosition(p);
531     }
532 
getPos()533     public Point getPos() {
534         return scrollPane.getViewport().getViewPosition();
535     }
536 
setNavButtons(int index, int last)537     public void setNavButtons(int index, int last) {
538         Debug.message("HELP:  NavButtons " + index + " " + last);
539 
540         if (last > index)
541             forwardButton.setEnabled(true);
542         else
543             forwardButton.setEnabled(false);
544 
545         if (index > 1 && last > 1)
546             backButton.setEnabled(true);
547         else
548             backButton.setEnabled(false);
549     }
550 
551 }
552 
553 
554 class pmJTextField extends JTextField {
isFocusable()555     public boolean isFocusable() {
556         return false;
557     }
558 }
559 
560 class pmHelpHelpOnPanel extends JPanel {
561 
562     pmJTextField helpTopic;
563 
pmHelpHelpOnPanel()564     public  pmHelpHelpOnPanel() {
565 
566         helpTopic = new pmJTextField();
567         helpTopic.setEditable(false);
568         helpTopic.setText("Default help topic");
569         helpTopic.setBackground(Color.white);
570 
571         Font f = helpTopic.getFont();
572         Font fb = new Font(f.getName(), Font.BOLD, f.getSize());
573         helpTopic.setFont(fb);
574 
575         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
576         JPanel p = new JPanel();
577         p.setLayout(new BorderLayout(5, 0));
578         p.add(new JLabel(
579             pmUtility.getResource("Help.on:")),
580               "West");
581         p.add(helpTopic, "Center");
582 
583         JPanel pp = new JPanel();
584         pp.setLayout(new BorderLayout(0, 0));
585         pp.add(p, "Center");
586 
587         // this.add(Box.createHorizontalStrut(5));
588         this.add(pp);
589         // this.add(Box.createHorizontalStrut(5));
590         this.add(Box.createHorizontalGlue());
591 
592 
593         // this.setBorder(BorderFactory.createEtchedBorder());
594 
595     }
596 
597 }
598