From 5833a54c3fda045dd1d1a5c1b79593d3e9aab06c Mon Sep 17 00:00:00 2001 From: anna Date: Sun, 21 Aug 2011 18:42:44 +0200 Subject: [PATCH 1/9] read access --- .../intellij/find/findUsages/JavaFindUsagesHandler.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java index d9dfa1a16155..3218b2dd73d2 100644 --- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java +++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java @@ -424,7 +424,12 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{ addClassesInPackage(aPackage, options.isIncludeSubpackages, classes); for (final PsiClass aClass : classes) { if (progress != null) { - progress.setText(FindBundle.message("find.searching.for.references.to.class.progress", aClass.getName())); + progress.setText(FindBundle.message("find.searching.for.references.to.class.progress", ApplicationManager.getApplication().runReadAction(new Computable(){ + @Override + public String compute() { + return aClass.getName(); + } + }))); } for (PsiFile file : files) { if (progress != null) { From b2ad5fd7be515acba4b606a57410031c8bd9bccb Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 22 Aug 2011 10:52:00 +0200 Subject: [PATCH 2/9] fix test data --- .../inplaceIntroduceField/beforeAssignmentReplaceAll_after.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java index 9d073f824f6d..79053152e42b 100644 --- a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java @@ -3,7 +3,7 @@ class Test { private final String string; Test() { - string = ""; + string = ""; myTimer = string; } } \ No newline at end of file From 5291622673533a812d916ce5889b05a1ebc162d8 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 22 Aug 2011 11:06:40 +0200 Subject: [PATCH 3/9] fire model changed on DnD --- .../src/com/intellij/ui/tabs/FileColorSettingsTable.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorSettingsTable.java b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorSettingsTable.java index 229c8ab019bf..98e2083d496b 100644 --- a/platform/lang-impl/src/com/intellij/ui/tabs/FileColorSettingsTable.java +++ b/platform/lang-impl/src/com/intellij/ui/tabs/FileColorSettingsTable.java @@ -242,6 +242,7 @@ public abstract class FileColorSettingsTable extends JBTable { @Override public void exchangeRows(int oldIndex, int newIndex) { myConfigurations.add(newIndex, myConfigurations.remove(oldIndex)); + fireTableRowsUpdated(Math.min(oldIndex, newIndex), Math.max(oldIndex, newIndex)); } } From 8774dbe130d975f21ac79fbdeb9f8e27e70a9a27 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 22 Aug 2011 11:10:20 +0200 Subject: [PATCH 4/9] care about selection --- .../platform-api/src/com/intellij/ui/TableRowsDnDSupport.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ui/TableRowsDnDSupport.java b/platform/platform-api/src/com/intellij/ui/TableRowsDnDSupport.java index dc339a2f8cff..08fc68df4f09 100644 --- a/platform/platform-api/src/com/intellij/ui/TableRowsDnDSupport.java +++ b/platform/platform-api/src/com/intellij/ui/TableRowsDnDSupport.java @@ -64,11 +64,13 @@ public class TableRowsDnDSupport { model.exchangeRows(min, min + 1); min++; } + table.getSelectionModel().setSelectionInterval(min, min); } else { while (max > min) { model.exchangeRows(max, max - 1); max--; } + table.getSelectionModel().setSelectionInterval(max, max); } } } From 47429a6399ac1bdf3fce2b900dc38796ea6caa1c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 22 Aug 2011 11:11:13 +0200 Subject: [PATCH 5/9] rewrite toolbar decorator to make it easy to support new components --- .../com/intellij/ui/ListToolbarDecorator.java | 81 +++++ .../intellij/ui/TableToolbarDecorator.java | 170 +++++++++++ .../src/com/intellij/ui/ToolbarDecorator.java | 286 +++--------------- .../com/intellij/ui/TreeToolbarDecorator.java | 47 +++ 4 files changed, 338 insertions(+), 246 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/ui/ListToolbarDecorator.java create mode 100644 platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java create mode 100644 platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java diff --git a/platform/platform-api/src/com/intellij/ui/ListToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/ListToolbarDecorator.java new file mode 100644 index 000000000000..ee801910fe18 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/ListToolbarDecorator.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2011 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.intellij.ui; + +import javax.swing.*; + +/** + * @author Konstantin Bulenkov + */ +class ListToolbarDecorator extends ToolbarDecorator { + private final JList myList; + + ListToolbarDecorator(JList list) { + myList = list; + myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = true; + createActions(); + } + + private void createActions() { + myRemoveAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + ListUtil.removeSelectedItems(myList); + updateButtons(); + } + }; + myUpAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + ListUtil.moveSelectedItemsUp(myList); + updateButtons(); + } + }; + myDownAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + ListUtil.moveSelectedItemsDown(myList); + updateButtons(); + } + }; + } + + @Override + protected JComponent getComponent() { + return myList; + } + + @Override + protected void updateButtons() { + final AddRemoveUpDownPanel p = getPanel(); + if (myList.isEnabled() && p != null) { + final int index = myList.getSelectedIndex(); + if (0 <= index && index < myList.getModel().getSize()) { + final boolean downEnable = myList.getMaxSelectionIndex() < myList.getModel().getSize() - 1; + final boolean upEnable = myList.getMinSelectionIndex() > 0; + p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true); + p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable); + p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable); + } else { + p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false); + p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false); + p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false); + } + p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true); + } + + } +} diff --git a/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java new file mode 100644 index 000000000000..02e62f623fdc --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java @@ -0,0 +1,170 @@ +/* + * Copyright 2000-2011 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.intellij.ui; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.util.ui.EditableModel; +import com.intellij.util.ui.ElementProducer; +import com.intellij.util.ui.ListTableModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableModel; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +class TableToolbarDecorator extends ToolbarDecorator { + private final JTable myTable; + private TableModel myTableModel; + + TableToolbarDecorator(@NotNull JTable table, @Nullable final ElementProducer producer) { + myTable = table; + myTableModel = table.getModel(); + myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = myTableModel instanceof EditableModel; + if (myTableModel instanceof EditableModel) { + createDefaultTableActions(producer); + } + myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + updateButtons(); + } + }); + } + + @Override + protected JComponent getComponent() { + return myTable; + } + + protected void updateButtons() { + final AddRemoveUpDownPanel p = getPanel(); + if (myTable.isEnabled() && p != null) { + final int index = myTable.getSelectedRow(); + final int size = myTableModel.getRowCount(); + if (0 <= index && index < size) { + final boolean downEnable = myTable.getSelectionModel().getMaxSelectionIndex() < size - 1; + final boolean upEnable = myTable.getSelectionModel().getMinSelectionIndex() > 0; + p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true); + p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable); + p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable); + } else { + p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false); + p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false); + p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false); + } + p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true); + } + } + + private void createDefaultTableActions(@Nullable final ElementProducer producer) { + final JTable table = myTable; + final EditableModel tableModel = (EditableModel)myTableModel; + + myAddAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + TableUtil.stopEditing(table); + final int rowCount = table.getRowCount(); + if (tableModel instanceof ListTableModel && producer != null) { + //noinspection unchecked + ((ListTableModel)tableModel).addRow(producer.createElement()); + } else { + tableModel.addRow(); + } + if (rowCount == table.getRowCount()) return; + final int index = myTableModel.getRowCount() - 1; + table.editCellAt(index, 0); + table.setRowSelectionInterval(index, index); + table.setColumnSelectionInterval(0, 0); + table.getParent().repaint(); + final Component editorComponent = table.getEditorComponent(); + if (editorComponent != null) { + final Rectangle bounds = editorComponent.getBounds(); + table.scrollRectToVisible(bounds); + editorComponent.requestFocus(); + } + } + }; + + myRemoveAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + TableUtil.stopEditing(table); + int index = table.getSelectedRow(); + if (0 <= index && index < myTableModel.getRowCount()) { + tableModel.removeRow(index); + if (index < myTableModel.getRowCount()) { + table.setRowSelectionInterval(index, index); + } + else { + if (index > 0) { + table.setRowSelectionInterval(index - 1, index - 1); + } + } + updateButtons(); + } + + table.getParent().repaint(); + table.requestFocus(); + } + }; + + myUpAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + TableUtil.stopEditing(table); + final int[] indexes = table.getSelectedRows(); + for (int index : indexes) { + if (0 < index && index < myTableModel.getRowCount()) { + tableModel.exchangeRows(index, index - 1); + table.setRowSelectionInterval(index - 1, index - 1); + } + } + table.requestFocus(); + } + }; + + myDownAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + TableUtil.stopEditing(table); + final int[] indexes = table.getSelectedRows(); + for (int index : indexes) { + if (0 <= index && index < myTableModel.getRowCount() - 1) { + tableModel.exchangeRows(index, index + 1); + table.setRowSelectionInterval(index + 1, index + 1); + } + } + table.requestFocus(); + } + }; + } + + @Override + protected void installDnD() { + if (myUpAction != null && myUpActionEnabled + && myDownAction != null && myDownActionEnabled + && !ApplicationManager.getApplication().isHeadlessEnvironment()) { + TableRowsDnDSupport.install(myTable, (EditableModel)myTableModel); + } + } +} diff --git a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java index b770de236525..75bc3d8a6ae8 100644 --- a/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java +++ b/platform/platform-api/src/com/intellij/ui/ToolbarDecorator.java @@ -17,24 +17,17 @@ package com.intellij.ui; import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.border.CustomLineBorder; import com.intellij.ui.table.TableView; -import com.intellij.util.ui.EditableModel; import com.intellij.util.ui.ElementProducer; -import com.intellij.util.ui.ListTableModel; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.LineBorder; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.table.TableModel; import java.awt.*; import java.util.ArrayList; import java.util.Comparator; @@ -44,23 +37,20 @@ import java.util.List; * @author Konstantin Bulenkov */ @SuppressWarnings("UnusedDeclaration") -public class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.ListenerFactory { - private JTable myTable; - private JTree myTree; - private TableModel myTableModel; +public abstract class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.ListenerFactory { private ListModel myListModel; - private Border myToolbarBorder; - private boolean myAddActionEnabled; - private boolean myRemoveActionEnabled; - private boolean myUpActionEnabled; - private boolean myDownActionEnabled; - private Border myBorder; + protected Border myToolbarBorder; + protected boolean myAddActionEnabled; + protected boolean myRemoveActionEnabled; + protected boolean myUpActionEnabled; + protected boolean myDownActionEnabled; + protected Border myBorder; private List myExtraActions = new ArrayList(); private ActionToolbarPosition myToolbarPosition; - private AnActionButtonRunnable myAddAction; - private AnActionButtonRunnable myRemoveAction; - private AnActionButtonRunnable myUpAction; - private AnActionButtonRunnable myDownAction; + protected AnActionButtonRunnable myAddAction; + protected AnActionButtonRunnable myRemoveAction; + protected AnActionButtonRunnable myUpAction; + protected AnActionButtonRunnable myDownAction; private String myAddName; private String myRemoveName; private String myMoveUpName; @@ -69,6 +59,15 @@ public class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.List private AddRemoveUpDownPanel myPanel; private JList myList; + public ToolbarDecorator() { + } + + protected abstract JComponent getComponent(); + protected abstract void updateButtons(); + + final AddRemoveUpDownPanel getPanel() { + return myPanel; + } private static final Comparator ACTION_BUTTONS_SORTER = new Comparator() { @Override public int compare(AnAction a1, AnAction a2) { @@ -79,214 +78,33 @@ public class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.List } return 0; } - }; + }; - private ToolbarDecorator(JTable table) { - myTable = table; - myTableModel = table.getModel(); - initPositionAndBorder(); - myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = myTableModel instanceof EditableModel; - if (myTableModel instanceof EditableModel) { - createDefaultTableActions(null); - } - } - private ToolbarDecorator(JList list) { - myList = list; - myListModel = list.getModel(); - myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = true; - initPositionAndBorder(); - createDefaultListActions(); - } - - private ToolbarDecorator(TableView table, ElementProducer producer) { - myTable = table; - myTableModel = table.getListTableModel(); - initPositionAndBorder(); - myAddActionEnabled = myRemoveActionEnabled = myUpActionEnabled = myDownActionEnabled = myTableModel instanceof ListTableModel; - if (myTableModel instanceof ListTableModel) { - createDefaultTableActions(producer); - } - } - - public ToolbarDecorator(JTree tree) { - myTree = tree; - initPositionAndBorder(); - } - - private void createDefaultListActions() { - myRemoveAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - ListUtil.removeSelectedItems(myList); - updateListButtons(myList, myPanel); - } - }; - myUpAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - ListUtil.moveSelectedItemsUp(myList); - updateListButtons(myList, myPanel); - } - }; - myDownAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - ListUtil.moveSelectedItemsDown(myList); - updateListButtons(myList, myPanel); - } - }; - } - - private void initPositionAndBorder() { - myToolbarPosition = SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : myTree == null ? ActionToolbarPosition.RIGHT : ActionToolbarPosition.TOP; + protected ToolbarDecorator initPositionAndBorder() { + myToolbarPosition = SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.RIGHT; myBorder = SystemInfo.isMac ? new CustomLineBorder(0,1,1,1) : new CustomLineBorder(0, 1, 0, 0); - if (myTable != null) { - myTable.setBorder(IdeBorderFactory.createEmptyBorder(0)); - } - if (myTree != null) { - myTree.setBorder(IdeBorderFactory.createEmptyBorder(0)); + final JComponent c = getComponent(); + if (c != null) { + c.setBorder(IdeBorderFactory.createEmptyBorder(0)); } + return this; } - private void createDefaultTableActions(@Nullable final ElementProducer producer) { - final JTable table = myTable; - final EditableModel tableModel = (EditableModel)myTableModel; - - myAddAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - TableUtil.stopEditing(table); - final int rowCount = table.getRowCount(); - if (tableModel instanceof ListTableModel && producer != null) { - //noinspection unchecked - ((ListTableModel)tableModel).addRow(producer.createElement()); - } else { - tableModel.addRow(); - } - if (rowCount == table.getRowCount()) return; - final int index = myTableModel.getRowCount() - 1; - table.editCellAt(index, 0); - table.setRowSelectionInterval(index, index); - table.setColumnSelectionInterval(0, 0); - table.getParent().repaint(); - final Component editorComponent = table.getEditorComponent(); - if (editorComponent != null) { - final Rectangle bounds = editorComponent.getBounds(); - table.scrollRectToVisible(bounds); - editorComponent.requestFocus(); - } - } - }; - - myRemoveAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - TableUtil.stopEditing(table); - int index = table.getSelectedRow(); - if (0 <= index && index < myTableModel.getRowCount()) { - tableModel.removeRow(index); - if (index < myTableModel.getRowCount()) { - table.setRowSelectionInterval(index, index); - } - else { - if (index > 0) { - table.setRowSelectionInterval(index - 1, index - 1); - } - } - updateTableButtons(table, tableModel, myPanel); - } - - table.getParent().repaint(); - table.requestFocus(); - } - }; - - myUpAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - TableUtil.stopEditing(table); - final int[] indexes = table.getSelectedRows(); - for (int index : indexes) { - if (0 < index && index < myTableModel.getRowCount()) { - tableModel.exchangeRows(index, index - 1); - table.setRowSelectionInterval(index - 1, index - 1); - } - } - table.requestFocus(); - } - }; - - myDownAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - TableUtil.stopEditing(table); - final int[] indexes = table.getSelectedRows(); - for (int index : indexes) { - if (0 <= index && index < myTableModel.getRowCount() - 1) { - tableModel.exchangeRows(index, index + 1); - table.setRowSelectionInterval(index + 1, index + 1); - } - } - table.requestFocus(); - } - }; - } - - private static void updateListButtons(final JList list, final AddRemoveUpDownPanel p) { - if (list.isEnabled() && p != null) { - final int index = list.getSelectedIndex(); - if (0 <= index && index < list.getModel().getSize()) { - final boolean downEnable = list.getMaxSelectionIndex() < list.getModel().getSize() - 1; - final boolean upEnable = list.getMinSelectionIndex() > 0; - p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true); - p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable); - p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable); - } else { - p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false); - p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false); - p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false); - } - p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true); - } - } - - private static void updateTableButtons(final JTable table, - final EditableModel tableModel, - final AddRemoveUpDownPanel p) { - if (table.isEnabled() && p != null) { - final int index = table.getSelectedRow(); - final int size = ((TableModel)tableModel).getRowCount(); - if (0 <= index && index < size) { - final boolean downEnable = table.getSelectionModel().getMaxSelectionIndex() < size - 1; - final boolean upEnable = table.getSelectionModel().getMinSelectionIndex() > 0; - p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, true); - p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, upEnable); - p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, downEnable); - } else { - p.setEnabled(AddRemoveUpDownPanel.Buttons.REMOVE, false); - p.setEnabled(AddRemoveUpDownPanel.Buttons.UP, false); - p.setEnabled(AddRemoveUpDownPanel.Buttons.DOWN, false); - } - p.setEnabled(AddRemoveUpDownPanel.Buttons.ADD, true); - } - } - - public static ToolbarDecorator createDecorator(@NotNull JTable table) { - return new ToolbarDecorator(table); + return new TableToolbarDecorator(table, null).initPositionAndBorder(); } public static ToolbarDecorator createDecorator(@NotNull JTree tree) { - return new ToolbarDecorator(tree); + return new TreeToolbarDecorator(tree).initPositionAndBorder(); } public static ToolbarDecorator createDecorator(@NotNull JList list) { - return new ToolbarDecorator(list); + return new ListToolbarDecorator(list).initPositionAndBorder(); } public static ToolbarDecorator createDecorator(@NotNull TableView table, ElementProducer producer) { - return new ToolbarDecorator(table, producer); + return new TableToolbarDecorator(table, producer).initPositionAndBorder(); } public ToolbarDecorator disableAddAction() { @@ -385,14 +203,14 @@ public class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.List public JPanel createPanel() { final AddRemoveUpDownPanel.Buttons[] buttons = getButtons(); - myPanel = new AddRemoveUpDownPanel(this, - myTable == null ? myList == null ? myTree : myList : myTable, + final JComponent contextComponent = getComponent(); + myPanel = new AddRemoveUpDownPanel(this, contextComponent, myToolbarPosition == ActionToolbarPosition.TOP || myToolbarPosition == ActionToolbarPosition.BOTTOM, myExtraActions.toArray(new AnActionButton[myExtraActions.size()]), myAddName, myRemoveName, myMoveUpName, myMoveDownName, buttons); myPanel.setBorder(myBorder); - final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable == null ? myList == null ? myTree : myList : myTable); + final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(contextComponent); if (myPreferredSize != null) { scrollPane.setPreferredSize(myPreferredSize); } @@ -401,46 +219,22 @@ public class ToolbarDecorator implements DataProvider, AddRemoveUpDownPanel.List @Override public void addNotify() { super.addNotify(); - if (myList != null) { - updateListButtons(myList, myPanel); - } - if (myTable != null && myTableModel instanceof EditableModel) { - updateTableButtons(myTable, (EditableModel)myTableModel, myPanel); - } + updateButtons(); } }; panel.add(scrollPane, BorderLayout.CENTER); panel.add(myPanel, getPlacement()); - if (myTableModel instanceof EditableModel && buttons.length > 0) { - updateTableButtons(myTable, (EditableModel)myTableModel, myPanel); - - if (myUpAction != null && myUpActionEnabled - && myDownAction != null && myDownActionEnabled - && !ApplicationManager.getApplication().isHeadlessEnvironment()) { - TableRowsDnDSupport.install(myTable, (EditableModel)myTableModel); - } - myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - updateTableButtons(myTable, (EditableModel)myTableModel, myPanel); - } - }); - } - if (myList != null) { - updateListButtons(myList, myPanel); - myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - updateListButtons(myList, myPanel); - } - }); - } + updateButtons(); + installDnD(); panel.setBorder(new LineBorder(UIUtil.getBorderColor())); panel.putClientProperty(ActionToolbar.ACTION_TOOLBAR_PROPERTY_KEY, myPanel.getComponent(0)); DataManager.registerDataProvider(panel, this); return panel; } + protected void installDnD() { + } + @Override public Object getData(@NonNls String dataId) { if (PlatformDataKeys.ACTIONS_SORTER.is(dataId)) { diff --git a/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java new file mode 100644 index 000000000000..0bc9c1e3597a --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2011 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.intellij.ui; + +import com.intellij.openapi.actionSystem.ActionToolbarPosition; +import com.intellij.openapi.util.SystemInfo; + +import javax.swing.*; + +/** + * @author Konstantin Bulenkov + */ +class TreeToolbarDecorator extends ToolbarDecorator { + private final JTree myTree; + + TreeToolbarDecorator(JTree tree) { + myTree = tree; + } + + @Override + protected ToolbarDecorator initPositionAndBorder() { + return super.initPositionAndBorder() + .setToolbarPosition(SystemInfo.isMac ? ActionToolbarPosition.BOTTOM : ActionToolbarPosition.TOP); + } + + @Override + protected JComponent getComponent() { + return myTree; + } + + @Override + protected void updateButtons() { + } +} From 97579406cb558411ac0013616ba2dbafef9298d1 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Mon, 22 Aug 2011 13:16:37 +0400 Subject: [PATCH 6/9] IDEA-73396 AE at com.intellij.openapi.components.impl.ComponentManagerImpl.getComponent Added check for the project 'disposed' state --- .../options/editor/CodeFoldingConfigurable.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingConfigurable.java index cb757f80140b..71cea9eb856d 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/CodeFoldingConfigurable.java @@ -85,13 +85,16 @@ public class CodeFoldingConfigurable extends CompositeConfigurable each : toUpdate) { - final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(each.second); - if (foldingManager != null) { - foldingManager.buildInitialFoldings(each.first); + for (Pair each : toUpdate) { + if (each.second == null || each.second.isDisposed()) { + continue; + } + final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(each.second); + if (foldingManager != null) { + foldingManager.buildInitialFoldings(each.first); + } } - } - EditorOptionsPanel.reinitAllEditors(); + EditorOptionsPanel.reinitAllEditors(); } }, ModalityState.NON_MODAL); } From 5b8641347cd72306273dc1607d0d8940e8941d83 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 10 Aug 2011 17:51:28 +0400 Subject: [PATCH 7/9] PersistentMap interface extracted --- .../util/indexing/MapIndexStorage.java | 132 ++--------------- .../util/indexing/ValueContainerMap.java | 134 ++++++++++++++++++ .../intellij/util/io/PersistentHashMap.java | 4 +- .../com/intellij/util/io/PersistentMap.java | 29 ++++ 4 files changed, 179 insertions(+), 120 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java create mode 100644 platform/util/src/com/intellij/util/io/PersistentMap.java diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java index d19589c47fba..63cf323519f8 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapIndexStorage.java @@ -17,22 +17,16 @@ package com.intellij.util.indexing; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.containers.SLRUCache; -import com.intellij.util.io.DataExternalizer; -import com.intellij.util.io.DataInputOutputUtil; -import com.intellij.util.io.KeyDescriptor; -import com.intellij.util.io.PersistentHashMap; -import gnu.trove.TIntHashSet; +import com.intellij.util.io.*; import org.jetbrains.annotations.NotNull; import java.io.*; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -43,28 +37,29 @@ import java.util.concurrent.locks.ReentrantLock; */ public final class MapIndexStorage implements IndexStorage{ private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.MapIndexStorage"); - private PersistentHashMap> myMap; + private PersistentMap> myMap; private SLRUCache> myCache; private final File myStorageFile; private final KeyDescriptor myKeyDescriptor; - private final ValueContainerExternalizer myValueContainerExternalizer; private final int myCacheSize; private final Lock l = new ReentrantLock(); + private final DataExternalizer myDataExternalizer; - public MapIndexStorage(File storageFile, final KeyDescriptor keyDescriptor, final DataExternalizer valueExternalizer, + public MapIndexStorage(File storageFile, final KeyDescriptor keyDescriptor, + final DataExternalizer valueExternalizer, final int cacheSize) throws IOException { myStorageFile = storageFile; myKeyDescriptor = keyDescriptor; - myValueContainerExternalizer = new ValueContainerExternalizer(valueExternalizer); myCacheSize = cacheSize; + myDataExternalizer = valueExternalizer; initMapAndCache(); } private void initMapAndCache() throws IOException { - final PersistentHashMap> map = - new PersistentHashMap>(myStorageFile, myKeyDescriptor, myValueContainerExternalizer); + final PersistentMap> map = + new ValueContainerMap(myStorageFile, myKeyDescriptor, myDataExternalizer); myCache = new SLRUCache>(myCacheSize, (int)(Math.ceil(myCacheSize * 0.25)) /* 25% from the main cache size*/) { @NotNull public ChangeTrackingValueContainer createValue(final Key key) { @@ -74,7 +69,7 @@ public final class MapIndexStorage implements IndexStorage compute() { - ValueContainer value = null; + ValueContainer value; try { value = map.get(key); if (value == null) { @@ -90,43 +85,13 @@ public final class MapIndexStorage implements IndexStorage valueContainer) { - if (!valueContainer.isDirty()) { - return; - } - try { - if (!valueContainer.needsCompacting()) { - final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); - //noinspection IOResourceOpenedButNotSafelyClosed - final DataOutputStream _out = new DataOutputStream(bytes); - final TIntHashSet set = valueContainer.getInvalidated(); - if (set.size() > 0) { - for (int inputId : set.toArray()) { - myValueContainerExternalizer.saveInvalidateCommand(_out, inputId); - } - } - final ValueContainer toRemove = valueContainer.getRemovedDelta(); - if (toRemove.size() > 0) { - myValueContainerExternalizer.saveAsRemoved(_out, toRemove); - } - - final ValueContainer toAppend = valueContainer.getAddedDelta(); - if (toAppend.size() > 0) { - myValueContainerExternalizer.save(_out, toAppend); - } - - map.appendData(key, new PersistentHashMap.ValueDataAppender() { - public void append(final DataOutput out) throws IOException { - out.write(bytes.getInternalBuffer(), 0, bytes.size()); - } - }); - } - else { - // rewrite the value container for defragmentation + if (valueContainer.isDirty()) { + try { map.put(key, valueContainer); } - } - catch (IOException e) { - throw new RuntimeException(e); + catch (IOException e) { + throw new RuntimeException(e); + } } } }; @@ -275,73 +240,4 @@ public final class MapIndexStorage implements IndexStorage implements DataExternalizer> { - private final DataExternalizer myExternalizer; - - private ValueContainerExternalizer(DataExternalizer externalizer) { - myExternalizer = externalizer; - } - - public void save(final DataOutput out, final ValueContainer container) throws IOException { - saveImpl(out, container, false); - } - - public void saveAsRemoved(final DataOutput out, final ValueContainer container) throws IOException { - saveImpl(out, container, true); - } - - public void saveInvalidateCommand(final DataOutput out, int inputId) throws IOException { - DataInputOutputUtil.writeSINT(out, -inputId); - } - - private void saveImpl(final DataOutput out, final ValueContainer container, final boolean asRemovedData) throws IOException { - DataInputOutputUtil.writeSINT(out, container.size()); - for (final Iterator valueIterator = container.getValueIterator(); valueIterator.hasNext();) { - final T value = valueIterator.next(); - myExternalizer.save(out, value); - - final ValueContainer.IntIterator ids = container.getInputIdsIterator(value); - if (ids != null) { - DataInputOutputUtil.writeSINT(out, ids.size()); - while (ids.hasNext()) { - final int id = ids.next(); - DataInputOutputUtil.writeSINT(out, asRemovedData ? -id : id); - } - } - else { - DataInputOutputUtil.writeSINT(out, 0); - } - } - } - - public ValueContainerImpl read(final DataInput in) throws IOException { - DataInputStream stream = (DataInputStream)in; - final ValueContainerImpl valueContainer = new ValueContainerImpl(); - - while (stream.available() > 0) { - final int valueCount = DataInputOutputUtil.readSINT(in); - if (valueCount < 0) { - valueContainer.removeAllValues(-valueCount); - valueContainer.setNeedsCompacting(true); - } - else { - for (int valueIdx = 0; valueIdx < valueCount; valueIdx++) { - final T value = myExternalizer.read(in); - final int idCount = DataInputOutputUtil.readSINT(in); - for (int i = 0; i < idCount; i++) { - final int id = DataInputOutputUtil.readSINT(in); - if (id < 0) { - valueContainer.removeValue(-id, value); - valueContainer.setNeedsCompacting(true); - } - else { - valueContainer.addValue(id, value); - } - } - } - } - } - return valueContainer; - } - } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java new file mode 100644 index 000000000000..da356061ab0d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/ValueContainerMap.java @@ -0,0 +1,134 @@ +package com.intellij.util.indexing; + +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.util.io.DataExternalizer; +import com.intellij.util.io.DataInputOutputUtil; +import com.intellij.util.io.KeyDescriptor; +import com.intellij.util.io.PersistentHashMap; +import gnu.trove.TIntHashSet; + +import java.io.*; +import java.util.Iterator; + +/** + * @author Dmitry Avdeev + * Date: 8/10/11 + */ +public class ValueContainerMap extends PersistentHashMap> { + + private final ValueContainerExternalizer myValueContainerExternalizer; + + public ValueContainerMap(final File file, + KeyDescriptor keyKeyDescriptor, + DataExternalizer valueExternalizer) throws IOException { + + super(file, keyKeyDescriptor, new ValueContainerExternalizer(valueExternalizer)); + myValueContainerExternalizer = (ValueContainerExternalizer)myValueExternalizer; + } + + @Override + public synchronized void put(Key key, ValueContainer container) throws IOException { + ChangeTrackingValueContainer valueContainer = (ChangeTrackingValueContainer)container; + if (!valueContainer.needsCompacting()) { + final BufferExposingByteArrayOutputStream bytes = new BufferExposingByteArrayOutputStream(); + //noinspection IOResourceOpenedButNotSafelyClosed + final DataOutputStream _out = new DataOutputStream(bytes); + final TIntHashSet set = valueContainer.getInvalidated(); + if (set.size() > 0) { + for (int inputId : set.toArray()) { + ValueContainerExternalizer.saveInvalidateCommand(_out, inputId); + } + } + final ValueContainer toRemove = valueContainer.getRemovedDelta(); + if (toRemove.size() > 0) { + myValueContainerExternalizer.saveAsRemoved(_out, toRemove); + } + + final ValueContainer toAppend = valueContainer.getAddedDelta(); + if (toAppend.size() > 0) { + myValueContainerExternalizer.save(_out, toAppend); + } + + appendData(key, new PersistentHashMap.ValueDataAppender() { + public void append(final DataOutput out) throws IOException { + out.write(bytes.getInternalBuffer(), 0, bytes.size()); + } + }); + } + else { + // rewrite the value container for defragmentation + super.put(key, valueContainer); + } + } + + private static final class ValueContainerExternalizer implements DataExternalizer> { + private final DataExternalizer myExternalizer; + + private ValueContainerExternalizer(DataExternalizer externalizer) { + myExternalizer = externalizer; + } + + public void save(final DataOutput out, final ValueContainer container) throws IOException { + saveImpl(out, container, false); + } + + public void saveAsRemoved(final DataOutput out, final ValueContainer container) throws IOException { + saveImpl(out, container, true); + } + + public static void saveInvalidateCommand(final DataOutput out, int inputId) throws IOException { + DataInputOutputUtil.writeSINT(out, -inputId); + } + + private void saveImpl(final DataOutput out, final ValueContainer container, final boolean asRemovedData) throws IOException { + DataInputOutputUtil.writeSINT(out, container.size()); + for (final Iterator valueIterator = container.getValueIterator(); valueIterator.hasNext();) { + final T value = valueIterator.next(); + myExternalizer.save(out, value); + + final ValueContainer.IntIterator ids = container.getInputIdsIterator(value); + if (ids != null) { + DataInputOutputUtil.writeSINT(out, ids.size()); + while (ids.hasNext()) { + final int id = ids.next(); + DataInputOutputUtil.writeSINT(out, asRemovedData ? -id : id); + } + } + else { + DataInputOutputUtil.writeSINT(out, 0); + } + } + } + + public ValueContainerImpl read(final DataInput in) throws IOException { + DataInputStream stream = (DataInputStream)in; + final ValueContainerImpl valueContainer = new ValueContainerImpl(); + + while (stream.available() > 0) { + final int valueCount = DataInputOutputUtil.readSINT(in); + if (valueCount < 0) { + valueContainer.removeAllValues(-valueCount); + valueContainer.setNeedsCompacting(true); + } + else { + for (int valueIdx = 0; valueIdx < valueCount; valueIdx++) { + final T value = myExternalizer.read(in); + final int idCount = DataInputOutputUtil.readSINT(in); + for (int i = 0; i < idCount; i++) { + final int id = DataInputOutputUtil.readSINT(in); + if (id < 0) { + valueContainer.removeValue(-id, value); + valueContainer.setNeedsCompacting(true); + } + else { + valueContainer.addValue(id, value); + } + } + } + } + } + return valueContainer; + } + } + +} diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java index 00e1fed872ed..50285ae9bace 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java @@ -38,11 +38,11 @@ import java.util.List; * @author Eugene Zhuravlev * Date: Dec 18, 2007 */ -public class PersistentHashMap extends PersistentEnumeratorDelegate{ +public class PersistentHashMap extends PersistentEnumeratorDelegate implements PersistentMap { private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.PersistentHashMap"); private PersistentHashMapValueStorage myValueStorage; - private final DataExternalizer myValueExternalizer; + protected final DataExternalizer myValueExternalizer; private static final long NULL_ADDR = 0; private static final int INITIAL_INDEX_SIZE; static { diff --git a/platform/util/src/com/intellij/util/io/PersistentMap.java b/platform/util/src/com/intellij/util/io/PersistentMap.java new file mode 100644 index 000000000000..f39ab275667b --- /dev/null +++ b/platform/util/src/com/intellij/util/io/PersistentMap.java @@ -0,0 +1,29 @@ +package com.intellij.util.io; + +import com.intellij.util.Processor; + +import java.io.IOException; + +/** + * @author Dmitry Avdeev + * Date: 8/10/11 + */ +public interface PersistentMap { + + V get(K key) throws IOException; + + void put(K key, V value) throws IOException; + + boolean processKeys(Processor processor) throws IOException; + + + boolean isClosed(); + + boolean isDirty(); + + void force(); + + void close() throws IOException; + + void markDirty() throws IOException; +} From 008c25133316709308eeeae34446c2f1e823656b Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Fri, 19 Aug 2011 18:59:11 +0400 Subject: [PATCH 8/9] native File.length() + save file size on vfs initialization --- bin/win/IdeaWin32.dll | Bin 9216 -> 9216 bytes native/IdeaWin32/IdeaWin32.cpp | 7 ++++ .../vfs/impl/local/LocalFileSystemBase.java | 8 ++++- .../openapi/vfs/impl/win32/FileInfo.java | 1 + .../openapi/vfs/impl/win32/Win32Kernel.java | 4 +++ .../vfs/impl/win32/Win32LocalFileSystem.java | 17 ++++++++-- .../vfs/newvfs/impl/VirtualDirectoryImpl.java | 24 ++++++++----- .../vfs/newvfs/persistent/PersistentFS.java | 32 +++++++++++++----- .../vfs/newvfs/persistent/RefreshWorker.java | 13 ++----- 9 files changed, 75 insertions(+), 31 deletions(-) diff --git a/bin/win/IdeaWin32.dll b/bin/win/IdeaWin32.dll index fc8c95a97aeb2daa19a41ca11aec96fb9d8240e1..068dd30aecb07b6fded18468ae0e0c345175ef02 100644 GIT binary patch delta 924 zcmYk5ZAepL6vyv#o!d2Mo3<-U%+2gWDyDO+!cEuPY+9>rIMh z>3|pN64DKy)zzd6M2!ifO;d^SfJPJsP#7u>4#2RckPN^Cf^JA?)?2#}gwuQ|uh*13 zmCbSObN4xplWokI+CpYdFVD0`T-vj7-I;R=2|}^p$YETbk!?XZAZ*MF;x5Wk)_All zc3n8ZlRhx!ZqR0A5!WnJ`g5yRDv7~Q@=W--AsUR0h8M_nl|&1*qR9}P%K{T@7w1*zbpBJ0pkU6SHD%z#H5P8fX2 z(|=?+{9NVtQjxW~tT~_2P@g#xNHZ6Aam2Gk1519o+Lgvqto!9sok}SQ8uc63>6Px% z)RRVx@_!?jV_M1K_*F2aHxmaW^ku{ipY<&zUUoT1jw~nx_u@RP*LfdHs-ZQ%j(@WV zkl!dSerG9WO0Fe?b$e zhDQbas?7h&jZ3VY((Bm7)Uuy_iCv18dQ#Tu&C$bM5Z<^zAwc&bMiVI#D zcCBc}UEiVpo=^}9#Dh3ef_K1uQMdNmhHZByhvPdhe=M&^-u{w9P`JIWqxIyuhkLTg#C*Bmi?>U=&(2fj?<3P n`sVsb{dmLmhF=X8&Q9k+CmNfTmz%12SM#Cfu_X>$%O3s(c0+H2 delta 854 zcmX|9Z%9*76n}Tly(ezEIiHw`TiFLetmRmdu3705rw+H_GoL8M?sK_Jtluo9HS4}B>rVWPyy3C~!)?t2q2?;Lo)-|zg+IhQ+FH&_=! zO8ri#0hFjw!CSzM>X8#3qGEIvX3=p}2Ro<!hH35`Y`C_bdA0%l4Z_QN@q7oCN7 zsv_irHPsR11(r6DY@tg@?xI1ev2@Z{#s^ zS%CtOpLtlFl8tabC8ayFEK3IZzlp2-d~Vnu8P8lyBTIH<7t}YB@__OHNeoHYqjqBl z6I)J*Vz`b_opTKJY4>>WCcnvGPV1B;cZg(!6ZoJ&_0#6)`Vf50HVoLdB{azglT^Rb z9NlQeT+)d(PGaT49zixAC6$;{W5$J9sl6L>f^7LnA{=UdHrEw<@=p}`d8ONlS!s?v z&9q!B;I+=Tsj*U1z2}nTnkbmo8V>p783gPQNXsOtRLkzy2rOe{_#ni!Ml=RGT`{^3 z7F}~ujkG;s-u#vph<8(%i<7cVmjt%JQ(c8(e*%8!YT0U{z>c_Ud~)KiC=z?d8G8n{ zoYH+;TZHi>_&GGSetObjectField(o, nameID, fileName); env->SetIntField(o, attributesID, lpData->dwFileAttributes); env->SetLongField(o, timestampID, fileTimeToInt64(&lpData->ftLastWriteTime)); + + ULARGE_INTEGER size; + size.LowPart = lpData->nFileSizeLow; + size.HighPart = lpData->nFileSizeHigh; + env->SetLongField(o, lengthID, size.QuadPart); return o; } @@ -59,6 +65,7 @@ JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;"); attributesID = env->GetFieldID(cls, "attributes", "I"); timestampID = env->GetFieldID(cls, "timestamp", "J"); + lengthID = env->GetFieldID(cls, "length", "J"); } JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java index b7dd59c55ed4..bca4f936c4db 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java @@ -408,7 +408,13 @@ public abstract class LocalFileSystemBase extends LocalFileSystem { @NotNull public byte[] contentsToByteArray(@NotNull final VirtualFile file) throws IOException { - return FileUtil.loadFileBytes(convertToIOFile(file)); + FileInputStream stream = new FileInputStream(convertToIOFile(file)); + try { + return FileUtil.loadBytes(stream, (int)file.getLength()); + } + finally { + stream.close(); + } } @NotNull diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java index 5a121418eb38..ea85f580259f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/FileInfo.java @@ -29,6 +29,7 @@ public class FileInfo { public String name; public int attributes; public long timestamp; + public long length; public String toString() { return name; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java index 638b957f6fda..4cda8acc9758 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32Kernel.java @@ -81,6 +81,10 @@ public class Win32Kernel { return timestamp / 10000 - 11644473600000l; } + public long getLength(String path) throws FileNotFoundException { + return getInfo(path).length; + } + private FileInfo getInfo(String path) throws FileNotFoundException { FileInfo info = myCache.get(path); if (info == null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java index 52edbe4930c6..b6a2c889cd18 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java @@ -63,7 +63,7 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { } private final Win32Kernel myKernel = new Win32Kernel(); - public static boolean checkMe = false; + public static boolean checkMe = true; private Win32LocalFileSystem() { } @@ -134,7 +134,6 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { try { long timeStamp = myKernel.getTimeStamp(file.getPath()); if (checkMe && timeStamp != super.getTimeStamp(file)) { - timeStamp = myKernel.getTimeStamp(file.getPath()); LOG.error(file.getPath()); } return timeStamp; @@ -145,6 +144,20 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { } @Override + public long getLength(@NotNull VirtualFile file) { + try { + long length = myKernel.getLength(file.getPath()); + if (checkMe && length != super.getLength(file)) { + LOG.error(file.getPath()); + } + return length; + } + catch (FileNotFoundException e) { + return super.getLength(file); + } + } + + @Override public WatchRequest addRootToWatch(@NotNull String rootPath, boolean toWatchRecursively) { throw new UnsupportedOperationException(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java index f0a0b471aaa3..aeadc67f8506 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualDirectoryImpl.java @@ -81,8 +81,11 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - private VirtualFileSystemEntry findChild(@NotNull String name, final boolean createIfNotFound, boolean ensureCanonicalName) { - final VirtualFileSystemEntry result = doFindChild(name, createIfNotFound, ensureCanonicalName); + private VirtualFileSystemEntry findChild(@NotNull String name, + final boolean createIfNotFound, + boolean ensureCanonicalName, + NewVirtualFileSystem delegate) { + final VirtualFileSystemEntry result = doFindChild(name, createIfNotFound, ensureCanonicalName, delegate); if (result == NULL_VIRTUAL_FILE) { return createIfNotFound ? createAndFindChildWithEventFire(name) : null; } @@ -100,7 +103,10 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } @Nullable - private VirtualFileSystemEntry doFindChild(@NotNull String name, final boolean createIfNotFound, boolean ensureCanonicalName) { + private VirtualFileSystemEntry doFindChild(@NotNull String name, + final boolean createIfNotFound, + boolean ensureCanonicalName, + NewVirtualFileSystem delegate) { if (name.length() == 0) { return null; } @@ -130,7 +136,6 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { if (file != null) return file; if (ensureCanonicalName) { - final NewVirtualFileSystem delegate = getFileSystem(); VirtualFile fake = new FakeVirtualFile(this, name); name = delegate.getCanonicallyCasedName(fake); if (name.length() == 0) return null; @@ -138,7 +143,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { synchronized (this) { // do not extract getId outside the synchronized block since it will cause a concurrency problem. - int id = PersistentFS.getId(this, name); + int id = PersistentFS.getId(this, name, delegate); if (id > 0) { // maybe another doFindChild() sneaked in the middle VirtualFileSystemEntry lastTry = map.get(name); @@ -304,7 +309,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { @Nullable public NewVirtualFile refreshAndFindChild(@NotNull String name) { - return findChild(name, true, true); + return findChild(name, true, true, getFileSystem()); } @Nullable @@ -353,8 +358,9 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } final String[] names = PersistentFS.listPersisted(this); + NewVirtualFileSystem delegate = PersistentFS.replaceWithNativeFS(getFileSystem()); for (String name : names) { - findChild(name, false, false); + findChild(name, false, false, delegate); } // important: should return a copy here for safe iterations @@ -395,7 +401,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { @Nullable public VirtualFileSystemEntry findChild(@NotNull final String name) { - return findChild(name, false, true); + return findChild(name, false, true, getFileSystem()); } @Nullable @@ -406,7 +412,7 @@ public class VirtualDirectoryImpl extends VirtualFileSystemEntry { } String name = ourPersistence.getName(id); - return findChild(name, false, false); + return findChild(name, false, false, getFileSystem()); } public NewVirtualFile findChildByIdIfCached(int id) { diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java index 23301ecff9fd..cfc1dd1b2baf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java @@ -26,10 +26,13 @@ import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ShutDownTracker; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem; import com.intellij.openapi.vfs.newvfs.*; import com.intellij.openapi.vfs.newvfs.events.*; import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; @@ -296,10 +299,15 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { FSRecords.setParent(id, parentId); FSRecords.setName(id, name); - FSRecords.setTimestamp(id, delegate.getTimeStamp(file)); - FSRecords.setFlags(id, (delegate.isDirectory(file) ? IS_DIRECTORY_FLAG : 0) | (delegate.isWritable(file) ? 0 : IS_READ_ONLY), true); + delegate = replaceWithNativeFS(delegate); - FSRecords.setLength(id, -1L); + FSRecords.setTimestamp(id, delegate.getTimeStamp(file)); + + boolean directory = delegate.isDirectory(file); + + FSRecords.setLength(id, directory ? -1L : delegate.getLength(file)); + + FSRecords.setFlags(id, (directory ? IS_DIRECTORY_FLAG : 0) | (delegate.isWritable(file) ? 0 : IS_READ_ONLY), true); // TODO!!!: More attributes? } @@ -358,8 +366,7 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { processEvent(new VFilePropertyChangeEvent(this, file, VirtualFile.PROP_WRITABLE, isWritable(file), writableFlag, false)); } - public static int getId(final VirtualFile parent, final String childName) { - final NewVirtualFileSystem delegate = getDelegate(parent); + public static int getId(final VirtualFile parent, final String childName, NewVirtualFileSystem delegate) { final int parentId = getFileId(parent); final int[] children = FSRecords.list(parentId); @@ -438,8 +445,6 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { processEvent(new VFilePropertyChangeEvent(requestor, file, VirtualFile.PROP_NAME, file.getName(), newName, false)); } - private static final boolean noCaching = Boolean.parseBoolean(System.getProperty("idea.no.content.caching")); - @NotNull public byte[] contentsToByteArray(@NotNull final VirtualFile file) throws IOException { return contentsToByteArray(file, true); @@ -458,8 +463,10 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { final byte[] content = delegate.contentsToByteArray(file); ApplicationEx application = (ApplicationEx)ApplicationManager.getApplication(); + // we should cache every local files content + // because the local history feature is currently depends on this cache if ((!delegate.isReadOnly() || !application.isInternal() && !application.isUnitTestMode()) && - !noCaching && content.length <= FILE_LENGTH_TO_CACHE_THRESHOLD) { + content.length <= FILE_LENGTH_TO_CACHE_THRESHOLD) { synchronized (INPUT_LOCK) { writeContent(file, new ByteSequence(content), delegate.isReadOnly()); @@ -1039,4 +1046,13 @@ public class PersistentFS extends ManagingFS implements ApplicationComponent { return maxLimitBytes; } } + + public static NewVirtualFileSystem replaceWithNativeFS(NewVirtualFileSystem delegate) { + if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL) && Registry.is("filesystem.useNative")) { + if (SystemInfo.isWindows && Win32LocalFileSystem.isAvailable()) { + delegate = Win32LocalFileSystem.getWin32Instance(); + } + } + return delegate; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 6f00cb6b4e17..04c43ca5dc77 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -19,12 +19,8 @@ */ package com.intellij.openapi.vfs.newvfs.persistent; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.impl.win32.Win32LocalFileSystem; import com.intellij.openapi.vfs.newvfs.ManagingFS; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; @@ -57,13 +53,8 @@ public class RefreshWorker { root.markClean(); } else { - if (delegate.getProtocol().equals(LocalFileSystem.PROTOCOL) && - root.isDirectory() && - Registry.is("filesystem.useNative")) { - - if (SystemInfo.isWindows && Win32LocalFileSystem.isAvailable()) { - delegate = Win32LocalFileSystem.getWin32Instance(); - } + if (root.isDirectory()) { + delegate = PersistentFS.replaceWithNativeFS(delegate); } final PersistentFS persistence = (PersistentFS)ManagingFS.getInstance(); From 0cc8ea56d68843741a1fe780715926ed91d47e95 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 22 Aug 2011 13:07:47 +0400 Subject: [PATCH 9/9] native File.length() + save file size on vfs initialization --- .../intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java index b6a2c889cd18..ee771618520f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/win32/Win32LocalFileSystem.java @@ -63,7 +63,7 @@ public class Win32LocalFileSystem extends LocalFileSystemBase { } private final Win32Kernel myKernel = new Win32Kernel(); - public static boolean checkMe = true; + public static boolean checkMe = false; private Win32LocalFileSystem() { }