diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml index fc65106a21fe..a72d00c60f2a 100644 --- a/python/src/META-INF/python-core.xml +++ b/python/src/META-INF/python-core.xml @@ -721,7 +721,7 @@ - + diff --git a/python/src/com/jetbrains/python/actions/PyViewArrayAction.java b/python/src/com/jetbrains/python/actions/PyViewArrayAction.java deleted file mode 100644 index 48e174fb0d9b..000000000000 --- a/python/src/com/jetbrains/python/actions/PyViewArrayAction.java +++ /dev/null @@ -1,775 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jetbrains.python.actions; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.impl.DocumentImpl; -import com.intellij.openapi.editor.impl.EditorFactoryImpl; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.ui.components.JBScrollPane; -import com.intellij.ui.table.JBTable; -import com.intellij.util.containers.HashSet; -import com.intellij.xdebugger.frame.XFullValueEvaluator; -import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeListener; -import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; -import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode; -import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; -import com.jetbrains.python.PythonFileType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; -import javax.swing.table.*; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.List; - -/** - * @author amarch - */ - -public class PyViewArrayAction extends XDebuggerTreeActionBase { - - @Override - protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) { - final MyDialog dialog = new MyDialog(e.getProject(), node, nodeName); - dialog.setTitle("View Array"); - dialog.setValue(node); - dialog.show(); - } - - private abstract class ArrayValueProvider { - - public abstract Object[][] parseValues(String rawValue); - } - - private class NumpyArrayValueProvider extends ArrayValueProvider { - - @Override - public Object[][] parseValues(String rawValues) { - return null; - } - - private boolean isNumeric(String value) { - return true; - } - } - - - private class MyDialog extends DialogWrapper { - public JTable myTable; - private XValueNodeImpl myNode; - private String myNodeName; - private Project myProject; - private MyComponent myComponent; - - private MyDialog(Project project, XValueNodeImpl node, @NotNull String nodeName) { - super(project, false); - setModal(false); - setCancelButtonText("Close"); - setCrossClosesWindow(true); - - myNode = node; - myNodeName = nodeName; - myProject = project; - - myComponent = new MyComponent(); - myTable = myComponent.getTable(); - - init(); - } - - - public abstract class XDebuggerTreeTableListener implements XDebuggerTreeListener { - abstract void setBaseNode(XValueNodeImpl baseNode); - - abstract XValueContainerNode findItems(@NotNull XDebuggerTreeNode node); - } - - public void setValue(XValueNodeImpl node) { - final ArrayValueProvider valueProvider; - - if (node.getValuePresentation() != null && - node.getValuePresentation().getType() != null && - node.getValuePresentation().getType().equals("ndarray")) { - valueProvider = new NumpyArrayValueProvider(); - - //myComponent.setDefaultSpinnerText(); - - XDebuggerTreeTableListener tableUpdater = new XDebuggerTreeTableListener() { - - XValueNodeImpl baseNode; - - XValueContainerNode innerNdarray; - - XValueContainerNode innerItems; - - int[] shape; - - int depth = 0; - - int loadedRows = 0; - - HashSet unloadedRowNumbers = new HashSet(); - - boolean baseChildrenLoaded = false; - - boolean numeric = false; - - boolean dataLoaded = false; - - Object[][] data; - - @Override - public void nodeLoaded(@NotNull RestorableStateNode node, String name) { - System.out.printf(name + " node loaded\n"); - - if (!baseChildrenLoaded && - (shape == null || name.equals("dtype")) && - ((XValueNodeImpl)node.getParent()).getName().equals(baseNode.getName())) { - if (name.equals("shape")) { - String rawValue = node.getRawValue(); - String[] shapes = rawValue.substring(1, rawValue.length() - 1).split(","); - shape = new int[shapes.length]; - for (int i = 0; i < shapes.length; i++) { - shape[i] = Integer.parseInt(shapes[i].trim()); - } - depth = Math.max(shape.length - 2, 0); - } - - if (name.equals("dtype")) { - String rawValue = node.getRawValue(); - if ("biufc".contains(rawValue.substring(0, 1))) { - numeric = true; - } - } - } - } - - @Override - public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List> children, boolean last) { - System.out.printf(children + "children loaded\n"); - - if (dataLoaded) { - return; - } - - //todo: not compute children if they yet computed - - if (!baseChildrenLoaded && node.equals(baseNode)) { - baseChildrenLoaded = true; - innerNdarray = (XValueContainerNode)node; - if (shape != null) { - if (shape.length >= 2) { - data = new Object[shape[shape.length - 2]][shape[shape.length - 1]]; - } - else { - data = new Object[1][shape[0]]; - } - } - } - - //go deeper - if (depth > 0) { - if (innerNdarray != null && innerNdarray.equals(node)) { - innerNdarray = null; - innerItems = findItems(node); - innerItems.startComputingChildren(); - } - - if (innerItems != null && innerItems.equals(node)) { - innerNdarray = (XValueContainerNode)node.getChildAt(1); - innerItems = null; - innerNdarray.startComputingChildren(); - depth -= 1; - } - - return; - } - - //find ndarray slice to display - if (depth == 0) { - innerItems = findItems(node); - innerItems.startComputingChildren(); - depth -= 1; - return; - } - - if (depth == -1 && node.equals(innerItems)) { - if (shape != null && shape.length == 1) { - for (int i = 0; i < node.getChildCount() - 1; i++) { - data[0][i] = fixValue(((XValueNodeImpl)node.getChildAt(i + 1)).getRawValue()); - } - loadData(); - loadedRows = 1; - } - else { - for (int i = 0; i < node.getChildCount() - 1; i++) { - ((XValueNodeImpl)node.getChildAt(i + 1)).startComputingChildren(); - unloadedRowNumbers.add(((XValueNodeImpl)node.getChildAt(i + 1)).getName()); - } - depth -= 1; - } - return; - } - - - if (depth == -2) { - String name = ((XValueNodeImpl)node).getName(); - // ndarrray children not computed yet - if (unloadedRowNumbers.contains(name)) { - unloadedRowNumbers.remove(name); - findItems(node).startComputingChildren(); - return; - } - - if (name.startsWith("[")) { - int row = parseName(((XValueNodeImpl)node.getParent()).getName()); - if (data[row][0] == null) { - for (int i = 0; i < node.getChildCount() - 1; i++) { - data[row][i] = fixValue(((XValueNodeImpl)node.getChildAt(i + 1)).getRawValue()); - } - loadedRows += 1; - } - } - } - - if (loadedRows == shape[shape.length - 2]) { - loadData(); - } - } - - //todo: remove this, make correct code in python - private String fixValue(String value) { - if (!numeric) { - return "\'" + value + "\'"; - } - return value; - } - - public void setBaseNode(XValueNodeImpl baseNode) { - this.baseNode = baseNode; - } - - private int parseName(String name) { - int open = name.indexOf('('); - return Integer.parseInt(name.substring(1, open - 2)); - } - - XValueContainerNode findItems(@NotNull XDebuggerTreeNode node) { - for (int i = 0; i < node.getChildCount(); i++) { - if (node.getChildAt(i).toString().startsWith("[")) { - return (XValueContainerNode)node.getChildAt(i); - } - } - return null; - } - - private void loadData() { - - DefaultTableModel model = new DefaultTableModel(data, range(0, data[0].length - 1)); - - myTable.setModel(model); - myTable.setDefaultEditor(myTable.getColumnClass(0), new MyTableCellEditor(myProject)); - - if (numeric) { - double min = Double.MAX_VALUE; - double max = Double.MIN_VALUE; - if (data.length > 0) { - try { - for (int i = 0; i < data.length; i++) { - for (int j = 0; j < data[0].length; j++) { - double d = Double.parseDouble(data[i][j].toString()); - min = min > d ? d : min; - max = max < d ? d : max; - } - } - } - catch (NumberFormatException e) { - min = 0; - max = 0; - } - } - else { - min = 0; - max = 0; - } - - myTable.setDefaultRenderer(myTable.getColumnClass(0), new MyTableCellRenderer(min, max)); - } - else { - myComponent.getColored().setSelected(false); - myComponent.getColored().setVisible(false); - } - - myComponent.getTextField().setText(getDefaultSliceRepresentation()); - dataLoaded = true; - innerItems = null; - innerNdarray = null; - } - - public String getDefaultSliceRepresentation() { - String representation = ""; - - if (baseNode != null) { - representation += baseNode.getName(); - if (shape != null && shape.length > 0) { - for (int i = 0; i < shape.length - 2; i++) { - representation += "[0]"; - } - if (shape.length == 1) { - representation += "[0:" + shape[0] + "]"; - } - else { - representation += "[0:" + shape[shape.length - 2] + "][0:" + shape[shape.length - 1] + "]"; - } - } - } - - return representation; - } - }; - - tableUpdater.setBaseNode(node); - - node.getTree().addTreeListener(tableUpdater); - - node.startComputingChildren(); - } - } - - private String[] range(int min, int max) { - String[] array = new String[max - min + 1]; - for (int i = min; i <= max; i++) { - array[i] = Integer.toString(i); - } - return array; - } - - private String evaluateFullValue(XValueNodeImpl node) { - final String[] result = new String[1]; - - XFullValueEvaluator.XFullValueEvaluationCallback valueEvaluationCallback = new XFullValueEvaluator.XFullValueEvaluationCallback() { - @Override - public void evaluated(@NotNull String fullValue) { - result[0] = fullValue; - } - - @Override - public void evaluated(@NotNull String fullValue, @Nullable Font font) { - result[0] = fullValue; - } - - @Override - public void errorOccurred(@NotNull String errorMessage) { - result[0] = errorMessage; - } - - @Override - public boolean isObsolete() { - return false; - } - }; - - if (node.getFullValueEvaluator() != null) { - node.getFullValueEvaluator().startEvaluation(valueEvaluationCallback); - } - else { - return node.getRawValue(); - } - - return result[0]; - } - - @Override - @NotNull - protected Action[] createActions() { - return new Action[]{getCancelAction()}; - } - - @Override - protected String getDimensionServiceKey() { - return "#com.jetbrains.python.actions.PyViewArrayAction"; - } - - @Override - protected JComponent createCenterPanel() { - return myComponent; - } - } - - private class MyComponent extends JPanel { - private JScrollPane myScrollPane; - private JTextField myTextField; - private JBTable myTable; - private JCheckBox myCheckBox; - - private static final String DATA_LOADING_IN_PROCESS = "Please wait, load array data."; - - public MyComponent() { - super(new GridBagLayout()); - - myTextField = new JTextField(); - myTextField.setToolTipText("Format"); - - myTable = new JBTable() { - public boolean getScrollableTracksViewportWidth() { - return getPreferredSize().width < getParent().getWidth(); - } - }; - myTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); - - myCheckBox = new JCheckBox(); - myCheckBox.setText("Colored"); - myCheckBox.setSelected(true); - myCheckBox.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if (e.getSource() == myCheckBox) { - if (myTable.getCellRenderer(0, 0) instanceof MyTableCellRenderer) { - MyTableCellRenderer renderer = (MyTableCellRenderer)myTable.getCellRenderer(0, 0); - if (myCheckBox.isSelected()) { - renderer.setColored(true); - } - else { - renderer.setColored(false); - } - } - myScrollPane.repaint(); - } - } - }); - - myScrollPane = new JBScrollPane(myTable); - myScrollPane.setHorizontalScrollBarPolicy(JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - myScrollPane.setVerticalScrollBarPolicy(JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - - JTable rowTable = new RowNumberTable(myTable); - myScrollPane.setRowHeaderView(rowTable); - myScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, - rowTable.getTableHeader()); - - add(myScrollPane, - new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - add(myTextField, - new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - add(myCheckBox, - new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - } - - public JTextField getTextField() { - return myTextField; - } - - public JBTable getTable() { - return myTable; - } - - public JCheckBox getColored() { - return myCheckBox; - } - - public void setDefaultSpinnerText() { - DefaultTableModel model = new DefaultTableModel(1, 1); - myTable.setModel(model); - myTable.setValueAt(DATA_LOADING_IN_PROCESS, 0, 0); - } - } - - - class MyTableCellRenderer extends DefaultTableCellRenderer { - - double min; - double max; - Color minColor; - Color maxColor; - boolean colored = true; - - public MyTableCellRenderer(double min, double max) { - this.min = min; - this.max = max; - minColor = new Color(100, 0, 0, 200); - maxColor = new Color(254, 0, 0, 200); - } - - public void setColored(boolean colored) { - this.colored = colored; - } - - public Component getTableCellRendererComponent(JTable table, Object value, - boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) { - if (isSelected) { - // cell (and perhaps other cells) are selected - } - - if (hasFocus) { - // this cell is the anchor and the table has the focus - } - - if (value != null) { - setText(value.toString()); - } - - - if (max != min) { - if (colored) { - try { - double med = Double.parseDouble(value.toString()); - int r = (int)(minColor.getRed() + Math.round((maxColor.getRed() - minColor.getRed()) / (max - min) * (med - min))); - this.setBackground(new Color(r % 256, 0, 0, 200)); - } - catch (NumberFormatException e) { - } - } - else { - this.setBackground(new Color(255, 255, 255)); - } - } - - - return this; - } - } - - - class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor { - Editor myEditor; - Project myProject; - - public MyTableCellEditor(Project project) { - super(); - myProject = project; - } - - public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, - int rowIndex, int vColIndex) { - - - //PyExpressionCodeFragmentImpl fragment = new PyExpressionCodeFragmentImpl(myProject, "array_view.py", value.toString(), true); - // - //myEditor = EditorFactoryImpl.getInstance(). - // createEditor(PsiDocumentManager.getInstance(myProject).getDocument(fragment), myProject); - - - myEditor = - EditorFactoryImpl.getInstance().createEditor(new DocumentImpl(value.toString()), myProject, PythonFileType.INSTANCE, false); - - - JComponent editorComponent = myEditor.getContentComponent(); - - editorComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) - .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enterStroke"); - editorComponent.getActionMap().put("enterStroke", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - doOKAction(); - } - }); - editorComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) - .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escapeStroke"); - editorComponent.getActionMap().put("escapeStroke", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - cancelEditing(); - } - }); - - return editorComponent; - } - - public Object getCellEditorValue() { - return myEditor.getDocument().getText(); - } - - public void doOKAction() { - //todo: not performed - System.out.println("ok"); - } - - public void cancelEditing() { - System.out.println("esc"); - } - } - - /* - * Use a JTable as a renderer for row numbers of a given main table. - * This table must be added to the row header of the scrollpane that - * contains the main table. - */ - public class RowNumberTable extends JTable - implements ChangeListener, PropertyChangeListener, TableModelListener { - private JTable main; - - public RowNumberTable(JTable table) { - main = table; - main.addPropertyChangeListener(this); - main.getModel().addTableModelListener(this); - - setFocusable(false); - setAutoCreateColumnsFromModel(false); - setSelectionModel(main.getSelectionModel()); - - - TableColumn column = new TableColumn(); - column.setHeaderValue(" "); - addColumn(column); - column.setCellRenderer(new RowNumberRenderer()); - - getColumnModel().getColumn(0).setPreferredWidth(50); - setPreferredScrollableViewportSize(getPreferredSize()); - } - - @Override - public void addNotify() { - super.addNotify(); - - Component c = getParent(); - - // Keep scrolling of the row table in sync with the main table. - - if (c instanceof JViewport) { - JViewport viewport = (JViewport)c; - viewport.addChangeListener(this); - } - } - - /* - * Delegate method to main table - */ - @Override - public int getRowCount() { - return main.getRowCount(); - } - - @Override - public int getRowHeight(int row) { - int rowHeight = main.getRowHeight(row); - - if (rowHeight != super.getRowHeight(row)) { - super.setRowHeight(row, rowHeight); - } - - return rowHeight; - } - - /* - * No model is being used for this table so just use the row number - * as the value of the cell. - */ - @Override - public Object getValueAt(int row, int column) { - return Integer.toString(row + 1); - } - - /* - * Don't edit data in the main TableModel by mistake - */ - @Override - public boolean isCellEditable(int row, int column) { - return false; - } - - /* - * Do nothing since the table ignores the model - */ - @Override - public void setValueAt(Object value, int row, int column) { - } - - // - // Implement the ChangeListener - // - public void stateChanged(ChangeEvent e) { - // Keep the scrolling of the row table in sync with main table - - JViewport viewport = (JViewport)e.getSource(); - JScrollPane scrollPane = (JScrollPane)viewport.getParent(); - scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y); - } - - // - // Implement the PropertyChangeListener - // - public void propertyChange(PropertyChangeEvent e) { - // Keep the row table in sync with the main table - - if ("selectionModel".equals(e.getPropertyName())) { - setSelectionModel(main.getSelectionModel()); - } - - if ("rowHeight".equals(e.getPropertyName())) { - repaint(); - } - - if ("model".equals(e.getPropertyName())) { - main.getModel().addTableModelListener(this); - revalidate(); - } - } - - // - // Implement the TableModelListener - // - @Override - public void tableChanged(TableModelEvent e) { - revalidate(); - } - - /* - * Attempt to mimic the table header renderer - */ - private class RowNumberRenderer extends DefaultTableCellRenderer { - public RowNumberRenderer() { - setHorizontalAlignment(JLabel.CENTER); - } - - public Component getTableCellRendererComponent( - JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - if (table != null) { - JTableHeader header = table.getTableHeader(); - - if (header != null) { - setForeground(header.getForeground()); - setBackground(header.getBackground()); - setFont(header.getFont()); - } - } - - if (isSelected) { - setFont(getFont().deriveFont(Font.BOLD)); - } - - setText((value == null) ? "" : value.toString()); - setBorder(UIManager.getBorder("TableHeader.cellBorder")); - - return this; - } - } - } -} diff --git a/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellEditor.java b/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellEditor.java new file mode 100644 index 000000000000..9ac0c0714b87 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellEditor.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.impl.DocumentImpl; +import com.intellij.openapi.editor.impl.EditorFactoryImpl; +import com.intellij.openapi.project.Project; +import com.jetbrains.python.PythonFileType; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +/** +* @author amarch +*/ +class ArrayTableCellEditor extends AbstractCellEditor implements TableCellEditor { + Editor myEditor; + Project myProject; + + public ArrayTableCellEditor(Project project) { + super(); + myProject = project; + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, + int rowIndex, int vColIndex) { + + + //PyExpressionCodeFragmentImpl fragment = new PyExpressionCodeFragmentImpl(myProject, "array_view.py", value.toString(), true); + // + //myEditor = EditorFactoryImpl.getInstance(). + // createEditor(PsiDocumentManager.getInstance(myProject).getDocument(fragment), myProject); + + + myEditor = + EditorFactoryImpl.getInstance().createEditor(new DocumentImpl(value.toString()), myProject, PythonFileType.INSTANCE, false); + + + JComponent editorComponent = myEditor.getContentComponent(); + + editorComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "enterStroke"); + editorComponent.getActionMap().put("enterStroke", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + doOKAction(); + } + }); + editorComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) + .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escapeStroke"); + editorComponent.getActionMap().put("escapeStroke", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + cancelEditing(); + } + }); + + return editorComponent; + } + + public Object getCellEditorValue() { + return myEditor.getDocument().getText(); + } + + public void doOKAction() { + //todo: not performed + System.out.println("ok"); + } + + public void cancelEditing() { + System.out.println("esc"); + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellRenderer.java b/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellRenderer.java new file mode 100644 index 000000000000..0a9ae77859a0 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/ArrayTableCellRenderer.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; + +/** +* @author amarch +*/ +class ArrayTableCellRenderer extends DefaultTableCellRenderer { + + double min; + double max; + Color minColor; + Color maxColor; + boolean colored = true; + + public ArrayTableCellRenderer(double min, double max) { + this.min = min; + this.max = max; + minColor = new Color(100, 0, 0, 200); + maxColor = new Color(254, 0, 0, 200); + } + + public void setColored(boolean colored) { + this.colored = colored; + } + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) { + if (isSelected) { + // cell (and perhaps other cells) are selected + } + + if (hasFocus) { + // this cell is the anchor and the table has the focus + } + + if (value != null) { + setText(value.toString()); + } + + + if (max != min) { + if (colored) { + try { + double med = Double.parseDouble(value.toString()); + int r = (int)(minColor.getRed() + Math.round((maxColor.getRed() - minColor.getRed()) / (max - min) * (med - min))); + this.setBackground(new Color(r % 256, 0, 0, 200)); + } + catch (NumberFormatException e) { + } + } + else { + this.setBackground(new Color(255, 255, 255)); + } + } + + + return this; + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/ArrayTableComponent.java b/python/src/com/jetbrains/python/actions/view/array/ArrayTableComponent.java new file mode 100644 index 000000000000..b8d739f44f95 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/ArrayTableComponent.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import com.intellij.ui.components.JBScrollPane; +import com.intellij.ui.table.JBTable; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** +* @author amarch +*/ +class ArrayTableComponent extends JPanel { + private JScrollPane myScrollPane; + private JTextField myTextField; + private JBTable myTable; + private JCheckBox myCheckBox; + + private static final String DATA_LOADING_IN_PROCESS = "Please wait, load array data."; + + public ArrayTableComponent() { + super(new GridBagLayout()); + + myTextField = new JTextField(); + myTextField.setToolTipText("Format"); + + myTable = new JBTable() { + public boolean getScrollableTracksViewportWidth() { + return getPreferredSize().width < getParent().getWidth(); + } + }; + myTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + + myCheckBox = new JCheckBox(); + myCheckBox.setText("Colored"); + myCheckBox.setSelected(true); + myCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getSource() == myCheckBox) { + if (myTable.getColumnCount() > 0 && myTable.getCellRenderer(0, 0) instanceof ArrayTableCellRenderer) { + ArrayTableCellRenderer renderer = (ArrayTableCellRenderer)myTable.getCellRenderer(0, 0); + if (myCheckBox.isSelected()) { + renderer.setColored(true); + } + else { + renderer.setColored(false); + } + } + myScrollPane.repaint(); + } + } + }); + + myScrollPane = new JBScrollPane(myTable); + myScrollPane.setHorizontalScrollBarPolicy(JBScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + myScrollPane.setVerticalScrollBarPolicy(JBScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + + JTable rowTable = new RowNumberTable(myTable); + myScrollPane.setRowHeaderView(rowTable); + myScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, + rowTable.getTableHeader()); + + add(myScrollPane, + new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + add(myTextField, + new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + add(myCheckBox, + new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.SOUTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + } + + public JTextField getTextField() { + return myTextField; + } + + public JBTable getTable() { + return myTable; + } + + public JCheckBox getColored() { + return myCheckBox; + } + + public void setDefaultSpinnerText() { + DefaultTableModel model = new DefaultTableModel(1, 1); + myTable.setModel(model); + myTable.setValueAt(DATA_LOADING_IN_PROCESS, 0, 0); + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/ArrayValueProvider.java b/python/src/com/jetbrains/python/actions/view/array/ArrayValueProvider.java new file mode 100644 index 000000000000..895c6e4e3bd1 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/ArrayValueProvider.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +/** +* @author amarch +*/ +abstract class ArrayValueProvider { + + public abstract Object[][] parseValues(String rawValue); +} diff --git a/python/src/com/jetbrains/python/actions/view/array/NumpyArrayValueProvider.java b/python/src/com/jetbrains/python/actions/view/array/NumpyArrayValueProvider.java new file mode 100644 index 000000000000..aa21e11787e5 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/NumpyArrayValueProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +/** +* @author amarch +*/ +class NumpyArrayValueProvider extends ArrayValueProvider { + + @Override + public Object[][] parseValues(String rawValues) { + return null; + } + + private boolean isNumeric(String value) { + return true; + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/PyViewArrayAction.java b/python/src/com/jetbrains/python/actions/view/array/PyViewArrayAction.java new file mode 100644 index 000000000000..247f508b9485 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/PyViewArrayAction.java @@ -0,0 +1,138 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.xdebugger.frame.XFullValueEvaluator; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; + +/** + * @author amarch + */ + +public class PyViewArrayAction extends XDebuggerTreeActionBase { + + @Override + protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) { + final MyDialog dialog = new MyDialog(e.getProject(), node, nodeName); + dialog.setTitle("View Array"); + dialog.setValue(node); + dialog.show(); + } + + + private class MyDialog extends DialogWrapper { + public JTable myTable; + private XValueNodeImpl myNode; + private String myNodeName; + private Project myProject; + private ArrayTableComponent myComponent; + + private MyDialog(Project project, XValueNodeImpl node, @NotNull String nodeName) { + super(project, false); + setModal(false); + setCancelButtonText("Close"); + setCrossClosesWindow(true); + + myNode = node; + myNodeName = nodeName; + myProject = project; + + myComponent = new ArrayTableComponent(); + myTable = myComponent.getTable(); + + init(); + } + + + public void setValue(XValueNodeImpl node) { + final ArrayValueProvider valueProvider; + + if (node.getValuePresentation() != null && + node.getValuePresentation().getType() != null && + node.getValuePresentation().getType().equals("ndarray")) { + valueProvider = new NumpyArrayValueProvider(); + + //myComponent.setDefaultSpinnerText(); + + XDebuggerTreeTableListener tableUpdater = new XDebuggerTreeTableListener(node, myTable, myComponent, myProject); + + node.getTree().addTreeListener(tableUpdater); + + node.startComputingChildren(); + } + } + + private String evaluateFullValue(XValueNodeImpl node) { + final String[] result = new String[1]; + + XFullValueEvaluator.XFullValueEvaluationCallback valueEvaluationCallback = new XFullValueEvaluator.XFullValueEvaluationCallback() { + @Override + public void evaluated(@NotNull String fullValue) { + result[0] = fullValue; + } + + @Override + public void evaluated(@NotNull String fullValue, @Nullable Font font) { + result[0] = fullValue; + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + result[0] = errorMessage; + } + + @Override + public boolean isObsolete() { + return false; + } + }; + + if (node.getFullValueEvaluator() != null) { + node.getFullValueEvaluator().startEvaluation(valueEvaluationCallback); + } + else { + return node.getRawValue(); + } + + return result[0]; + } + + @Override + @NotNull + protected Action[] createActions() { + return new Action[]{getCancelAction()}; + } + + @Override + protected String getDimensionServiceKey() { + return "#com.jetbrains.python.actions.view.array.PyViewArrayAction"; + } + + @Override + protected JComponent createCenterPanel() { + return myComponent; + } + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/RowNumberTable.java b/python/src/com/jetbrains/python/actions/view/array/RowNumberTable.java new file mode 100644 index 000000000000..50c2e55eae76 --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/RowNumberTable.java @@ -0,0 +1,184 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import java.awt.*; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/* +* Use a JTable as a renderer for row numbers of a given main table. +* This table must be added to the row header of the scrollpane that +* contains the main table. +*/ +public class RowNumberTable extends JTable + implements ChangeListener, PropertyChangeListener, TableModelListener { + private JTable main; + + public RowNumberTable(JTable table) { + main = table; + main.addPropertyChangeListener(this); + main.getModel().addTableModelListener(this); + + setFocusable(false); + setAutoCreateColumnsFromModel(false); + setSelectionModel(main.getSelectionModel()); + + + TableColumn column = new TableColumn(); + column.setHeaderValue(" "); + addColumn(column); + column.setCellRenderer(new RowNumberRenderer()); + + getColumnModel().getColumn(0).setPreferredWidth(50); + setPreferredScrollableViewportSize(getPreferredSize()); + } + + @Override + public void addNotify() { + super.addNotify(); + + Component c = getParent(); + + // Keep scrolling of the row table in sync with the main table. + + if (c instanceof JViewport) { + JViewport viewport = (JViewport)c; + viewport.addChangeListener(this); + } + } + + /* + * Delegate method to main table + */ + @Override + public int getRowCount() { + return main.getRowCount(); + } + + @Override + public int getRowHeight(int row) { + int rowHeight = main.getRowHeight(row); + + if (rowHeight != super.getRowHeight(row)) { + super.setRowHeight(row, rowHeight); + } + + return rowHeight; + } + + /* + * No model is being used for this table so just use the row number + * as the value of the cell. + */ + @Override + public Object getValueAt(int row, int column) { + return Integer.toString(row + 1); + } + + /* + * Don't edit data in the main TableModel by mistake + */ + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + + /* + * Do nothing since the table ignores the model + */ + @Override + public void setValueAt(Object value, int row, int column) { + } + + // + // Implement the ChangeListener + // + public void stateChanged(ChangeEvent e) { + // Keep the scrolling of the row table in sync with main table + + JViewport viewport = (JViewport)e.getSource(); + JScrollPane scrollPane = (JScrollPane)viewport.getParent(); + scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y); + } + + // + // Implement the PropertyChangeListener + // + public void propertyChange(PropertyChangeEvent e) { + // Keep the row table in sync with the main table + + if ("selectionModel".equals(e.getPropertyName())) { + setSelectionModel(main.getSelectionModel()); + } + + if ("rowHeight".equals(e.getPropertyName())) { + repaint(); + } + + if ("model".equals(e.getPropertyName())) { + main.getModel().addTableModelListener(this); + revalidate(); + } + } + + // + // Implement the TableModelListener + // + @Override + public void tableChanged(TableModelEvent e) { + revalidate(); + } + + /* + * Attempt to mimic the table header renderer + */ + private class RowNumberRenderer extends DefaultTableCellRenderer { + public RowNumberRenderer() { + setHorizontalAlignment(JLabel.CENTER); + } + + public Component getTableCellRendererComponent( + JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (table != null) { + JTableHeader header = table.getTableHeader(); + + if (header != null) { + setForeground(header.getForeground()); + setBackground(header.getBackground()); + setFont(header.getFont()); + } + } + + if (isSelected) { + setFont(getFont().deriveFont(Font.BOLD)); + } + + setText((value == null) ? "" : value.toString()); + setBorder(UIManager.getBorder("TableHeader.cellBorder")); + + return this; + } + } +} diff --git a/python/src/com/jetbrains/python/actions/view/array/XDebuggerTreeTableListener.java b/python/src/com/jetbrains/python/actions/view/array/XDebuggerTreeTableListener.java new file mode 100644 index 000000000000..d3681581efca --- /dev/null +++ b/python/src/com/jetbrains/python/actions/view/array/XDebuggerTreeTableListener.java @@ -0,0 +1,272 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jetbrains.python.actions.view.array; + +import com.intellij.openapi.project.Project; +import com.intellij.util.containers.HashSet; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeListener; +import com.intellij.xdebugger.impl.ui.tree.nodes.RestorableStateNode; +import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueContainerNode; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.util.List; + +/** +* @author amarch +*/ +public class XDebuggerTreeTableListener implements XDebuggerTreeListener { + + XValueNodeImpl baseNode; + + XValueContainerNode innerNdarray; + + XValueContainerNode innerItems; + + ArrayTableComponent myComponent; + + Project myProject; + + JTable myTable; + + int[] shape; + + int depth = 0; + + int loadedRows = 0; + + HashSet unloadedRowNumbers = new HashSet(); + + boolean baseChildrenLoaded = false; + + boolean numeric = false; + + boolean dataLoaded = false; + + Object[][] data; + + public XDebuggerTreeTableListener(XValueNodeImpl node, JTable table, ArrayTableComponent component, Project project) { + super(); + baseNode = baseNode; + myTable = table; + myComponent = component; + myProject= project; + } + + @Override + public void nodeLoaded(@NotNull RestorableStateNode node, String name) { + System.out.printf(name + " node loaded\n"); + + if (!baseChildrenLoaded && + (shape == null || name.equals("dtype")) && + ((XValueNodeImpl)node.getParent()).getName().equals(baseNode.getName())) { + if (name.equals("shape")) { + String rawValue = node.getRawValue(); + String[] shapes = rawValue.substring(1, rawValue.length() - 1).split(","); + shape = new int[shapes.length]; + for (int i = 0; i < shapes.length; i++) { + shape[i] = Integer.parseInt(shapes[i].trim()); + } + depth = Math.max(shape.length - 2, 0); + } + + if (name.equals("dtype")) { + String rawValue = node.getRawValue(); + if ("biufc".contains(rawValue.substring(0, 1))) { + numeric = true; + } + } + } + } + + @Override + public void childrenLoaded(@NotNull XDebuggerTreeNode node, @NotNull List> children, boolean last) { + System.out.printf(children + "children loaded\n"); + + if (dataLoaded) { + return; + } + + //todo: not compute children if they yet computed + + if (!baseChildrenLoaded && node.equals(baseNode)) { + baseChildrenLoaded = true; + innerNdarray = (XValueContainerNode)node; + if (shape != null) { + if (shape.length >= 2) { + data = new Object[shape[shape.length - 2]][shape[shape.length - 1]]; + } + else { + data = new Object[1][shape[0]]; + } + } + } + + //go deeper + if (depth > 0) { + if (innerNdarray != null && innerNdarray.equals(node)) { + innerNdarray = null; + innerItems = findItems(node); + innerItems.startComputingChildren(); + } + + if (innerItems != null && innerItems.equals(node)) { + innerNdarray = (XValueContainerNode)node.getChildAt(1); + innerItems = null; + innerNdarray.startComputingChildren(); + depth -= 1; + } + + return; + } + + //find ndarray slice to display + if (depth == 0) { + innerItems = findItems(node); + innerItems.startComputingChildren(); + depth -= 1; + return; + } + + if (depth == -1 && node.equals(innerItems)) { + if (shape != null && shape.length == 1) { + for (int i = 0; i < node.getChildCount() - 1; i++) { + data[0][i] = ((XValueNodeImpl)node.getChildAt(i + 1)).getRawValue(); + } + loadData(); + loadedRows = 1; + } + else { + for (int i = 0; i < node.getChildCount() - 1; i++) { + ((XValueNodeImpl)node.getChildAt(i + 1)).startComputingChildren(); + unloadedRowNumbers.add(((XValueNodeImpl)node.getChildAt(i + 1)).getName()); + } + depth -= 1; + } + return; + } + + + if (depth == -2) { + String name = ((XValueNodeImpl)node).getName(); + // ndarrray children not computed yet + if (unloadedRowNumbers.contains(name)) { + unloadedRowNumbers.remove(name); + findItems(node).startComputingChildren(); + return; + } + + if (name.startsWith("[")) { + int row = Integer.parseInt((((XValueNodeImpl)node.getParent()).getName())); + if (data[row][0] == null) { + for (int i = 0; i < node.getChildCount() - 1; i++) { + data[row][i] = ((XValueNodeImpl)node.getChildAt(i + 1)).getRawValue(); + } + loadedRows += 1; + } + } + } + + if (loadedRows == shape[shape.length - 2]) { + loadData(); + } + } + + XValueContainerNode findItems(@NotNull XDebuggerTreeNode node) { + for (int i = 0; i < node.getChildCount(); i++) { + if (node.getChildAt(i).toString().startsWith("[")) { + return (XValueContainerNode)node.getChildAt(i); + } + } + return null; + } + + private String[] range(int min, int max) { + String[] array = new String[max - min + 1]; + for (int i = min; i <= max; i++) { + array[i] = Integer.toString(i); + } + return array; + } + + private void loadData() { + + DefaultTableModel model = new DefaultTableModel(data, range(0, data[0].length - 1)); + + myTable.setModel(model); + myTable.setDefaultEditor(myTable.getColumnClass(0), new ArrayTableCellEditor(myProject)); + + if (numeric) { + double min = Double.MAX_VALUE; + double max = Double.MIN_VALUE; + if (data.length > 0) { + try { + for (int i = 0; i < data.length; i++) { + for (int j = 0; j < data[0].length; j++) { + double d = Double.parseDouble(data[i][j].toString()); + min = min > d ? d : min; + max = max < d ? d : max; + } + } + } + catch (NumberFormatException e) { + min = 0; + max = 0; + } + } + else { + min = 0; + max = 0; + } + + myTable.setDefaultRenderer(myTable.getColumnClass(0), new ArrayTableCellRenderer(min, max)); + } + else { + myComponent.getColored().setSelected(false); + myComponent.getColored().setVisible(false); + } + + myComponent.getTextField().setText(getDefaultSliceRepresentation()); + dataLoaded = true; + innerItems = null; + innerNdarray = null; + } + + public String getDefaultSliceRepresentation() { + String representation = ""; + + if (baseNode != null) { + representation += baseNode.getName(); + if (shape != null && shape.length > 0) { + for (int i = 0; i < shape.length - 2; i++) { + representation += "[0]"; + } + if (shape.length == 1) { + representation += "[0:" + shape[0] + "]"; + } + else { + representation += "[0:" + shape[shape.length - 2] + "][0:" + shape[shape.length - 1] + "]"; + } + } + } + + return representation; + } + +}