2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Bruno JOFRET
4 * Copyright (C) 2010 - DIGITEO - Vincent COUVERT
5 * Copyright (C) 2011 - Calixte DENIZET
7 * This file must be used under the terms of the CeCILL.
8 * This source file is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution. The terms
10 * are also available at
11 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
14 package org.scilab.modules.ui_data.variablebrowser;
16 import static org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.asynchronousScilabExec;
18 import java.awt.Color;
19 import java.awt.MouseInfo;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.MouseEvent;
23 import java.awt.event.MouseListener;
25 import javax.swing.ActionMap;
26 import javax.swing.SwingUtilities;
28 import java.util.ArrayList;
29 import java.util.HashSet;
30 import java.util.List;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTable;
34 import javax.swing.ListSelectionModel;
35 import javax.swing.RowFilter;
36 import javax.swing.table.DefaultTableCellRenderer;
37 import javax.swing.table.TableColumn;
38 import javax.swing.table.TableModel;
39 import javax.swing.table.TableRowSorter;
41 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement;
42 import org.scilab.modules.action_binding.highlevel.ScilabInterpreterManagement.InterpreterException;
43 import org.scilab.modules.gui.bridge.tab.SwingScilabTab;
44 import org.scilab.modules.gui.bridge.contextmenu.SwingScilabContextMenu;
45 import org.scilab.modules.gui.contextmenu.ContextMenu;
46 import org.scilab.modules.gui.contextmenu.ScilabContextMenu;
47 import org.scilab.modules.gui.checkboxmenuitem.CheckBoxMenuItem;
48 import org.scilab.modules.gui.menu.Menu;
49 import org.scilab.modules.gui.menu.ScilabMenu;
50 import org.scilab.modules.gui.menubar.MenuBar;
51 import org.scilab.modules.gui.menubar.ScilabMenuBar;
52 import org.scilab.modules.gui.messagebox.ScilabModalDialog;
53 import org.scilab.modules.gui.messagebox.ScilabModalDialog.IconType;
54 import org.scilab.modules.gui.pushbutton.PushButton;
55 import org.scilab.modules.gui.textbox.TextBox;
56 import org.scilab.modules.gui.toolbar.ScilabToolBar;
57 import org.scilab.modules.gui.toolbar.ToolBar;
58 import org.scilab.modules.gui.utils.WindowsConfigurationManager;
59 import org.scilab.modules.localization.Messages;
60 import org.scilab.modules.types.ScilabTypeEnum;
61 import org.scilab.modules.ui_data.BrowseVar;
62 import org.scilab.modules.ui_data.actions.BooleanFilteringAction;
63 import org.scilab.modules.ui_data.actions.CompiledFunctionFilteringAction;
64 import org.scilab.modules.ui_data.actions.DoubleFilteringAction;
65 import org.scilab.modules.ui_data.actions.FunctionLibFilteringAction;
66 import org.scilab.modules.ui_data.actions.GraphicHandlesFilteringAction;
67 import org.scilab.modules.ui_data.actions.HelpAction;
68 import org.scilab.modules.ui_data.actions.ImplicitPolynomialFilteringAction;
69 import org.scilab.modules.ui_data.actions.IntegerFilteringAction;
70 import org.scilab.modules.ui_data.actions.IntrinsicFunctionFilteringAction;
71 import org.scilab.modules.ui_data.actions.ListFilteringAction;
72 import org.scilab.modules.ui_data.actions.MListFilteringAction;
73 import org.scilab.modules.ui_data.actions.MatlabSparseFilteringAction;
74 import org.scilab.modules.ui_data.actions.PointerFilteringAction;
75 import org.scilab.modules.ui_data.actions.PolynomialFilteringAction;
76 import org.scilab.modules.ui_data.actions.ScilabVarFilteringAction;
77 import org.scilab.modules.ui_data.actions.ScilabVarFilteringButtonAction;
78 import org.scilab.modules.ui_data.actions.SparseBoolFilteringAction;
79 import org.scilab.modules.ui_data.actions.SparseFilteringAction;
80 import org.scilab.modules.ui_data.actions.StringFilteringAction;
81 import org.scilab.modules.ui_data.actions.TListFilteringAction;
82 import org.scilab.modules.ui_data.actions.UncompiledFunctionFilteringAction;
83 import org.scilab.modules.ui_data.datatable.SwingTableModel;
84 import org.scilab.modules.ui_data.utils.UiDataMessages;
85 import org.scilab.modules.ui_data.variableeditor.actions.ExportToCsvAction;
86 import org.scilab.modules.ui_data.variablebrowser.actions.CloseAction;
87 import org.scilab.modules.ui_data.variablebrowser.actions.DeleteAction;
88 import org.scilab.modules.ui_data.variablebrowser.actions.RefreshAction;
89 import org.scilab.modules.ui_data.variablebrowser.rowfilter.VariableBrowserRowDataFilter;
90 import org.scilab.modules.ui_data.variablebrowser.rowfilter.VariableBrowserRowTypeFilter;
93 * Swing implementation of Scilab Variable browser
96 public final class SwingScilabVariableBrowser extends SwingScilabTab implements SimpleVariableBrowser {
98 public static final String VARBROWSERUUID = "3b649047-6a71-4998-bd8e-00d367a4793c";
100 private static final long serialVersionUID = 2169382559550113917L;
102 private SwingTableModel<Object> dataModel;
103 private JTable table;
105 private MenuBar menuBar;
106 private Menu fileMenu;
107 private Menu helpMenu;
108 private Menu filterMenu;
109 private CheckBoxMenuItem filterDoubleCheckBox;
110 private CheckBoxMenuItem filterPolynomialCheckBox;
111 private CheckBoxMenuItem filterScilabVarCheckBox;
112 private CheckBoxMenuItem filterBooleanCheckBox;
113 private CheckBoxMenuItem filterSparseCheckBox;
114 private CheckBoxMenuItem filterSparseBoolCheckBox;
115 private CheckBoxMenuItem filterIntegerCheckBox;
116 private CheckBoxMenuItem filterGraphicHandlesCheckBox;
117 private CheckBoxMenuItem filterStringCheckBox;
118 private CheckBoxMenuItem filterUncompiledFuncCheckBox;
119 private CheckBoxMenuItem filtercompiledFuncCheckBox;
120 private CheckBoxMenuItem filterFunctionLibCheckBox;
121 private CheckBoxMenuItem filterListCheckBox;
122 private CheckBoxMenuItem filterTListCheckBox;
123 private CheckBoxMenuItem filterMListCheckBox;
124 private CheckBoxMenuItem filterPointerCheckBox;
125 private CheckBoxMenuItem filterIntrinsicFunctionCheckBox;
126 private CheckBoxMenuItem filterMatlabSparseCheckBox;
127 private CheckBoxMenuItem filterImplicitPolynomialCheckBox;
128 private PushButton filteringButton;
130 private boolean isSetData = false;
132 private TableRowSorter < ? > rowSorter;
135 * Create a JTable with data Model.
136 * @param columnsName : Titles of JTable columns.
138 public SwingScilabVariableBrowser(String[] columnsName, int[] aligment) {
139 super(UiDataMessages.VARIABLE_BROWSER, VARBROWSERUUID);
141 setAssociatedXMLIDForHelp("browsevar");
146 ToolBar toolBar = ScilabToolBar.createToolBar();
147 toolBar.add(RefreshAction.createButton(UiDataMessages.REFRESH));
148 toolBar.addSeparator();
149 toolBar.add(DeleteAction.createButton(this, UiDataMessages.DELETE));
150 toolBar.addSeparator();
151 toolBar.add(HelpAction.createButton(UiDataMessages.HELP));
152 filteringButton = ScilabVarFilteringButtonAction.createButton("Show/hide Scilab variable");
153 // toolBar.add(filteringButton);
156 dataModel = new SwingTableModel<Object>(columnsName);
158 table = new JTable(dataModel) {
159 //Implement table cell tool tips.
160 public String getToolTipText(MouseEvent e) {
162 TableModel model = ((JTable) e.getSource()).getModel();
163 java.awt.Point p = e.getPoint();
164 int rowIndex = rowAtPoint(p);
167 rowIndex = convertRowIndexToModel(rowIndex);
168 int colIndex = columnAtPoint(p);
169 if (colIndex == BrowseVar.TYPE_DESC_COLUMN_INDEX) { /* Scilab type */
171 tip = Messages.gettext("Scilab type:") + " " + model.getValueAt(rowIndex, BrowseVar.TYPE_COLUMN_INDEX).toString();
172 } catch (IllegalArgumentException exception) {
173 /* If the type is not known/managed, don't crash */
177 if (colIndex == BrowseVar.SIZE_COLUMN_INDEX) {
178 /* Use the getModel() method because the
179 * column 5 has been removed from display
180 * but still exist in the model */
181 tip = Messages.gettext("Bytes:") + " " + model.getValueAt(rowIndex, BrowseVar.BYTES_COLUMN_INDEX).toString();
189 table.setFillsViewportHeight(true);
190 table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
191 table.setAutoCreateRowSorter(true);
193 /* Size of the icon column */
194 table.getColumnModel().getColumn(0).setPreferredWidth(30);
196 /* Hide the columns. But keep it in memory for the tooltip */
197 TableColumn column = table.getColumnModel().getColumn(BrowseVar.TYPE_COLUMN_INDEX);
198 /* The order to removing does matter since it changes the positions */
199 table.removeColumn(column);
201 column = table.getColumnModel().getColumn(BrowseVar.FROM_SCILAB_COLUMN_INDEX);
202 table.removeColumn(column);
204 column = table.getColumnModel().getColumn(BrowseVar.BYTES_COLUMN_INDEX);
205 table.removeColumn(column);
207 table.addMouseListener(new BrowseVarMouseListener());
208 // Mouse selection mode
209 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
210 table.setCellSelectionEnabled(true);
212 table.setBackground(Color.WHITE);
213 if (table.getGridColor().equals(Color.WHITE)) {
214 table.setGridColor(new Color(128, 128, 128));
216 table.setShowHorizontalLines(true);
217 table.setShowVerticalLines(true);
219 for (int i = 0; i < aligment.length; i++) {
220 align(table, columnsName[i], aligment[i]);
223 // Plug the shortcuts
224 ExportToCsvAction.registerAction(this, table);
226 JScrollPane scrollPane = new JScrollPane(table);
227 setContentPane(scrollPane);
228 WindowsConfigurationManager.restorationFinished(this);
234 public void addInfoBar(TextBox infoBarToAdd) {
235 setInfoBar(infoBarToAdd);
241 public void addMenuBar(MenuBar menuBarToAdd) {
242 setMenuBar(menuBarToAdd);
248 public void addToolBar(ToolBar toolBarToAdd) {
249 setToolBar(toolBarToAdd);
255 public void setColumnNames(String[] columnNames) {
256 dataModel.setColumnNames(columnNames);
262 public void setData(Object[][] data) {
264 dataModel.setData(data);
265 rowSorter = new TableRowSorter<TableModel>(dataModel);
266 this.updateRowFiltering();
269 private static void align(JTable table, String name, int alignment) {
270 if (alignment != -1) {
271 DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
272 renderer.setHorizontalAlignment(alignment);
274 TableColumn col = table.getColumn(name);
276 col.setCellRenderer(renderer);
278 } catch (IllegalArgumentException e) { }
283 * Update the display after filtering
284 * @see org.scilab.modules.ui_data.variablebrowser.SimpleVariableBrowser#updateRowFiltering()
286 public void updateRowFiltering() {
287 if (isSetData == false) { /* If the pull of the data has not been done, do it (please) */
289 ScilabInterpreterManagement.synchronousScilabExec("browsevar");
291 } catch (InterpreterException e) {
292 System.err.println(e);
295 VariableBrowserRowTypeFilter rowTypeFilter = new VariableBrowserRowTypeFilter(getFilteredTypeValues());
296 VariableBrowserRowDataFilter rowDataFilter = new VariableBrowserRowDataFilter(getFilteredDataValues());
298 List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>();
299 RowFilter<Object, Object> compoundRowFilter = null;
300 filters.add(rowTypeFilter);
301 filters.add(rowDataFilter);
302 compoundRowFilter = RowFilter.andFilter(filters);
304 rowSorter.setRowFilter(compoundRowFilter);
305 table.setRowSorter(rowSorter);
309 * MouseListener inner class
311 private class BrowseVarMouseListener implements MouseListener {
316 public BrowseVarMouseListener() {
321 * Mouse CLICKED event handling
323 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
325 public void mouseClicked(MouseEvent e) {
327 // Right click management
328 if ((e.getClickCount() == 1 && SwingUtilities.isRightMouseButton(e)) || e.isPopupTrigger()) {
331 int clickedRow = ((JTable) e.getSource()).rowAtPoint(e.getPoint());
332 // Does nothing if no variable selected
333 if (clickedRow != -1) {
334 displayContextMenu();
338 if (e.getClickCount() >= 2) {
339 int clickedRow = ((JTable) e.getSource()).rowAtPoint(e.getPoint());
340 if (clickedRow != -1) {
341 String variableName = table.getValueAt(clickedRow, BrowseVar.NAME_COLUMN_INDEX).toString();
343 String variableVisibility = ((JTable) e.getSource())
344 .getValueAt(((JTable) e.getSource()).getSelectedRow(), BrowseVar.VISIBILITY_COLUMN_INDEX).toString();
346 // Global variables are not editable yet
347 if (variableVisibility.equals("global")) {
348 ScilabModalDialog.show(getBrowserTab(),
349 UiDataMessages.GLOBAL_NOT_EDITABLE,
350 UiDataMessages.VARIABLE_EDITOR,
351 IconType.ERROR_ICON);
356 asynchronousScilabExec(null,
357 "if exists(\"" + variableName + "\") == 1 then "
359 + " editvar(\"" + variableName + "\"); "
361 + " messagebox(\"Variables of type \"\"\" + typeof ("
362 + variableName + ") + \"\"\" can not be edited.\""
363 + ",\"" + UiDataMessages.VARIABLE_EDITOR + "\", \"error\", \"modal\");"
364 + " clear ans;" // clear return value of messagebox
367 + " messagebox(\"Variable \"\""
368 + variableName + "\"\" no more exists.\""
369 + ",\"" + UiDataMessages.VARIABLE_EDITOR + "\", \"error\", \"modal\");"
370 + " clear ans;" // clear return value of messagebox
371 + " browsevar();" // Reload browsevar to remove cleared variables
373 } catch (InterpreterException e1) {
374 System.err.println("An error in the interpreter has been catched: " + e1.getLocalizedMessage());
381 * Mouse ENTERED event handling
383 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
385 public void mouseEntered(MouseEvent e) {
389 * Mouse EXITED event handling
391 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
393 public void mouseExited(MouseEvent e) {
397 * Mouse PRESSED event handling
399 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
401 public void mousePressed(MouseEvent e) {
405 * Mouse RELEASED event handling
407 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
409 public void mouseReleased(MouseEvent e) {
414 * Create and display the context menu
416 private void displayContextMenu() {
417 ContextMenu menu = ScilabContextMenu.createContextMenu();
419 DeleteAction delete = new DeleteAction(SwingScilabVariableBrowser.this);
420 menu.add(delete.createMenuItem());
422 ExportToCsvAction csvExport = new ExportToCsvAction((SwingScilabTab)SwingScilabVariableBrowser.this, UiDataMessages.EXPORTCSV);
423 menu.add(csvExport.createMenuItem(SwingScilabVariableBrowser.this, UiDataMessages.EXPORTCSV));
424 menu.setVisible(true);
426 ((SwingScilabContextMenu) menu.getAsSimpleContextMenu()).setLocation(
427 MouseInfo.getPointerInfo().getLocation().x,
428 MouseInfo.getPointerInfo().getLocation().y);
436 * Creates the menuBar
438 public void buildMenuBar() {
439 menuBar = ScilabMenuBar.createMenuBar();
441 fileMenu = ScilabMenu.createMenu();
442 fileMenu.setText(UiDataMessages.FILE);
443 fileMenu.setMnemonic('F');
444 fileMenu.add(RefreshAction.createMenuItem(UiDataMessages.REFRESH));
445 fileMenu.addSeparator();
446 fileMenu.add(CloseAction.createMenu());
448 menuBar.add(fileMenu);
450 filterMenu = ScilabMenu.createMenu();
451 filterMenu.setText(UiDataMessages.FILTER);
452 filterMenu.setMnemonic('I');
454 filterScilabVarCheckBox = ScilabVarFilteringAction.createCheckBoxMenu();
455 filterScilabVarCheckBox.setChecked(true);
456 filterMenu.add(filterScilabVarCheckBox);
458 filterMenu.addSeparator();
460 filterBooleanCheckBox = BooleanFilteringAction.createCheckBoxMenu();
461 filterBooleanCheckBox.setChecked(true);
462 filterMenu.add(filterBooleanCheckBox);
464 filterDoubleCheckBox = DoubleFilteringAction.createCheckBoxMenu();
465 filterDoubleCheckBox.setChecked(true);
466 filterMenu.add(filterDoubleCheckBox);
468 filterPolynomialCheckBox = PolynomialFilteringAction.createCheckBoxMenu();
469 filterPolynomialCheckBox.setChecked(true);
470 filterMenu.add(filterPolynomialCheckBox);
472 filterFunctionLibCheckBox = FunctionLibFilteringAction.createCheckBoxMenu();
473 filterMenu.add(filterFunctionLibCheckBox);
475 filterStringCheckBox = StringFilteringAction.createCheckBoxMenu();
476 filterStringCheckBox.setChecked(true);
477 filterMenu.add(filterStringCheckBox);
479 filterSparseCheckBox = SparseFilteringAction.createCheckBoxMenu();
480 filterSparseCheckBox.setChecked(true);
481 filterMenu.add(filterSparseCheckBox);
483 filterSparseBoolCheckBox = SparseBoolFilteringAction.createCheckBoxMenu();
484 filterSparseBoolCheckBox.setChecked(true);
485 filterMenu.add(filterSparseBoolCheckBox);
487 filterIntegerCheckBox = IntegerFilteringAction.createCheckBoxMenu();
488 filterIntegerCheckBox.setChecked(true);
489 filterMenu.add(filterIntegerCheckBox);
491 filterGraphicHandlesCheckBox = GraphicHandlesFilteringAction.createCheckBoxMenu();
492 filterGraphicHandlesCheckBox.setChecked(true);
493 filterMenu.add(filterGraphicHandlesCheckBox);
495 filterUncompiledFuncCheckBox = UncompiledFunctionFilteringAction.createCheckBoxMenu();
496 filterMenu.add(filterUncompiledFuncCheckBox);
498 filtercompiledFuncCheckBox = CompiledFunctionFilteringAction.createCheckBoxMenu();
499 filterMenu.add(filtercompiledFuncCheckBox);
501 filterListCheckBox = ListFilteringAction.createCheckBoxMenu();
502 filterListCheckBox.setChecked(true);
503 filterMenu.add(filterListCheckBox);
505 filterTListCheckBox = TListFilteringAction.createCheckBoxMenu();
506 filterTListCheckBox.setChecked(true);
507 filterMenu.add(filterTListCheckBox);
509 filterMListCheckBox = MListFilteringAction.createCheckBoxMenu();
510 filterMListCheckBox.setChecked(true);
511 filterMenu.add(filterMListCheckBox);
513 filterPointerCheckBox = PointerFilteringAction.createCheckBoxMenu();
514 filterPointerCheckBox.setChecked(true);
515 filterMenu.add(filterPointerCheckBox);
517 filterIntrinsicFunctionCheckBox = IntrinsicFunctionFilteringAction.createCheckBoxMenu();
518 filterMenu.add(filterIntrinsicFunctionCheckBox);
520 filterMatlabSparseCheckBox = MatlabSparseFilteringAction.createCheckBoxMenu();
521 filterMenu.add(filterMatlabSparseCheckBox);
523 filterImplicitPolynomialCheckBox = ImplicitPolynomialFilteringAction.createCheckBoxMenu();
524 filterMenu.add(filterImplicitPolynomialCheckBox);
526 menuBar.add(filterMenu);
528 helpMenu = ScilabMenu.createMenu();
529 helpMenu.setText("?");
530 helpMenu.setMnemonic('?');
531 helpMenu.add(HelpAction.createMenuItem(UiDataMessages.HELP));
532 menuBar.add(helpMenu);
537 * Filter management of data (Scilab or user data)
538 * @return the set of filtered values
540 public boolean getFilteredDataValues() {
541 return filterScilabVarCheckBox.isChecked();
546 * Filter management of type
547 * @return the set of filtered values
549 public HashSet<ScilabTypeEnum> getFilteredTypeValues() {
550 HashSet<ScilabTypeEnum> filteredValues = new HashSet<ScilabTypeEnum>();
551 // TODO to replace later by something which smells less
552 if (!filterBooleanCheckBox.isChecked()) {
553 filteredValues.add(ScilabTypeEnum.sci_boolean);
556 if (!filterDoubleCheckBox.isChecked()) {
557 filteredValues.add(ScilabTypeEnum.sci_matrix);
560 if (!filterFunctionLibCheckBox.isChecked()) {
561 filteredValues.add(ScilabTypeEnum.sci_lib);
564 if (!filterStringCheckBox.isChecked()) {
565 filteredValues.add(ScilabTypeEnum.sci_strings);
568 if (!filterPolynomialCheckBox.isChecked()) {
569 filteredValues.add(ScilabTypeEnum.sci_poly);
572 if (!filterSparseCheckBox.isChecked()) {
573 filteredValues.add(ScilabTypeEnum.sci_sparse);
576 if (!filterSparseBoolCheckBox.isChecked()) {
577 filteredValues.add(ScilabTypeEnum.sci_boolean_sparse);
580 if (!filterIntegerCheckBox.isChecked()) {
581 filteredValues.add(ScilabTypeEnum.sci_ints);
584 if (!filterGraphicHandlesCheckBox.isChecked()) {
585 filteredValues.add(ScilabTypeEnum.sci_handles);
588 if (!filterUncompiledFuncCheckBox.isChecked()) {
589 filteredValues.add(ScilabTypeEnum.sci_u_function);
592 if (!filtercompiledFuncCheckBox.isChecked()) {
593 filteredValues.add(ScilabTypeEnum.sci_c_function);
596 if (!filterListCheckBox.isChecked()) {
597 filteredValues.add(ScilabTypeEnum.sci_list);
600 if (!filterTListCheckBox.isChecked()) {
601 filteredValues.add(ScilabTypeEnum.sci_tlist);
604 if (!filterMListCheckBox.isChecked()) {
605 filteredValues.add(ScilabTypeEnum.sci_mlist);
608 if (!filterPointerCheckBox.isChecked()) {
609 filteredValues.add(ScilabTypeEnum.sci_pointer);
612 if (!filterIntrinsicFunctionCheckBox.isChecked()) {
613 filteredValues.add(ScilabTypeEnum.sci_intrinsic_function);
616 if (!filterMatlabSparseCheckBox.isChecked()) {
617 filteredValues.add(ScilabTypeEnum.sci_matlab_sparse);
620 if (!filterImplicitPolynomialCheckBox.isChecked()) {
621 filteredValues.add(ScilabTypeEnum.sci_implicit_poly);
624 return filteredValues;
628 * Get this browser as a Tab object
631 public SwingScilabTab getBrowserTab() {
637 * Return the variable Browser Table
638 * @return The variable Browser Table
640 public JTable getTable() {