Merge remote-tracking branch 'origin/5.5'
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / tab / SwingScilabDockablePanel.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007-2008 - INRIA - Vincent Couvert
4  * Copyright (C) 2007 - INRIA - Bruno JOFRET
5  * Copyright (C) 2007 - INRIA - Marouane BEN JELLOUL
6  * Copyright (C) 2011 - DIGITEO - Vincent Couvert
7  * Copyright (C) 2014 - Scilab Enterprises - Bruno JOFRET
8  *
9  * This file must be used under the terms of the CeCILL.
10  * This source file is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution.  The terms
12  * are also available at
13  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
14  *
15  */
16
17 package org.scilab.modules.gui.bridge.tab;
18
19 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_AUTORESIZE__;
20 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_AXES_SIZE__;
21 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_CLOSEREQUESTFCN__;
22 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_POSITION__;
23 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.__GO_SIZE__;
24
25 import java.awt.Color;
26 import java.awt.Component;
27 import java.awt.Container;
28 import java.awt.Dimension;
29 import java.awt.Graphics;
30 import java.awt.Image;
31 import java.awt.event.ComponentEvent;
32 import java.awt.event.ComponentListener;
33 import java.awt.event.FocusEvent;
34 import java.awt.event.FocusListener;
35 import java.awt.event.HierarchyBoundsListener;
36 import java.awt.event.HierarchyEvent;
37 import java.awt.event.KeyEvent;
38 import java.awt.event.KeyListener;
39 import java.lang.reflect.InvocationTargetException;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.ListIterator;
43
44 import javax.swing.Action;
45 import javax.swing.ImageIcon;
46 import javax.swing.JLayeredPane;
47 import javax.swing.JTextPane;
48 import javax.swing.KeyStroke;
49 import javax.swing.SwingUtilities;
50
51 import org.flexdock.docking.DockingConstants;
52 import org.flexdock.docking.DockingManager;
53 import org.flexdock.docking.DockingPort;
54 import org.flexdock.docking.activation.ActiveDockableTracker;
55 import org.flexdock.docking.event.DockingEvent;
56 import org.flexdock.docking.props.PropertyChangeListenerFactory;
57 import org.flexdock.view.Titlebar;
58 import org.flexdock.view.View;
59 import org.scilab.modules.action_binding.InterpreterManagement;
60 import org.scilab.modules.commons.ScilabConstants;
61 import org.scilab.modules.commons.gui.FindIconHelper;
62 import org.scilab.modules.graphic_objects.figure.Figure;
63 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
64 import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
65 import org.scilab.modules.gui.SwingViewObject;
66 import org.scilab.modules.gui.SwingViewWidget;
67 import org.scilab.modules.gui.bridge.canvas.SwingScilabCanvas;
68 import org.scilab.modules.gui.bridge.console.SwingScilabConsole;
69 import org.scilab.modules.gui.bridge.helpbrowser.SwingScilabHelpBrowser;
70 import org.scilab.modules.gui.bridge.menubar.SwingScilabMenuBar;
71 import org.scilab.modules.gui.bridge.popupmenu.SwingScilabPopupMenu;
72 import org.scilab.modules.gui.bridge.pushbutton.SwingScilabPushButton;
73 import org.scilab.modules.gui.bridge.radiobutton.SwingScilabRadioButton;
74 import org.scilab.modules.gui.bridge.slider.SwingScilabScroll;
75 import org.scilab.modules.gui.bridge.tree.SwingScilabTree;
76 import org.scilab.modules.gui.bridge.uidisplaytree.SwingScilabUiDisplayTree;
77 import org.scilab.modules.gui.bridge.uitable.SwingScilabUiTable;
78 import org.scilab.modules.gui.bridge.window.SwingScilabWindow;
79 import org.scilab.modules.gui.canvas.Canvas;
80 import org.scilab.modules.gui.console.Console;
81 import org.scilab.modules.gui.console.ScilabConsole;
82 import org.scilab.modules.gui.dockable.Dockable;
83 import org.scilab.modules.gui.editor.EditorEventListener;
84 import org.scilab.modules.gui.events.GlobalEventWatcher;
85 import org.scilab.modules.gui.events.ScilabEventListener;
86 import org.scilab.modules.gui.events.callback.CommonCallBack;
87 import org.scilab.modules.gui.helpbrowser.HelpBrowser;
88 import org.scilab.modules.gui.menubar.MenuBar;
89 import org.scilab.modules.gui.tab.SimpleTab;
90 import org.scilab.modules.gui.textbox.TextBox;
91 import org.scilab.modules.gui.toolbar.ToolBar;
92 import org.scilab.modules.gui.tree.Tree;
93 import org.scilab.modules.gui.uidisplaytree.UiDisplayTree;
94 import org.scilab.modules.gui.utils.BarUpdater;
95 import org.scilab.modules.gui.utils.ClosingOperationsManager;
96 import org.scilab.modules.gui.utils.Position;
97 import org.scilab.modules.gui.utils.SciClosingAction;
98 import org.scilab.modules.gui.utils.SciHelpOnComponentAction;
99 import org.scilab.modules.gui.utils.SciUndockingAction;
100 import org.scilab.modules.gui.utils.Size;
101 import org.scilab.modules.gui.widget.Widget;
102
103 /**
104  * Swing implementation for Scilab tabs in GUIs This implementation uses
105  * FlexDock package
106  * @author Bruno JOFRET
107  * @author Vincent COUVERT
108  * @author Marouane BEN JELLOUL
109  * @author Jean-Baptiste SILVY
110  */
111
112 public class SwingScilabDockablePanel extends View implements SimpleTab, FocusListener, KeyListener, SwingScilabPanel {
113
114     private static final Image SCILAB_ICON = new ImageIcon(FindIconHelper.findIcon("scilab", "256x256")).getImage();
115
116     private static final long serialVersionUID = 1L;
117
118     private static final String UNDOCK = "undock";
119     private static final String HELP = "help";
120     protected boolean hasLayout = false;
121
122     private Integer id;
123
124     private boolean eventEnabled = false;
125     ComponentListener componentListener;
126
127     static {
128         PropertyChangeListenerFactory.addFactory(new BarUpdater.UpdateBarFactory());
129     }
130
131     private String parentWindowId;
132     private MenuBar menuBar;
133     private ToolBar toolBar;
134     private TextBox infoBar;
135     private String helpID;
136     private boolean paintEnable = true;
137
138     /** Contains the canvas and widgets */
139     private JLayeredPane uiContentPane;
140     private JLayeredPane layeredPane;
141
142     /** Scroll the axes */
143     private SwingScilabScrollPane scrolling;
144
145     private Image icon;
146
147     private Action closeAction;
148
149     /** The listener for event handling */
150     private ScilabEventListener eventHandler;
151     private EditorEventListener editorEventHandler = null;
152
153     /** A reference to the canvas used for event handling management */
154     private SwingScilabCanvas contentCanvas = null;
155
156     private Dimension deltaSize = null;
157
158     /**
159      * Constructor
160      * @param name the name of the tab
161      * @param uuid an uuid to identify the tab
162      */
163     public SwingScilabDockablePanel(String name, String uuid) {
164         super(uuid, name, name);
165         //This button is "overloaded" when we add a callback
166         //this.addAction(DockingConstants.CLOSE_ACTION);
167         // Removed because make JOGL crash when "Unpin"
168         //this.addAction(DockingConstants.PIN_ACTION);
169         this.addAction(DockingConstants.ACTIVE_WINDOW);
170
171         // no need for an axes
172         contentPane = null;
173         uiContentPane = null;
174         scrolling = null;
175
176         this.setVisible(true);
177
178         getTitlebar().addFocusListener(this);
179         addFocusListener(this);
180         setCallback(null);
181
182         getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("shift F6"), ACTION_TOGGLE_PREVIOUS);
183     }
184
185     /**
186      * Create a graphic tab used to display a figure with 3D graphics and/or
187      * UIcontrols
188      * @param name name of the tab
189      * @param figureId id of the displayed figure
190      */
191     public SwingScilabDockablePanel(String name, int figureId) {
192         super(name, name, name);
193
194         // This button is "overloaded" when we add a callback
195         //this.addAction(DockingConstants.CLOSE_ACTION);
196         // Removed because make JOGL crash when "Unpin"
197         //this.addAction(DockingConstants.PIN_ACTION);
198         this.addAction(DockingConstants.ACTIVE_WINDOW);
199
200         // create the panel in which all the uiobjects will lie.
201         //contentPane = new SwingScilabAxes(figureId);
202
203         // add it inside a JSCrollPane
204         //scrolling = new SwingScilabScrollPane(contentPane);
205         //scrolling.setBackground(1, 0, 0);
206         // put in in the back of the tab
207         //setContentPane(scrolling.getAsContainer());
208
209         this.setVisible(true);
210
211         getTitlebar().addFocusListener(this);
212         addFocusListener(this);
213         setCallback(null);
214
215         getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("shift F6"), ACTION_TOGGLE_PREVIOUS);
216     }
217
218     /**
219      * Constructor
220      * @param name the name of the tab (used to identify it)
221      */
222     public SwingScilabDockablePanel(String name) {
223         this(name, name);
224     }
225
226     /**
227      * Set the associated help page
228      * @param helpID the xml id of the associated help page
229      */
230     public void setAssociatedXMLIDForHelp(String helpID) {
231         this.helpID = helpID;
232     }
233
234     /**
235      * Get the associated help page
236      * @return the xml id of the associated help page
237      */
238     public String getAssociatedXMLIDForHelp() {
239         return helpID;
240     }
241
242     public static void removeActions(SwingScilabDockablePanel tab) {
243         tab.setActionBlocked(DockingConstants.CLOSE_ACTION, true);
244         tab.setActionBlocked(UNDOCK, true);
245         if (tab.getTitlebar() != null) {
246             tab.getTitlebar().revalidate();
247         }
248     }
249
250     public static void addActions(SwingScilabDockablePanel tab) {
251         tab.setActionBlocked(DockingConstants.CLOSE_ACTION, false);
252         tab.setActionBlocked(UNDOCK, false);
253         tab.getTitlebar().revalidate();
254     }
255
256     public SwingScilabDockablePanel(String figureTitle, int figureId, final Figure figure) {
257         this(figureTitle, figureId);
258         /* OpenGL context */
259         //SwingScilabCanvas canvas = new SwingScilabCanvas(figureId, figure);
260         //contentCanvas = canvas;
261
262         editorEventHandler = new EditorEventListener(figure.getIdentifier());
263
264         layeredPane = new JLayeredPane();
265         layeredPane.setLayout(null);
266         layeredPane.setBorder(null);
267         layeredPane.setOpaque(true);
268
269         uiContentPane = new JLayeredPane();
270         uiContentPane.setOpaque(false);
271         uiContentPane.setLayout(null);
272         uiContentPane.setBorder(null);
273
274         layeredPane.add(uiContentPane, JLayeredPane.DEFAULT_LAYER + 1, 0);
275         scrolling = new SwingScilabScrollPane(layeredPane, uiContentPane, figure);
276
277         setContentPane(scrolling.getAsContainer());
278
279         uiContentPane.setVisible(true);
280
281         /* Manage figure_position property */
282         addHierarchyBoundsListener(new HierarchyBoundsListener() {
283             public void ancestorResized(HierarchyEvent arg0) {
284             }
285
286             public void ancestorMoved(HierarchyEvent e) {
287                 if (e.getChanged() instanceof SwingScilabWindow) {
288                     Position parentPosition = SwingScilabWindow.allScilabWindows.get(parentWindowId).getPosition();
289                     Integer[] newPosition = new Integer[] { parentPosition.getX(), parentPosition.getY() };
290                     GraphicController.getController().setProperty(id, __GO_POSITION__, newPosition);
291                 }
292             }
293         });
294
295         /* Manage figure_size property */
296         componentListener = new ComponentListener() {
297             public void componentShown(ComponentEvent arg0) {
298             }
299
300             public void componentResized(ComponentEvent arg0) {
301
302                 /* Update the figure_size property */
303                 Size parentSize = SwingScilabWindow.allScilabWindows.get(parentWindowId).getDims();
304                 Integer[] newSize = new Integer[] { parentSize.getWidth(), parentSize.getHeight() };
305
306                 GraphicController.getController().setProperty(id, __GO_SIZE__, newSize);
307
308                 Boolean autoResize = (Boolean) GraphicController.getController().getProperty(id, __GO_AUTORESIZE__);
309
310                 if (autoResize != null && autoResize) {
311                     /* Update the axes_size property */
312                     Integer[] newAxesSize = new Integer[] { getContentPane().getWidth(), getContentPane().getHeight() };
313                     GraphicController.getController().setProperty(id, __GO_AXES_SIZE__, newAxesSize);
314                 }
315
316                 String resizeFcn = (String) GraphicController.getController().getProperty(id, GraphicObjectProperties.__GO_RESIZEFCN__);
317                 if (resizeFcn != null && !resizeFcn.equals("")) {
318                     String resizeCommand = "if exists(\"gcbo\") then %oldgcbo = gcbo; end;" + "gcbo = getcallbackobject(" + id + ");" + resizeFcn
319                                            + ";if exists(\"%oldgcbo\") then gcbo = %oldgcbo; else clear gcbo; end;";
320                     InterpreterManagement.requestScilabExec(resizeCommand);
321                 } else if (hasLayout == false) {
322                     for (Component comp : getWidgetPane().getComponents()) {
323                         if (comp instanceof Widget) {
324                             Widget widget = (Widget) comp;
325                             SwingViewObject obj = (SwingViewObject) comp;
326                             SwingViewWidget.update(widget, __GO_POSITION__, GraphicController.getController().getProperty(obj.getId(), __GO_POSITION__));
327                         }
328                     }
329                 }
330             }
331
332             public void componentMoved(ComponentEvent arg0) {
333             }
334
335             public void componentHidden(ComponentEvent arg0) {
336             }
337         };
338
339         addComponentListener(componentListener);
340         /* Manage closerequestfcn */
341         ClosingOperationsManager.registerClosingOperation(SwingScilabDockablePanel.this, new ClosingOperationsManager.ClosingOperation() {
342
343             public int canClose() {
344                 String closeRequestFcn = (String) GraphicController.getController().getProperty(getId(), __GO_CLOSEREQUESTFCN__);
345                 if (!closeRequestFcn.equals("")) {
346                     String closeCommand = "if exists(\"gcbo\") then %oldgcbo = gcbo; end;"
347                                           + "gcbo = getcallbackobject(" + getId() + ");"
348                                           + closeRequestFcn + ";fire_closing_finished();"
349                                           + ";if exists(\"%oldgcbo\") then gcbo = %oldgcbo; else clear gcbo; end;";
350                     InterpreterManagement.putCommandInScilabQueue(closeCommand);
351                     return -1;
352                 } else {
353                     closeAction.actionPerformed(null);
354                     return 1;
355                 }
356             }
357
358             public void destroy() {
359             }
360
361             public String askForClosing(final List<SwingScilabDockablePanel> list) {
362                 return null;
363             }
364
365             @Override
366             public void updateDependencies(List<SwingScilabDockablePanel> list, ListIterator<SwingScilabDockablePanel> it) {
367
368             }
369         });
370         ClosingOperationsManager.addDependencyWithRoot(this);
371     }
372
373     /**
374      * @param e the FocusEvent
375      */
376     @Override
377     public void focusGained(FocusEvent e) {
378         //ActiveDockableTracker.requestDockableActivation(this);
379         if (contentPane != null) {
380             contentPane.requestFocus();
381         } else if (getContentPane() != null) {
382             getContentPane().requestFocus();
383         } else {
384             SwingScilabDockablePanel.this.requestFocusInWindow();
385         }
386     }
387
388     /**
389      * Call when the tab restoration is ended.
390      */
391     public void endedRestoration() {
392     }
393
394     /**
395      * @return the window icon associated with this tab
396      */
397     public Image getWindowIcon() {
398         if (icon == null) {
399             return SCILAB_ICON;
400         } else {
401             return icon;
402         }
403     }
404
405     /**
406      * @param icon the window icon associated with this tab
407      */
408     public void setWindowIcon(Image icon) {
409         this.icon = icon;
410     }
411
412     /**
413      * @param iconName window icon associated with this tab
414      */
415     public void setWindowIcon(String iconName) {
416         setWindowIcon(new ImageIcon(FindIconHelper.findIcon(iconName, "256x256")).getImage());
417     }
418
419     /**
420      * @param e the FocusEvent
421      */
422     @Override
423     public void focusLost(FocusEvent e) {
424     }
425
426     /**
427      * {@inheritDoc}
428      */
429     @Override
430     public void dockingComplete(DockingEvent evt) {
431         super.dockingComplete(evt);
432
433         DockingPort port = evt.getNewDockingPort();
434         SwingScilabWindow win = (SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, (Component) port);
435         Iterator iter = port.getDockables().iterator();
436
437         if (port.getDockables().size() > 1) {
438             while (iter.hasNext()) {
439                 Object d = iter.next();
440                 if (d instanceof SwingScilabDockablePanel) {
441                     SwingScilabDockablePanel view = (SwingScilabDockablePanel) d;
442                     addActions(view);
443                 }
444             }
445         } else {
446             removeActions(this);
447         }
448
449         if (win != null) {
450             setParentWindowId(win.getId());
451         } else {
452             // Should not occur
453             SwingUtilities.invokeLater(new Runnable() {
454                 public void run() {
455                     if (getParentWindow() != null) {
456                         setParentWindowId(getParentWindow().getId());
457                     } else {
458                         System.err.println("No window for tab:" + SwingScilabDockablePanel.this.getClass().getName() + " after docking complete");
459                     }
460                 }
461             });
462         }
463     }
464
465     /**
466      * Sets the Name of a swing Scilab tab
467      * @param newTabName the Name of the tab
468      * @see org.scilab.modules.gui.tab.ScilabTab#setName(String)
469      */
470     @Override
471     public void setName(String newTabName) {
472         setTitle(newTabName, true);
473         getTitlePane().repaint();
474         SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this).setName(newTabName);
475     }
476
477     /**
478      * @return the UUID of the parent window
479      */
480     public String getParentWindowUUID() {
481         return ((SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this)).getUUID();
482     }
483
484     /**
485      * @return the UUID of the parent window
486      */
487     public SwingScilabWindow getParentWindow() {
488         return (SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, this);
489     }
490
491     /**
492      * Gets the title of a swing Scilab tab
493      * @return the title of the tab
494      * @see org.scilab.modules.gui.tab.ScilabTab#getName()
495      */
496     @Override
497     public String getName() {
498         return this.getTitle();
499     }
500
501     /**
502      * Paint immediately this component
503      */
504     public void paintImmediately() {
505         // paint all
506         paintImmediately(0, 0, getWidth(), getHeight());
507     }
508
509     /**
510      * Draws a swing Scilab tab
511      * @see org.scilab.modules.gui.uielement.UIElement#draw()
512      */
513     @Override
514     public void draw() {
515         if (SwingUtilities.isEventDispatchThread()) {
516             setVisible(true);
517             paintImmediately();
518         } else {
519             try {
520                 SwingUtilities.invokeAndWait(new Runnable() {
521                     @Override
522                     public void run() {
523                         setVisible(true);
524                         paintImmediately();
525                     }
526                 });
527             } catch (InterruptedException e) {
528                 e.printStackTrace();
529             } catch (InvocationTargetException e) {
530                 e.printStackTrace();
531             }
532         }
533
534     }
535
536     /**
537      * Gets the dimensions (width and height) of a swing Scilab tab
538      * @return the dimensions of the tab
539      * @see org.scilab.modules.gui.uielement.UIElement#getDims()
540      */
541     @Override
542     public Size getDims() {
543         return new Size(this.getSize().width, this.getSize().height);
544     }
545
546     /**
547      * Get the size for the axes
548      * @return size of the axes in pixels
549      */
550     @Override
551     public Size getAxesSize() {
552         return new Size(contentPane.getWidth(), contentPane.getHeight());
553     }
554
555     /**
556      * @param newSize new size to set for the axes
557      */
558     @Override
559     public void setAxesSize(Size newSize) {
560         contentPane.setSize(new Dimension(newSize.getWidth(), newSize.getHeight()));
561         uiContentPane.setSize(new Dimension(newSize.getWidth(), newSize.getHeight()));
562     }
563
564     /**
565      * Gets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
566      * @return the position of the tab
567      * @see org.scilab.modules.gui.uielement.UIElement#getPosition()
568      */
569     @Override
570     public Position getPosition() {
571         return new Position(this.getX(), this.getY());
572     }
573
574     /**
575      * Sets the dimensions (width and height) of a swing Scilab tab
576      * @param newSize the dimensions we want to set to the tab
577      * @see org.scilab.modules.gui.uielement.UIElement#setDims(org.scilab.modules.gui.utils.Size)
578      */
579     @Override
580     public void setDims(Size newSize) {
581         this.setSize(newSize.getWidth(), newSize.getHeight());
582     }
583
584     /**
585      * Sets the position (X-coordinate and Y-coordinate) of a swing Scilab tab
586      * @param newPosition the position we want to set to the tab
587      * @see org.scilab.modules.gui.uielement.UIElement#setPosition(org.scilab.modules.gui.utils.Position)
588      */
589     @Override
590     public void setPosition(Position newPosition) {
591         this.setLocation(newPosition.getX(), newPosition.getY());
592     }
593
594     /**
595      * Add a member (dockable element) to container and returns its index
596      * @param member the member to add
597      * @return index of member in ArrayList
598      */
599     @Override
600     public int addMember(Canvas member) {
601         return 0;
602     }
603
604     /**
605      * We want to be able to remove directly a Canvas from a Tab.
606      * @param member canvas to remove
607      */
608     @Override
609     public void removeMember(Canvas member) {
610     }
611
612     /**
613      * Add a SwingViewObject (from SwingView.java) to container and returns its
614      * index
615      * @param member the member to add
616      */
617     public void addMember(SwingViewObject member) {
618         if (member instanceof SwingScilabAxes) {
619             if (contentCanvas == null) {
620                 contentCanvas = new SwingScilabCanvas((Figure) GraphicController.getController().getObjectFromId(((SwingScilabAxes) member).getFigureId()));
621                 contentCanvas.addEventHandlerKeyListener(editorEventHandler);
622                 contentCanvas.addEventHandlerMouseListener(editorEventHandler);
623                 contentCanvas.addEventHandlerMouseMotionListener(editorEventHandler);
624                 if (eventEnabled) {
625                     editorEventHandler.setEnable(false);
626                     enableEventHandler();
627                 }
628
629                 layeredPane.add(contentCanvas, JLayeredPane.FRAME_CONTENT_LAYER);
630
631                 scrolling.setCanvas(contentCanvas);
632
633                 contentCanvas.addKeyListener(this);
634             }
635             return;
636         }
637
638         SwingScilabCommonPanel.addMember(this, member);
639     }
640
641     /**
642      * Remove a SwingViewObject (from SwingView.java)
643      * @param member the member to remove
644      */
645     public void removeMember(SwingViewObject member) {
646         SwingScilabCommonPanel.removeMember(this, member);
647     }
648
649     /**
650      * Add a member (dockable element) to container and returns its index
651      * @param member the member to add
652      * @return index of member in ArrayList
653      */
654     @Override
655     public int addMember(Console member) {
656         return this.addMember((SwingScilabConsole) member.getAsSimpleConsole());
657     }
658
659     /**
660      * Add a member (dockable element) to container and returns its index
661      * @param member the member to add
662      * @return index of member in ArrayList
663      */
664     private int addMember(SwingScilabConsole member) {
665         // replace the current content pane
666         this.setContentPane(member);
667         return this.getComponentZOrder(member);
668     }
669
670     /**
671      * Add a member (dockable element) to container and returns its index
672      * @param member the member to add
673      * @return index of member in ArrayList
674      */
675     @Override
676     public int addMember(HelpBrowser member) {
677         return this.addMember((SwingScilabHelpBrowser) member.getAsSimpleHelpBrowser());
678     }
679
680     /**
681      * Add a member (dockable element) to container and returns its index
682      * @param member the member to add
683      * @return index of member in ArrayList
684      */
685     private int addMember(SwingScilabHelpBrowser member) {
686         // replace the current content pane
687         this.setContentPane(member);
688         return this.getComponentZOrder(member);
689     }
690
691     /**
692      * Add a member (dockable element) to container and returns its index
693      * @param member the member to add
694      * @return index of member in ArrayList
695      */
696     public int addMember(UiDisplayTree member) {
697         return this.addMember((SwingScilabUiDisplayTree) member.getAsSimpleUiDisplayTree());
698     }
699
700     /**
701      * Add a member (dockable element) to container and returns its index
702      * @param member the member to add
703      * @return index of member in ArrayList
704      */
705     private int addMember(SwingScilabUiDisplayTree member) {
706         return 0;
707     }
708
709     /**
710      * Remove a Tree from its container
711      * @param member the Tree to remove
712      */
713     public void removeMember(UiDisplayTree member) {
714         this.removeMember((SwingScilabUiDisplayTree) member.getAsSimpleUiDisplayTree());
715     }
716
717     /**
718      * Remove a Tree from its container
719      * @param member the Tree to remove
720      */
721     private void removeMember(SwingScilabUiDisplayTree member) {
722     }
723
724     /**
725      * Add a Tree member (dockable element) to container and returns its index
726      * @param member the member to add
727      * @return index of member in ArrayList
728      */
729     @Override
730     public int addMember(Tree member) {
731         return this.addMember((SwingScilabTree) member.getAsSimpleTree());
732     }
733
734     /**
735      * Add a Tree member (dockable element) to container and returns its index
736      * @param member the member to add
737      * @return index of member in ArrayList
738      */
739     public int addMember(SwingScilabTree member) {
740         return 0;
741     }
742
743     /**
744      * Add a Tree member (dockable element) to container and returns its index
745      * @param member the member to add
746      * @return index of member in ArrayList
747      */
748     public int addTree(SwingScilabTree member) {
749         this.setContentPane(member.getAsComponent());
750         return this.getComponentZOrder(member.getAsComponent());
751     }
752
753     /**
754      * Remove a PopupMenu from its container
755      * @param member the PopupMenu to remove
756      */
757     @Override
758     public void removeMember(Tree member) {
759         this.removeMember((SwingScilabTree) member.getAsSimpleTree());
760     }
761
762     /**
763      * Remove a PopupMenu from its container
764      * @param member the PopupMenu to remove
765      */
766     private void removeMember(SwingScilabTree member) {
767     }
768
769     /**
770      * Add a member (dockable element) to container and returns its index
771      * @param member the member to add
772      * @return index of member in ArrayList
773      */
774     public int addMember(Dockable member) {
775         // TODO Auto-generated method stub
776         return 0;
777     }
778
779     /**
780      * Get the current status of the Tab in its parent
781      * @return true is the tab is the tab currently "on top" in its parent
782      */
783     @Override
784     public boolean isCurrentTab() {
785         // TODO should not always return TRUE
786         return true;
787     }
788
789     /**
790      * Get the parent window id for this tab
791      * @return the id of the parent window
792      */
793     @Override
794     public String getParentWindowId() {
795         return this.parentWindowId;
796     }
797
798     /**
799      * Get the canvas
800      * @return the canvas
801      */
802     public SwingScilabCanvas getContentCanvas() {
803         return contentCanvas;
804     }
805
806     /**
807      * Set the parent window id for this tab
808      * @param id the id of the parent window
809      */
810     @Override
811     public void setParentWindowId(String id) {
812         this.parentWindowId = id;
813     }
814
815     /**
816      * Setter for MenuBar
817      * @param newMenuBar : the MenuBar to set.
818      * @see org.scilab.modules.gui.tab.SimpleTab#setMenuBar(org.scilab.modules.gui.menubar.MenuBar)
819      */
820     @Override
821     public void setMenuBar(MenuBar newMenuBar) {
822         if (this.menuBar != newMenuBar) {
823             if (this.menuBar != null) {
824                 ((SwingScilabMenuBar) this.menuBar.getAsSimpleMenuBar()).close();
825             }
826             this.menuBar = newMenuBar;
827         }
828     }
829
830     /**
831      * Getter for MenuBar
832      * @return MenuBar : the MenuBar associated to the Tab.
833      * @see org.scilab.modules.gui.tab.SimpleTab#getMenuBar()
834      */
835     @Override
836     public MenuBar getMenuBar() {
837         return this.menuBar;
838     }
839
840     /**
841      * Setter for ToolBar
842      * @param newToolBar : the ToolBar to set.
843      * @see org.scilab.modules.gui.tab.SimpleTab#setToolBar(org.scilab.modules.gui.toolbar.ToolBar)
844      */
845     @Override
846     public void setToolBar(ToolBar newToolBar) {
847         this.toolBar = newToolBar;
848     }
849
850     /**
851      * Getter for ToolBar
852      * @return ToolBar : the ToolBar associated to the Tab.
853      * @see org.scilab.modules.gui.tab.SimpleTab#getToolBar()
854      */
855     @Override
856     public ToolBar getToolBar() {
857         return this.toolBar;
858     }
859
860     /**
861      * Setter for InfoBar
862      * @param newInfoBar the InfoBar to set.
863      */
864     @Override
865     public void setInfoBar(TextBox newInfoBar) {
866         this.infoBar = newInfoBar;
867     }
868
869     /**
870      * Getter for InfoBar
871      * @return the InfoBar associated to the Tab.
872      */
873     @Override
874     public TextBox getInfoBar() {
875         return this.infoBar;
876     }
877
878     /**
879      * Set the callback of the tab
880      * @param callback the callback to set.
881      */
882     @Override
883     public void setCallback(CommonCallBack callback) {
884
885         if (closeAction != null) {
886             this.getTitlebar().removeAction(closeAction);
887         }
888
889         if (callback != null) {
890             closeAction = new SciClosingAction(this, callback);
891         } else {
892             closeAction = new SciClosingAction(this);
893         }
894
895         closeAction.putValue(Action.NAME, DockingConstants.CLOSE_ACTION);
896         ((Titlebar) getTitlePane()).removeAction(DockingConstants.CLOSE_ACTION);
897         addAction(closeAction);
898
899         /* Undock button */
900         SciUndockingAction undockAction = new SciUndockingAction(this);
901         undockAction.putValue(Action.NAME, UNDOCK);
902         ((Titlebar) getTitlePane()).removeAction(UNDOCK);
903         addAction(undockAction);
904
905         /* Help button */
906         SciHelpOnComponentAction helpAction = new SciHelpOnComponentAction(this);
907         helpAction.putValue(Action.NAME, HELP);
908         ((Titlebar) getTitlePane()).removeAction(HELP);
909         addAction(helpAction);
910     }
911
912     /**
913      * Set this tab as the current tab of its parent Window
914      */
915     @Override
916     public void setCurrent() {
917         ActiveDockableTracker.requestDockableActivation(this);
918     }
919
920     /**
921      * Set the background color of the tab.
922      * @param red red channel of the color
923      * @param green green channel
924      * @param blue blue channel
925      */
926     @Override
927     public void setBackground(double red, double green, double blue) {
928         Color newColor = new Color((float) red, (float) green, (float) blue);
929         setBackground(newColor);
930     }
931
932     /**
933      * Get the part of the axes which is currently viewed
934      * @return [x,y,w,h] array
935      */
936     @Override
937     public int[] getViewingRegion() {
938         return scrolling.getViewingRegion();
939     }
940
941     /**
942      * Specify a new viewport for the axes For SwingScilabCanvas viewport can
943      * not be modified since it match the parent tab size
944      * @param posX X coordinate of upper left point of the viewport within the
945      * axes
946      * @param posY Y coordinate of upper left point of the viewport within the
947      * axes
948      * @param width width of the viewport
949      * @param height height of the viewport
950      */
951     @Override
952     public void setViewingRegion(int posX, int posY, int width, int height) {
953     }
954
955     /**
956      * Set the event handler of the Canvas
957      * @param funName the name of the Scilab function to call
958      */
959     public void setEventHandler(String funName) {
960         disableEventHandler();
961         eventHandler = new ScilabEventListener(funName, getId());
962         if (eventEnabled) {
963             editorEventHandler.setEnable(false);
964             enableEventHandler();
965         }
966     }
967
968     /**
969      * Set the status of the event handler of the Canvas
970      * @param status is true to set the event handler active
971      */
972     public void setEventHandlerEnabled(boolean status) {
973         if (status && eventEnabled) {
974             return;
975         }
976
977         if (status) {
978             editorEventHandler.setEnable(false);
979             enableEventHandler();
980             eventEnabled = true;
981         } else {
982             editorEventHandler.setEnable(true);
983             disableEventHandler();
984             eventEnabled = false;
985         }
986     }
987
988     /**
989      * Specify whether the canvas should fit the parent tab size (and
990      * consequently the scrollpane size) or not
991      * @param onOrOff true to enable autoresize mode
992      */
993     @Override
994     public void setAutoResizeMode(boolean onOrOff) {
995     }
996
997     /**
998      * @return whether the resize mode is on or off
999      */
1000     @Override
1001     public boolean getAutoResizeMode() {
1002         return true;
1003     }
1004
1005     /**
1006      * Close the tab and disable it.
1007      */
1008     public void close() {
1009         if (getTitlePane() != null) {
1010             ((Titlebar) getTitlePane()).removeAction(DockingConstants.CLOSE_ACTION);
1011             ((Titlebar) getTitlePane()).removeAction(UNDOCK);
1012             ((Titlebar) getTitlePane()).removeAction(HELP);
1013         }
1014
1015         if (closeAction != null) {
1016             getTitlebar().removeAction(closeAction);
1017             if (closeAction instanceof SciClosingAction) {
1018                 ((SciClosingAction) closeAction).clean();
1019             }
1020             closeAction = null;
1021         }
1022
1023         setMenuBar(null);
1024         setToolBar(null);
1025         setInfoBar(null);
1026         setTitlebar(null);
1027         removeAll();
1028         //setActive(false);
1029
1030         scrolling = null;
1031         contentPane = null;
1032         DockingManager.unregisterDockable((Component) this);
1033
1034         // without this children canvas are not released.
1035         Container dummyContainer = new Container();
1036         this.setContentPane(dummyContainer);
1037         if (editorEventHandler != null) {
1038             editorEventHandler.onExit();
1039         }
1040     }
1041
1042     public void disablePaint() {
1043         paintEnable = false;
1044     }
1045
1046     public void setFigureBackground(Color color) {
1047         if (layeredPane != null) {
1048             layeredPane.setBackground(color);
1049         }
1050     }
1051
1052     /**
1053      * Redefine paint children to be sure that AWT components are well painted.
1054      * @param g a Graphics
1055      */
1056     @Override
1057     public void paintChildren(Graphics g) {
1058         if (paintEnable) {
1059             Component[] children = getComponents();
1060             for (int i = 0; i < children.length; i++) {
1061                 // AWT children don't draw themselves automatically
1062                 // so force their draw
1063                 if (!children[i].isLightweight()) {
1064                     children[i].paint(g);
1065                 }
1066             }
1067             super.paintChildren(g);
1068         }
1069     }
1070
1071     /**
1072      * Update the tab after a modification of its properties
1073      * @param property the property name
1074      * @param value the property value
1075      * @see org.scilab.modules.gui.SwingViewObject#update(java.lang.String,
1076      * java.lang.Object)
1077      */
1078     public void update(int property, Object value) {
1079         SwingScilabCommonPanel.update(this, property, value);
1080     }
1081
1082     /**
1083      * Get the tab UID
1084      * @return the UID
1085      * @see org.scilab.modules.gui.SwingViewObject#getId()
1086      */
1087     public Integer getId() {
1088         return id;
1089     }
1090
1091     /**
1092      * Set the tab UID
1093      * @param id the UID
1094      * @see org.scilab.modules.gui.SwingViewObject#setId(java.lang.String)
1095      */
1096     public void setId(Integer id) {
1097         this.id = id;
1098     }
1099
1100     /**
1101      * Turn on event handling.
1102      */
1103     private void enableEventHandler() {
1104         if (contentCanvas != null) {
1105             contentCanvas.addEventHandlerKeyListener(eventHandler);
1106             contentCanvas.addEventHandlerMouseListener(eventHandler);
1107             contentCanvas.addEventHandlerMouseMotionListener(eventHandler);
1108         }
1109     }
1110
1111     /**
1112      * Turn off event handling.
1113      */
1114     private void disableEventHandler() {
1115         if (eventHandler != null && contentCanvas != null) {
1116             contentCanvas.removeEventHandlerKeyListener(eventHandler);
1117             contentCanvas.removeEventHandlerMouseListener(eventHandler);
1118             contentCanvas.removeEventHandlerMouseMotionListener(eventHandler);
1119         }
1120     }
1121
1122     public void keyPressed(KeyEvent e) {
1123
1124     }
1125
1126     public void keyReleased(KeyEvent e) {
1127     }
1128
1129     public void keyTyped(KeyEvent e) {
1130         if (ScilabConstants.isGUI() && (eventHandler == null || !eventEnabled) && !GlobalEventWatcher.isActivated() && !editorEventHandler.isDatatipEnable()
1131                 && Character.isLetterOrDigit(e.getKeyChar())) {
1132             SwingScilabConsole console = (SwingScilabConsole) ScilabConsole.getConsole().getAsSimpleConsole();
1133             JTextPane input = (JTextPane) console.getConfiguration().getInputCommandView();
1134             input.requestFocus();
1135             SwingScilabWindow win = (SwingScilabWindow) SwingUtilities.getAncestorOfClass(SwingScilabWindow.class, console);
1136             win.toFront();
1137             input.dispatchEvent(new KeyEvent(input, KeyEvent.KEY_TYPED, System.currentTimeMillis(), e.getModifiers(), e.getKeyCode(), e.getKeyChar(), e.getKeyLocation()));
1138         }
1139     }
1140
1141     public JLayeredPane getWidgetPane() {
1142         return uiContentPane;
1143     }
1144
1145     public void setHasLayout(boolean hasLayout) {
1146         this.hasLayout = hasLayout;
1147     }
1148
1149     public void applyDeltaSize() {
1150         if (deltaSize != null) {
1151             if (deltaSize.getWidth() != 0 || deltaSize.getHeight() != 0) {
1152                 //update view and update model ( from componentResize of Window )
1153                 SwingScilabWindow figure = SwingScilabWindow.allScilabWindows.get(getParentWindowId());
1154                 Dimension oldAxesSize = getContentPane().getSize();
1155                 figure.setDims(new Size((int)(oldAxesSize.getWidth() + deltaSize.getWidth()), (int)(oldAxesSize.getHeight() + deltaSize.getHeight())));
1156             }
1157
1158             deltaSize = null;
1159         }
1160     }
1161
1162     public void storeSizeDelta() {
1163         Dimension axesSize = getContentPane().getSize();
1164         SwingScilabWindow figure = SwingScilabWindow.allScilabWindows.get(getParentWindowId());
1165         Size figureSize = figure.getDims();
1166         deltaSize = new Dimension((int)(figureSize.getWidth() - axesSize.getWidth()), (int)(figureSize.getHeight() - axesSize.getHeight()));
1167     }
1168
1169     public void disableResizeEvent() {
1170         removeComponentListener(componentListener);
1171     }
1172
1173     public void enableResizeEvent() {
1174         addComponentListener(componentListener);
1175     }
1176 }