mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
Binary file not shown.
@@ -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<String>(){
|
||||
@Override
|
||||
public String compute() {
|
||||
return aClass.getName();
|
||||
}
|
||||
})));
|
||||
}
|
||||
for (PsiFile file : files) {
|
||||
if (progress != null) {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ class Test {
|
||||
private final String string;
|
||||
|
||||
Test() {
|
||||
string =<caret> "";
|
||||
<caret>string = "";
|
||||
myTimer = string;
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ fileTimeToInt64 (const FILETIME * time)
|
||||
jfieldID nameID;
|
||||
jfieldID attributesID;
|
||||
jfieldID timestampID;
|
||||
jfieldID lengthID;
|
||||
|
||||
jobject CreateFileInfo(JNIEnv *env, LPWIN32_FIND_DATA lpData, jclass cls) {
|
||||
|
||||
@@ -52,6 +53,11 @@ jobject CreateFileInfo(JNIEnv *env, LPWIN32_FIND_DATA lpData, jclass cls) {
|
||||
env->SetObjectField(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) {
|
||||
|
||||
+9
-6
@@ -85,13 +85,16 @@ public class CodeFoldingConfigurable extends CompositeConfigurable<CodeFoldingOp
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
for (Pair<Editor, Project> each : toUpdate) {
|
||||
final CodeFoldingManager foldingManager = CodeFoldingManager.getInstance(each.second);
|
||||
if (foldingManager != null) {
|
||||
foldingManager.buildInitialFoldings(each.first);
|
||||
for (Pair<Editor, Project> 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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Key, Value> implements IndexStorage<Key, Value>{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.MapIndexStorage");
|
||||
private PersistentHashMap<Key, ValueContainer<Value>> myMap;
|
||||
private PersistentMap<Key, ValueContainer<Value>> myMap;
|
||||
private SLRUCache<Key, ChangeTrackingValueContainer<Value>> myCache;
|
||||
private final File myStorageFile;
|
||||
private final KeyDescriptor<Key> myKeyDescriptor;
|
||||
private final ValueContainerExternalizer<Value> myValueContainerExternalizer;
|
||||
private final int myCacheSize;
|
||||
|
||||
private final Lock l = new ReentrantLock();
|
||||
private final DataExternalizer<Value> myDataExternalizer;
|
||||
|
||||
public MapIndexStorage(File storageFile, final KeyDescriptor<Key> keyDescriptor, final DataExternalizer<Value> valueExternalizer,
|
||||
public MapIndexStorage(File storageFile, final KeyDescriptor<Key> keyDescriptor,
|
||||
final DataExternalizer<Value> valueExternalizer,
|
||||
final int cacheSize) throws IOException {
|
||||
|
||||
myStorageFile = storageFile;
|
||||
myKeyDescriptor = keyDescriptor;
|
||||
myValueContainerExternalizer = new ValueContainerExternalizer<Value>(valueExternalizer);
|
||||
myCacheSize = cacheSize;
|
||||
myDataExternalizer = valueExternalizer;
|
||||
initMapAndCache();
|
||||
}
|
||||
|
||||
private void initMapAndCache() throws IOException {
|
||||
final PersistentHashMap<Key, ValueContainer<Value>> map =
|
||||
new PersistentHashMap<Key, ValueContainer<Value>>(myStorageFile, myKeyDescriptor, myValueContainerExternalizer);
|
||||
final PersistentMap<Key, ValueContainer<Value>> map =
|
||||
new ValueContainerMap<Key, Value>(myStorageFile, myKeyDescriptor, myDataExternalizer);
|
||||
myCache = new SLRUCache<Key, ChangeTrackingValueContainer<Value>>(myCacheSize, (int)(Math.ceil(myCacheSize * 0.25)) /* 25% from the main cache size*/) {
|
||||
@NotNull
|
||||
public ChangeTrackingValueContainer<Value> createValue(final Key key) {
|
||||
@@ -74,7 +69,7 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
|
||||
}
|
||||
|
||||
public ValueContainer<Value> compute() {
|
||||
ValueContainer<Value> value = null;
|
||||
ValueContainer<Value> value;
|
||||
try {
|
||||
value = map.get(key);
|
||||
if (value == null) {
|
||||
@@ -90,43 +85,13 @@ public final class MapIndexStorage<Key, Value> implements IndexStorage<Key, Valu
|
||||
}
|
||||
|
||||
protected void onDropFromCache(final Key key, final ChangeTrackingValueContainer<Value> 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<Value> toRemove = valueContainer.getRemovedDelta();
|
||||
if (toRemove.size() > 0) {
|
||||
myValueContainerExternalizer.saveAsRemoved(_out, toRemove);
|
||||
}
|
||||
|
||||
final ValueContainer<Value> 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<Key, Value> implements IndexStorage<Key, Valu
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ValueContainerExternalizer<T> implements DataExternalizer<ValueContainer<T>> {
|
||||
private final DataExternalizer<T> myExternalizer;
|
||||
|
||||
private ValueContainerExternalizer(DataExternalizer<T> externalizer) {
|
||||
myExternalizer = externalizer;
|
||||
}
|
||||
|
||||
public void save(final DataOutput out, final ValueContainer<T> container) throws IOException {
|
||||
saveImpl(out, container, false);
|
||||
}
|
||||
|
||||
public void saveAsRemoved(final DataOutput out, final ValueContainer<T> 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<T> container, final boolean asRemovedData) throws IOException {
|
||||
DataInputOutputUtil.writeSINT(out, container.size());
|
||||
for (final Iterator<T> 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<T> read(final DataInput in) throws IOException {
|
||||
DataInputStream stream = (DataInputStream)in;
|
||||
final ValueContainerImpl<T> valueContainer = new ValueContainerImpl<T>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Key, Value> extends PersistentHashMap<Key, ValueContainer<Value>> {
|
||||
|
||||
private final ValueContainerExternalizer<Value> myValueContainerExternalizer;
|
||||
|
||||
public ValueContainerMap(final File file,
|
||||
KeyDescriptor<Key> keyKeyDescriptor,
|
||||
DataExternalizer<Value> valueExternalizer) throws IOException {
|
||||
|
||||
super(file, keyKeyDescriptor, new ValueContainerExternalizer<Value>(valueExternalizer));
|
||||
myValueContainerExternalizer = (ValueContainerExternalizer<Value>)myValueExternalizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void put(Key key, ValueContainer<Value> container) throws IOException {
|
||||
ChangeTrackingValueContainer<Value> valueContainer = (ChangeTrackingValueContainer<Value>)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<Value> toRemove = valueContainer.getRemovedDelta();
|
||||
if (toRemove.size() > 0) {
|
||||
myValueContainerExternalizer.saveAsRemoved(_out, toRemove);
|
||||
}
|
||||
|
||||
final ValueContainer<Value> 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<T> implements DataExternalizer<ValueContainer<T>> {
|
||||
private final DataExternalizer<T> myExternalizer;
|
||||
|
||||
private ValueContainerExternalizer(DataExternalizer<T> externalizer) {
|
||||
myExternalizer = externalizer;
|
||||
}
|
||||
|
||||
public void save(final DataOutput out, final ValueContainer<T> container) throws IOException {
|
||||
saveImpl(out, container, false);
|
||||
}
|
||||
|
||||
public void saveAsRemoved(final DataOutput out, final ValueContainer<T> 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<T> container, final boolean asRemovedData) throws IOException {
|
||||
DataInputOutputUtil.writeSINT(out, container.size());
|
||||
for (final Iterator<T> 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<T> read(final DataInput in) throws IOException {
|
||||
DataInputStream stream = (DataInputStream)in;
|
||||
final ValueContainerImpl<T> valueContainer = new ValueContainerImpl<T>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<AnActionButton> myExtraActions = new ArrayList<AnActionButton>();
|
||||
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<AnAction> ACTION_BUTTONS_SORTER = new Comparator<AnAction>() {
|
||||
@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 <T> ToolbarDecorator(TableView<T> table, ElementProducer<T> 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 <T> ToolbarDecorator createDecorator(@NotNull TableView<T> table, ElementProducer<T> 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)) {
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -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
|
||||
|
||||
@@ -29,6 +29,7 @@ public class FileInfo {
|
||||
public String name;
|
||||
public int attributes;
|
||||
public long timestamp;
|
||||
public long length;
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+14
-1
@@ -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();
|
||||
}
|
||||
|
||||
+15
-9
@@ -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) {
|
||||
|
||||
+24
-8
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-11
@@ -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();
|
||||
|
||||
@@ -38,11 +38,11 @@ import java.util.List;
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 18, 2007
|
||||
*/
|
||||
public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<Key>{
|
||||
public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<Key> implements PersistentMap<Key, Value> {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.PersistentHashMap");
|
||||
|
||||
private PersistentHashMapValueStorage myValueStorage;
|
||||
private final DataExternalizer<Value> myValueExternalizer;
|
||||
protected final DataExternalizer<Value> myValueExternalizer;
|
||||
private static final long NULL_ADDR = 0;
|
||||
private static final int INITIAL_INDEX_SIZE;
|
||||
static {
|
||||
|
||||
@@ -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<K, V> {
|
||||
|
||||
V get(K key) throws IOException;
|
||||
|
||||
void put(K key, V value) throws IOException;
|
||||
|
||||
boolean processKeys(Processor<K> processor) throws IOException;
|
||||
|
||||
|
||||
boolean isClosed();
|
||||
|
||||
boolean isDirty();
|
||||
|
||||
void force();
|
||||
|
||||
void close() throws IOException;
|
||||
|
||||
void markDirty() throws IOException;
|
||||
}
|
||||
Reference in New Issue
Block a user