mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -23,6 +23,8 @@ import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.projectRoots.*;
|
||||
import com.intellij.openapi.roots.AnnotationOrderRootType;
|
||||
@@ -62,8 +64,40 @@ public class JavaSdkImpl extends JavaSdk {
|
||||
private static final String JAVA_VERSION_PREFIX = "java version ";
|
||||
private static final String OPENJDK_VERSION_PREFIX = "openjdk version ";
|
||||
|
||||
public JavaSdkImpl() {
|
||||
public JavaSdkImpl(final VirtualFileManager fileManager, final FileTypeManager fileTypeManager) {
|
||||
super("JavaSDK");
|
||||
|
||||
fileManager.addVirtualFileListener(new VirtualFileAdapter() {
|
||||
|
||||
public void fileDeleted(@NotNull VirtualFileEvent event) {
|
||||
updateCache(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contentsChanged(@NotNull VirtualFileEvent event) {
|
||||
updateCache(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
updateCache(event);
|
||||
}
|
||||
|
||||
private void updateCache(VirtualFileEvent event) {
|
||||
final VirtualFile file = event.getFile();
|
||||
if (FileTypes.ARCHIVE.equals(fileTypeManager.getFileTypeByFileName(event.getFileName()))) {
|
||||
final String filePath = file.getPath();
|
||||
synchronized (myCachedVersionStrings) {
|
||||
for (String sdkHome : myCachedVersionStrings.keySet()) {
|
||||
if (FileUtil.isAncestor(sdkHome, filePath, false)) {
|
||||
myCachedVersionStrings.remove(sdkHome);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -428,7 +462,7 @@ public class JavaSdkImpl extends JavaSdk {
|
||||
modificator.addRoot(root, annoType);
|
||||
}
|
||||
|
||||
private final Map<String, String> myCachedVersionStrings = new HashMap<String, String>();
|
||||
private final Map<String, String> myCachedVersionStrings = Collections.synchronizedMap(new HashMap<String, String>());
|
||||
|
||||
@Override
|
||||
public final String getVersionString(String sdkHome) {
|
||||
|
||||
@@ -30,13 +30,24 @@ import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/*
|
||||
* Executor to perform <possibly> long operations on pooled thread
|
||||
* Is is used to reduce blinking, in case of fast end of background task.
|
||||
*/
|
||||
public class BackgroundTaskUtil {
|
||||
private static final Runnable TOO_SLOW_OPERATION = new EmptyRunnable();
|
||||
|
||||
/*
|
||||
* Executor to perform <possibly> long operations on pooled thread
|
||||
* It can be used to reduce blinking if background task completed fast. In this case callback will be called without invokeLater().
|
||||
*
|
||||
* Simple approach:
|
||||
*
|
||||
* onSlowAction.run() // show "Loading..."
|
||||
* executeOnPooledThread({
|
||||
* Runnable callback = backgroundTask(); // some background computations
|
||||
* invokeLater(callback); // apply changes
|
||||
* });
|
||||
*
|
||||
* will lead to "Loading..." visible between current moment and execution of invokeLater() event.
|
||||
* This period can be very short and looks like 'jumping' if background operation is fast.
|
||||
*/
|
||||
@CalledInAwt
|
||||
@NotNull
|
||||
public static ProgressIndicator executeAndTryWait(@NotNull final Function<ProgressIndicator, Runnable> backgroundTask,
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
@@ -143,9 +142,6 @@ public class TypedHandler extends TypedActionHandlerBase {
|
||||
}
|
||||
|
||||
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor)) return;
|
||||
if (!FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
|
||||
final Document originalDocument = originalEditor.getDocument();
|
||||
|
||||
@@ -40,7 +40,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorModificationUtil;
|
||||
import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -68,7 +67,7 @@ public class LookupTypedHandler extends TypedActionHandlerBase {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor) || !FileDocumentManager.getInstance().requestWriting(originalEditor.getDocument(), project)) {
|
||||
if (!CodeInsightUtilBase.prepareEditorForWrite(originalEditor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class IncrementalSearchHandler {
|
||||
EditorActionManager actionManager = EditorActionManager.getInstance();
|
||||
|
||||
TypedAction typedAction = actionManager.getTypedAction();
|
||||
typedAction.setupHandler(new MyTypedHandler(typedAction.getHandler()));
|
||||
typedAction.setupRawHandler(new MyTypedHandler(typedAction.getRawHandler()));
|
||||
|
||||
actionManager.setActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE, new BackSpaceHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE)));
|
||||
actionManager.setActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP, new UpHandler(actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP)));
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.intellij.ui.tabs.TabInfo;
|
||||
import com.intellij.ui.tabs.TabsListener;
|
||||
import com.intellij.ui.tabs.UiDecorator;
|
||||
import com.intellij.ui.tabs.impl.JBEditorTabs;
|
||||
import com.intellij.ui.tabs.impl.TabLabel;
|
||||
import com.intellij.ui.tabs.impl.singleRow.ScrollableSingleRowLayout;
|
||||
import com.intellij.ui.tabs.impl.singleRow.SingleRowLayout;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
@@ -114,6 +115,16 @@ public class GridCellImpl implements GridCell {
|
||||
public void resetDropOver(TabInfo tabInfo) {
|
||||
((RunnerContentUi)myContext).myTabs.resetDropOver(tabInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TabLabel createTabLabel(TabInfo info) {
|
||||
return new TabLabel(this, info) {
|
||||
@Override
|
||||
public void setAlignmentToCenter(boolean toCenter) {
|
||||
super.setAlignmentToCenter(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
}.setDataProvider(new DataProvider() {
|
||||
@Override
|
||||
@Nullable
|
||||
|
||||
+56
-28
@@ -26,8 +26,16 @@ import com.intellij.openapi.projectRoots.*;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.messages.impl.MessageListenerList;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -35,10 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@State(
|
||||
name = "ProjectJdkTable",
|
||||
@@ -60,37 +65,60 @@ public class ProjectJdkTableImpl extends ProjectJdkTable implements ExportableCo
|
||||
myMessageBus = ApplicationManager.getApplication().getMessageBus();
|
||||
myListenerList = new MessageListenerList<Listener>(myMessageBus, JDK_TABLE_TOPIC);
|
||||
// support external changes to jdk libraries (Endorsed Standards Override)
|
||||
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
|
||||
final MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect();
|
||||
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
|
||||
private FileTypeManager myFileTypeManager = FileTypeManager.getInstance();
|
||||
|
||||
@Override
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
updateJdks(event.getFile());
|
||||
public void before(@NotNull List<? extends VFileEvent> events) {
|
||||
}
|
||||
|
||||
private void updateJdks(VirtualFile file) {
|
||||
if (file.isDirectory() ||
|
||||
// avoid calling getFileType() because it will try to detect file type from content for unknown/text file types
|
||||
!FileTypes.ARCHIVE.equals(myFileTypeManager.getFileTypeByFileName(file.getName()))) {
|
||||
// consider only archive files that may contain libraries
|
||||
return;
|
||||
}
|
||||
for (Sdk sdk : mySdks) {
|
||||
final SdkType sdkType = (SdkType)sdk.getSdkType();
|
||||
if (!(sdkType instanceof JavaSdkType)) {
|
||||
continue;
|
||||
public void after(@NotNull List<? extends VFileEvent> events) {
|
||||
if (!events.isEmpty()) {
|
||||
final Set<Sdk> affected = new SmartHashSet<Sdk>();
|
||||
for (VFileEvent event : events) {
|
||||
addAffectedJavaSdk(event, affected);
|
||||
}
|
||||
final VirtualFile home = sdk.getHomeDirectory();
|
||||
if (home == null) {
|
||||
continue;
|
||||
}
|
||||
if (VfsUtilCore.isAncestor(home, file, true)) {
|
||||
sdkType.setupSdkPaths(sdk);
|
||||
// no need to iterate further assuming the file cannot be under the home of several SDKs
|
||||
break;
|
||||
if (!affected.isEmpty()) {
|
||||
for (Sdk sdk : affected) {
|
||||
((SdkType)sdk.getSdkType()).setupSdkPaths(sdk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addAffectedJavaSdk(VFileEvent event, Set<Sdk> affected) {
|
||||
final VirtualFile file = event.getFile();
|
||||
String fileName = null;
|
||||
if (file != null && file.isValid()) {
|
||||
if (file.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
fileName = file.getName();
|
||||
}
|
||||
final String eventPath = event.getPath();
|
||||
if (fileName == null) {
|
||||
fileName = VfsUtil.extractFileName(eventPath);
|
||||
}
|
||||
if (fileName != null) {
|
||||
// avoid calling getFileType() because it will try to detect file type from content for unknown/text file types
|
||||
// consider only archive files that may contain libraries
|
||||
if (!FileTypes.ARCHIVE.equals(myFileTypeManager.getFileTypeByFileName(fileName))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (Sdk sdk : mySdks) {
|
||||
if (sdk.getSdkType() instanceof JavaSdkType && !affected.contains(sdk)) {
|
||||
final String homePath = sdk.getHomePath();
|
||||
if (!StringUtil.isEmpty(homePath) && FileUtil.isAncestor(homePath, eventPath, true)) {
|
||||
affected.add(sdk);
|
||||
// no need to iterate further assuming the file cannot be under the home of several SDKs
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+65
-38
@@ -23,7 +23,6 @@ import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -33,11 +32,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @see EditorActionManager#getTypedAction()
|
||||
*/
|
||||
public class TypedAction {
|
||||
@NotNull
|
||||
private TypedActionHandler myRawHandler;
|
||||
private TypedActionHandler myHandler;
|
||||
private boolean myHandlersLoaded;
|
||||
|
||||
public TypedAction() {
|
||||
myHandler = new Handler();
|
||||
myRawHandler = new DefaultRawHandler();
|
||||
}
|
||||
|
||||
private void ensureHandlersLoaded() {
|
||||
@@ -55,11 +57,6 @@ public class TypedAction {
|
||||
if (editor.isViewer()) return;
|
||||
|
||||
Document doc = editor.getDocument();
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (!FileDocumentManager.getInstance().requestWriting(doc, project)) {
|
||||
return;
|
||||
}
|
||||
|
||||
doc.startGuardedBlockChecking();
|
||||
try {
|
||||
final String str = String.valueOf(charTyped);
|
||||
@@ -99,43 +96,73 @@ public class TypedAction {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
|
||||
if (editor == null) return;
|
||||
|
||||
Runnable command = new TypingCommand(editor, charTyped, dataContext);
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(CommonDataKeys.PROJECT.getData(dataContext), command, "", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
|
||||
/**
|
||||
* Gets the current 'raw' typing handler.
|
||||
*
|
||||
* @see #setupRawHandler(TypedActionHandler)
|
||||
*/
|
||||
@NotNull
|
||||
public TypedActionHandler getRawHandler() {
|
||||
return myRawHandler;
|
||||
}
|
||||
|
||||
private class TypingCommand implements Runnable {
|
||||
private final Editor myEditor;
|
||||
private final char myCharTyped;
|
||||
private final DataContext myDataContext;
|
||||
|
||||
public TypingCommand(Editor editor, char charTyped, DataContext dataContext) {
|
||||
myEditor = editor;
|
||||
myCharTyped = charTyped;
|
||||
myDataContext = dataContext;
|
||||
}
|
||||
/**
|
||||
* Replaces current 'raw' typing handler with the specified handler. The handler should pass unprocessed typing to the
|
||||
* previously registered 'raw' handler.
|
||||
* <p>
|
||||
* 'Raw' handler is a handler directly invoked by the code which handles typing in editor. Default 'raw' handler
|
||||
* performs some generic logic that has to be done on typing (like checking whether file has write access, creating a command
|
||||
* instance for undo subsystem, initiating write action, etc), but delegates to 'normal' handler for actual typing logic.
|
||||
*
|
||||
* @param handler the handler to set.
|
||||
* @return the previously registered handler.
|
||||
*
|
||||
* @see #getRawHandler()
|
||||
* @see #getHandler()
|
||||
* @see #setupHandler(TypedActionHandler)
|
||||
*/
|
||||
@NotNull
|
||||
public TypedActionHandler setupRawHandler(@NotNull TypedActionHandler handler) {
|
||||
TypedActionHandler tmp = myRawHandler;
|
||||
myRawHandler = handler;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
|
||||
if (editor == null) return;
|
||||
myRawHandler.execute(editor, charTyped, dataContext);
|
||||
}
|
||||
|
||||
private class DefaultRawHandler implements TypedActionHandler {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(myEditor.getDocument(), myEditor.getProject()) {
|
||||
@Override
|
||||
public void run() {
|
||||
Document doc = myEditor.getDocument();
|
||||
doc.startGuardedBlockChecking();
|
||||
try {
|
||||
getHandler().execute(myEditor, myCharTyped, myDataContext);
|
||||
public void execute(@NotNull final Editor editor, final char charTyped, @NotNull final DataContext dataContext) {
|
||||
CommandProcessor.getInstance().executeCommand(
|
||||
CommonDataKeys.PROJECT.getData(dataContext),
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), editor.getProject())) {
|
||||
return;
|
||||
}
|
||||
ApplicationManager.getApplication().runWriteAction(new DocumentRunnable(editor.getDocument(), editor.getProject()) {
|
||||
@Override
|
||||
public void run() {
|
||||
Document doc = editor.getDocument();
|
||||
doc.startGuardedBlockChecking();
|
||||
try {
|
||||
getHandler().execute(editor, charTyped, dataContext);
|
||||
}
|
||||
catch (ReadOnlyFragmentModificationException e) {
|
||||
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
|
||||
}
|
||||
finally {
|
||||
doc.stopGuardedBlockChecking();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (ReadOnlyFragmentModificationException e) {
|
||||
EditorActionManager.getInstance().getReadonlyFragmentModificationHandler(doc).handle(e);
|
||||
}
|
||||
finally {
|
||||
doc.stopGuardedBlockChecking();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
"", editor.getDocument(), UndoConfirmationPolicy.DEFAULT, editor.getDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.intellij.ui;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import java.awt.*;
|
||||
@@ -25,7 +27,7 @@ import java.awt.*;
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public abstract class ColoredTableCellRenderer extends SimpleColoredRenderer implements TableCellRenderer {
|
||||
public final Component getTableCellRendererComponent(JTable table, Object value,
|
||||
public final Component getTableCellRendererComponent(JTable table, @Nullable Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int col) {
|
||||
clear();
|
||||
setPaintFocusBorder(hasFocus && table.getCellSelectionEnabled());
|
||||
@@ -35,5 +37,5 @@ public abstract class ColoredTableCellRenderer extends SimpleColoredRenderer imp
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column);
|
||||
protected abstract void customizeCellRenderer(JTable table, @Nullable Object value, boolean selected, boolean hasFocus, int row, int column);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.impl.ToolWindowImpl;
|
||||
import com.intellij.openapi.wm.impl.ToolWindowManagerImpl;
|
||||
import com.intellij.ui.*;
|
||||
@@ -584,7 +585,10 @@ public class Switcher extends AnAction implements DumbAware {
|
||||
}
|
||||
}.registerCustomShortcutSet(TW_SHORTCUT, this, myPopup);
|
||||
|
||||
final Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
|
||||
Window window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
|
||||
if (window == null) {
|
||||
window = WindowManager.getInstance().getFrame(project);
|
||||
}
|
||||
myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, myPopup);
|
||||
myPopup.showInCenterOf(window);
|
||||
}
|
||||
|
||||
+1
@@ -180,6 +180,7 @@ class EditorCoordinateMapper {
|
||||
|
||||
FoldRegion outermostCollapsed = myFoldingModel.getCollapsedRegionAtOffset(offset);
|
||||
if (outermostCollapsed != null && offset > outermostCollapsed.getStartOffset()) {
|
||||
assert outermostCollapsed.isValid();
|
||||
offset = outermostCollapsed.getStartOffset();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TFloatArrayList;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -259,8 +260,10 @@ class EditorPainter {
|
||||
@Override
|
||||
public void paint(Graphics2D g, VisualLineFragmentsIterator.Fragment fragment, int start, int end,
|
||||
TextAttributes attributes, float xStart, float xEnd, int y) {
|
||||
g.setColor(attributes.getForegroundColor());
|
||||
fragment.draw(g, xStart, y, start, end);
|
||||
if (attributes != null && attributes.getForegroundColor() != null) {
|
||||
g.setColor(attributes.getForegroundColor());
|
||||
fragment.draw(g, xStart, y, start, end);
|
||||
}
|
||||
if (fragment.getCurrentFoldRegion() == null) {
|
||||
int logicalLine = fragment.getStartLogicalLine();
|
||||
if (logicalLine != currentLogicalLine[0]) {
|
||||
@@ -269,7 +272,7 @@ class EditorPainter {
|
||||
}
|
||||
paintWhitespace(g, text, xStart, y, start, end, whitespacePaintingStrategy, fragment);
|
||||
}
|
||||
if (hasTextEffect(attributes.getEffectColor(), attributes.getEffectType())) {
|
||||
if (attributes != null && hasTextEffect(attributes.getEffectColor(), attributes.getEffectType())) {
|
||||
paintTextEffect(g, xStart, xEnd, y, attributes.getEffectColor(), attributes.getEffectType());
|
||||
}
|
||||
}
|
||||
@@ -283,7 +286,8 @@ class EditorPainter {
|
||||
}
|
||||
}
|
||||
|
||||
float paintLineLayoutWithEffect(Graphics2D g, LineLayout layout, float x, float y, Color effectColor, EffectType effectType) {
|
||||
float paintLineLayoutWithEffect(Graphics2D g, LineLayout layout, float x, float y,
|
||||
@Nullable Color effectColor, @Nullable EffectType effectType) {
|
||||
float initialX = x;
|
||||
for (LineLayout.VisualFragment fragment : layout.getFragmentsInVisualOrder(x)) {
|
||||
fragment.draw(g, x, y);
|
||||
@@ -296,7 +300,7 @@ class EditorPainter {
|
||||
return x;
|
||||
}
|
||||
|
||||
private static boolean hasTextEffect(Color effectColor, EffectType effectType) {
|
||||
private static boolean hasTextEffect(@Nullable Color effectColor, @Nullable EffectType effectType) {
|
||||
return effectColor != null && (effectType == EffectType.LINE_UNDERSCORE ||
|
||||
effectType == EffectType.BOLD_LINE_UNDERSCORE ||
|
||||
effectType == EffectType.BOLD_DOTTED_LINE ||
|
||||
|
||||
@@ -299,7 +299,9 @@ public class EditorView implements Disposable {
|
||||
LineLayout getFoldRegionLayout(FoldRegion foldRegion) {
|
||||
LineLayout layout = foldRegion.getUserData(FOLD_REGION_TEXT_LAYOUT);
|
||||
if (layout == null) {
|
||||
layout = new LineLayout(this, foldRegion.getPlaceholderText(), myEditor.getFoldingModel().getPlaceholderAttributes().getFontType(),
|
||||
TextAttributes placeholderAttributes = myEditor.getFoldingModel().getPlaceholderAttributes();
|
||||
layout = new LineLayout(this, foldRegion.getPlaceholderText(),
|
||||
placeholderAttributes == null ? Font.PLAIN : placeholderAttributes.getFontType(),
|
||||
myFontRenderContext);
|
||||
foldRegion.putUserData(FOLD_REGION_TEXT_LAYOUT, layout);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.editor.impl.view;
|
||||
import com.intellij.openapi.editor.colors.FontPreferences;
|
||||
import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.intellij.lang.annotations.JdkConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -109,6 +110,7 @@ class LineLayout {
|
||||
}
|
||||
|
||||
private static List<BidiRun> createRuns(char[] text) {
|
||||
if (Registry.is("editor.disable.rtl")) return Collections.singletonList(new BidiRun((byte)0, 0, text.length));
|
||||
Bidi bidi = new Bidi(text, 0, null, 0, text.length, Bidi.DIRECTION_LEFT_TO_RIGHT);
|
||||
int runCount = bidi.getRunCount();
|
||||
List<BidiRun> runs = new ArrayList<BidiRun>(runCount);
|
||||
|
||||
+35
-194
@@ -19,17 +19,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphJustificationInfo;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Fragment of text using a common font
|
||||
*/
|
||||
class TextFragment implements LineFragment {
|
||||
// glyph location that should definitely be outside of painted region
|
||||
private static final Point NOWHERE = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
|
||||
@NotNull
|
||||
private final GlyphVector myGlyphVector;
|
||||
@NotNull
|
||||
@@ -78,18 +77,42 @@ class TextFragment implements LineFragment {
|
||||
assert startOffset >= 0;
|
||||
assert endOffset <= myCharPositions.length;
|
||||
assert startOffset < endOffset;
|
||||
GlyphVector vector;
|
||||
if (startOffset == 0 && endOffset == myCharPositions.length) {
|
||||
vector = myGlyphVector;
|
||||
g.drawGlyphVector(myGlyphVector, x, y);
|
||||
}
|
||||
else {
|
||||
boolean isRtl = isRtl();
|
||||
vector = new GlyphVectorWindow(myGlyphVector,
|
||||
isRtl ? myCharPositions.length - endOffset : startOffset,
|
||||
isRtl ? myCharPositions.length - startOffset : endOffset,
|
||||
getX(startOffset));
|
||||
// We cannot use our own GlyphVector implementation, as it wouldn't support
|
||||
// Mac-specific automatic font fallback (negative glyph indices will be rejected,
|
||||
// even though they are used inside StandardGlyphVector in that case).
|
||||
// We also cannot clone myGlyphVector without casting to sun.font.StandardGlyphVector,
|
||||
// as clone() method is not public in GlyphVector (even though it's Cloneable).
|
||||
// So we are modifying glyph positions in-place, and restore them after painting.
|
||||
int logicalStartOffset = isRtl() ? myCharPositions.length - endOffset : startOffset;
|
||||
int logicalEndOffset = isRtl() ? myCharPositions.length - startOffset : endOffset;
|
||||
int glyphCount = myGlyphVector.getNumGlyphs();
|
||||
Point2D[] savedPositions = new Point2D[glyphCount + 1];
|
||||
int lastPaintedGlyph = -1;
|
||||
for (int i = 0; i < glyphCount; i++) {
|
||||
savedPositions[i] = myGlyphVector.getGlyphPosition(i);
|
||||
int c = myGlyphVector.getGlyphCharIndex(i);
|
||||
if (c >= logicalStartOffset && c < logicalEndOffset) {
|
||||
lastPaintedGlyph = i;
|
||||
}
|
||||
else {
|
||||
myGlyphVector.setGlyphPosition(i, NOWHERE);
|
||||
}
|
||||
}
|
||||
savedPositions[glyphCount] = myGlyphVector.getGlyphPosition(glyphCount);
|
||||
myGlyphVector.setGlyphPosition(glyphCount, savedPositions[lastPaintedGlyph + 1]);
|
||||
try {
|
||||
g.drawGlyphVector(myGlyphVector, x - getX(startOffset), y);
|
||||
}
|
||||
finally {
|
||||
for (int i = 0; i <= glyphCount; i++) {
|
||||
myGlyphVector.setGlyphPosition(i, savedPositions[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
g.drawGlyphVector(vector, x, y);
|
||||
}
|
||||
|
||||
private boolean isRtl() {
|
||||
@@ -144,188 +167,6 @@ class TextFragment implements LineFragment {
|
||||
return startX + getX(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* GlyphVector that represents a portion of another (previously laid out) GlyphVector
|
||||
*/
|
||||
private static class GlyphVectorWindow extends GlyphVector {
|
||||
private final GlyphVector myDelegate;
|
||||
private final int[] myGlyphMap;
|
||||
private final int myStartChar;
|
||||
private final float myStartX;
|
||||
|
||||
GlyphVectorWindow(@NotNull GlyphVector delegate, int startOffset, int endOffset, float startX) {
|
||||
myDelegate = delegate;
|
||||
myStartChar = startOffset;
|
||||
myStartX = startX;
|
||||
|
||||
int glyphCount = 0;
|
||||
for (int i = 0; i < delegate.getNumGlyphs(); i++) {
|
||||
int c = delegate.getGlyphCharIndex(i);
|
||||
if (c >= startOffset && c < endOffset) {
|
||||
glyphCount++;
|
||||
}
|
||||
}
|
||||
|
||||
assert glyphCount > 0;
|
||||
|
||||
myGlyphMap = new int[glyphCount];
|
||||
int p = 0;
|
||||
for (int i = 0; i < delegate.getNumGlyphs(); i++) {
|
||||
int c = delegate.getGlyphCharIndex(i);
|
||||
if (c >= startOffset && c < endOffset) {
|
||||
myGlyphMap[p++] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Font getFont() {
|
||||
return myDelegate.getFont();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FontRenderContext getFontRenderContext() {
|
||||
return myDelegate.getFontRenderContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumGlyphs() {
|
||||
return myGlyphMap.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphCode(int glyphIndex) {
|
||||
return myDelegate.getGlyphCode(myGlyphMap[glyphIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getGlyphCodes(int beginGlyphIndex, int numEntries, int[] codeReturn) {
|
||||
if (codeReturn == null) {
|
||||
codeReturn = new int[numEntries];
|
||||
}
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
codeReturn[i] = myDelegate.getGlyphCode(myGlyphMap[beginGlyphIndex + i]);
|
||||
}
|
||||
return codeReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutFlags() {
|
||||
return myDelegate.getLayoutFlags() | FLAG_HAS_POSITION_ADJUSTMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlyphCharIndex(int glyphIndex) {
|
||||
return myDelegate.getGlyphCharIndex(myGlyphMap[glyphIndex]) - myStartChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getGlyphCharIndices(int beginGlyphIndex, int numEntries, int[] codeReturn) {
|
||||
if (codeReturn == null) {
|
||||
codeReturn = new int[numEntries];
|
||||
}
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
codeReturn[i] = myDelegate.getGlyphCharIndex(myGlyphMap[beginGlyphIndex + i]) - myStartChar;
|
||||
}
|
||||
return codeReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point2D getGlyphPosition(int glyphIndex) {
|
||||
Point2D.Float pos = (Point2D.Float) myDelegate.getGlyphPosition(glyphIndex < myGlyphMap.length ?
|
||||
myGlyphMap[glyphIndex] :
|
||||
myGlyphMap[glyphIndex - 1] + 1);
|
||||
pos.x -= myStartX;
|
||||
return pos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, float[] positionReturn) {
|
||||
if (positionReturn == null) {
|
||||
positionReturn = new float[numEntries * 2];
|
||||
}
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
int index = beginGlyphIndex + i;
|
||||
int delegateIndex = index < myGlyphMap.length ? myGlyphMap[index] : myGlyphMap[index - 1] + 1;
|
||||
Point2D.Float pos = (Point2D.Float) myDelegate.getGlyphPosition(delegateIndex);
|
||||
positionReturn[i * 2] = pos.x - myStartX;
|
||||
positionReturn[i * 2 + 1] = pos.y;
|
||||
}
|
||||
return positionReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffineTransform getGlyphTransform(int glyphIndex) {
|
||||
return myDelegate.getGlyphTransform(myGlyphMap[glyphIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performDefaultLayout() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getLogicalBounds() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle2D getVisualBounds() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getOutline(float x, float y) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getGlyphOutline(int glyphIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlyphPosition(int glyphIndex, Point2D newPos) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGlyphTransform(int glyphIndex, AffineTransform newTX) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getGlyphLogicalBounds(int glyphIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getGlyphVisualBounds(int glyphIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlyphMetrics getGlyphMetrics(int glyphIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("CovariantEquals")
|
||||
@Override
|
||||
public boolean equals(GlyphVector set) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private class TextFragmentWindow implements LineFragment {
|
||||
private final int myStartOffset;
|
||||
private final int myEndOffset;
|
||||
|
||||
+3
-1
@@ -271,7 +271,9 @@ class VisualLineFragmentsIterator implements Iterator<VisualLineFragmentsIterato
|
||||
if (myDelegate == null) {
|
||||
LineLayout foldRegionLayout = myView.getFoldRegionLayout(myFoldRegion);
|
||||
TextAttributes attributes = myView.getEditor().getFoldingModel().getPlaceholderAttributes();
|
||||
myView.getPainter().paintLineLayoutWithEffect(g, foldRegionLayout, x, y, attributes.getEffectColor(), attributes.getEffectType());
|
||||
myView.getPainter().paintLineLayoutWithEffect(g, foldRegionLayout, x, y,
|
||||
attributes == null ? null : attributes.getEffectColor(),
|
||||
attributes == null ? null : attributes.getEffectType());
|
||||
}
|
||||
else {
|
||||
int lineStartOffset = myDocument.getLineStartOffset(myCurrentStartLogicalLine);
|
||||
|
||||
+6
-1
@@ -389,7 +389,12 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz
|
||||
}
|
||||
|
||||
public void update() {
|
||||
myRootContainer.update();
|
||||
try {
|
||||
myRootContainer.update();
|
||||
}
|
||||
finally {
|
||||
resetVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.vcs.log.ui.frame;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.CopyProvider;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -69,6 +70,7 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, CopyProvider {
|
||||
private static final Logger LOG = Logger.getInstance(VcsLogGraphTable.class);
|
||||
|
||||
public static final int ROOT_INDICATOR_COLORED_WIDTH = 8;
|
||||
public static final int ROOT_INDICATOR_WHITE_WIDTH = 5;
|
||||
@@ -336,9 +338,16 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
|
||||
}
|
||||
|
||||
private VcsLogHighlighter.VcsCommitStyle getStyle(int row, int column, String text, boolean hasFocus, final boolean selected) {
|
||||
final RowInfo<Integer> rowInfo = myDataPack.getVisibleGraph().getRowInfo(row);
|
||||
|
||||
Component dummyRendererComponent = myDummyRenderer.getTableCellRendererComponent(this, text, selected, hasFocus, row, column);
|
||||
|
||||
VisibleGraph<Integer> visibleGraph = myDataPack.getVisibleGraph();
|
||||
if (row < 0 || row >= visibleGraph.getVisibleCommitCount()) {
|
||||
LOG.error("Visible graph has " + visibleGraph.getVisibleCommitCount() + " commits, yet we want row " + row);
|
||||
return VcsCommitStyleFactory.createStyle(dummyRendererComponent.getForeground(), dummyRendererComponent.getBackground());
|
||||
}
|
||||
|
||||
final RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);
|
||||
|
||||
VcsLogHighlighter.VcsCommitStyle defaultStyle = VcsCommitStyleFactory
|
||||
.createStyle(rowInfo.getRowType() == RowType.UNMATCHED ? JBColor.GRAY : dummyRendererComponent.getForeground(),
|
||||
dummyRendererComponent.getBackground());
|
||||
|
||||
@@ -43,7 +43,7 @@ public class GitTaskHandler extends DvcsTaskHandler<GitRepository> {
|
||||
|
||||
@Override
|
||||
protected void checkout(@NotNull String taskName, @NotNull List<GitRepository> repos, @Nullable Runnable callInAwtLater) {
|
||||
myBrancher.checkout(taskName, repos, callInAwtLater);
|
||||
myBrancher.checkout(taskName, false, repos, callInAwtLater);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,7 @@ public class GitCheckoutRevisionAction extends GitLogSingleCommitAction {
|
||||
@Override
|
||||
protected void actionPerformed(@NotNull GitRepository repository, @NotNull VcsFullCommitDetails commit) {
|
||||
GitBrancher brancher = ServiceManager.getService(repository.getProject(), GitBrancher.class);
|
||||
brancher.checkout(commit.getId().asString(), Collections.singletonList(repository), null);
|
||||
brancher.checkout(commit.getId().asString(), false, Collections.singletonList(repository), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,12 +92,12 @@ public final class GitBranchWorker {
|
||||
public void checkoutNewBranchStartingFrom(@NotNull String newBranchName, @NotNull String startPoint,
|
||||
@NotNull List<GitRepository> repositories) {
|
||||
updateInfo(repositories);
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, startPoint, newBranchName).execute();
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, startPoint, false, newBranchName).execute();
|
||||
}
|
||||
|
||||
public void checkout(@NotNull final String reference, @NotNull List<GitRepository> repositories) {
|
||||
public void checkout(@NotNull final String reference, boolean detach, @NotNull List<GitRepository> repositories) {
|
||||
updateInfo(repositories);
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, reference, null).execute();
|
||||
new GitCheckoutOperation(myProject, myFacade, myGit, myUiHandler, repositories, reference, detach, null).execute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,18 +60,21 @@ public interface GitBrancher {
|
||||
* If local changes prevent the checkout, shows the list of them and proposes to make a "smart checkout":
|
||||
* stash-checkout-unstash.</p>
|
||||
* <p>Doesn't check the reference for validity.</p>
|
||||
*
|
||||
* @param reference reference to be checked out.
|
||||
* @param detach if true, checkout operation will put the repository into the detached HEAD state
|
||||
* (useful if one wants to checkout a remote branch position, but not create a new tracking local branch);
|
||||
* if false, it will behave the same as {@code git checkout} command does, i.e. switch to the local branch,
|
||||
* create a local branch tracking the given remote branch, checkout hash or tag into the detached HEAD.
|
||||
* @param repositories repositories to operate on.
|
||||
* @param callInAwtLater the Runnable that should be called after execution of the method (both successful and unsuccessful).
|
||||
* If given, it will be called in the EDT {@link javax.swing.SwingUtilities#invokeLater(Runnable) later}.
|
||||
* If given, it will be called in the EDT {@link javax.swing.SwingUtilities#invokeLater(Runnable) later}.
|
||||
*/
|
||||
void checkout(@NotNull String reference, @NotNull List<GitRepository> repositories, @Nullable Runnable callInAwtLater);
|
||||
void checkout(@NotNull String reference, boolean detach, @NotNull List<GitRepository> repositories, @Nullable Runnable callInAwtLater);
|
||||
|
||||
/**
|
||||
* Creates and checks out a new local branch starting from the given reference:
|
||||
* {@code git checkout -b <branchname> <start-point>}. <br/>
|
||||
* Provides the "smart checkout" procedure the same as in {@link #checkout(String, java.util.List, Runnable)}.
|
||||
* Provides the "smart checkout" procedure the same as in {@link #checkout(String, boolean, List, Runnable)}.
|
||||
*
|
||||
* @param newBranchName the name of the new local branch.
|
||||
* @param startPoint the reference to checkout.
|
||||
|
||||
@@ -69,11 +69,13 @@ class GitBrancherImpl implements GitBrancher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkout(@NotNull final String reference, @NotNull final List<GitRepository> repositories,
|
||||
public void checkout(@NotNull final String reference,
|
||||
final boolean detach,
|
||||
@NotNull final List<GitRepository> repositories,
|
||||
@Nullable Runnable callInAwtLater) {
|
||||
new CommonBackgroundTask(myProject, "Checking out " + reference, callInAwtLater) {
|
||||
@Override public void execute(@NotNull ProgressIndicator indicator) {
|
||||
newWorker(indicator).checkout(reference, repositories);
|
||||
newWorker(indicator).checkout(reference, detach, repositories);
|
||||
}
|
||||
}.runInBackground();
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class GitCheckoutNewBranchOperation extends GitBranchOperation {
|
||||
GitCompoundResult deleteResult = new GitCompoundResult(myProject);
|
||||
Collection<GitRepository> repositories = getSuccessfulRepositories();
|
||||
for (GitRepository repository : repositories) {
|
||||
GitCommandResult result = myGit.checkout(repository, myCurrentHeads.get(repository), null, true);
|
||||
GitCommandResult result = myGit.checkout(repository, myCurrentHeads.get(repository), null, true, false);
|
||||
checkoutResult.append(repository, result);
|
||||
if (result.success()) {
|
||||
deleteResult.append(repository, myGit.branchDelete(repository, myNewBranchName, false));
|
||||
|
||||
@@ -52,13 +52,20 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
public static final String ROLLBACK_PROPOSAL_FORMAT = "You may rollback (checkout back to previous branch) not to let branches diverge.";
|
||||
|
||||
@NotNull private final String myStartPointReference;
|
||||
private final boolean myDetach;
|
||||
@Nullable private final String myNewBranch;
|
||||
|
||||
GitCheckoutOperation(@NotNull Project project, GitPlatformFacade facade, @NotNull Git git, @NotNull GitBranchUiHandler uiHandler,
|
||||
GitCheckoutOperation(@NotNull Project project,
|
||||
GitPlatformFacade facade,
|
||||
@NotNull Git git,
|
||||
@NotNull GitBranchUiHandler uiHandler,
|
||||
@NotNull Collection<GitRepository> repositories,
|
||||
@NotNull String startPointReference, @Nullable String newBranch) {
|
||||
@NotNull String startPointReference,
|
||||
boolean detach,
|
||||
@Nullable String newBranch) {
|
||||
super(project, facade, git, uiHandler, repositories);
|
||||
myStartPointReference = startPointReference;
|
||||
myDetach = detach;
|
||||
myNewBranch = newBranch;
|
||||
}
|
||||
|
||||
@@ -78,8 +85,8 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
GitUntrackedFilesOverwrittenByOperationDetector untrackedOverwrittenByCheckout =
|
||||
new GitUntrackedFilesOverwrittenByOperationDetector(root);
|
||||
|
||||
GitCommandResult result = myGit.checkout(repository, myStartPointReference, myNewBranch, false,
|
||||
localChangesDetector, unmergedFiles, untrackedOverwrittenByCheckout);
|
||||
GitCommandResult result = myGit.checkout(repository, myStartPointReference, myNewBranch, false, myDetach,
|
||||
localChangesDetector, unmergedFiles, untrackedOverwrittenByCheckout);
|
||||
if (result.success()) {
|
||||
refresh(repository);
|
||||
markSuccessful(repository);
|
||||
@@ -171,7 +178,7 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
GitCompoundResult checkoutResult = new GitCompoundResult(myProject);
|
||||
GitCompoundResult deleteResult = new GitCompoundResult(myProject);
|
||||
for (GitRepository repository : getSuccessfulRepositories()) {
|
||||
GitCommandResult result = myGit.checkout(repository, myCurrentHeads.get(repository), null, true);
|
||||
GitCommandResult result = myGit.checkout(repository, myCurrentHeads.get(repository), null, true, false);
|
||||
checkoutResult.append(repository, result);
|
||||
if (result.success() && myNewBranch != null) {
|
||||
/*
|
||||
@@ -235,7 +242,7 @@ class GitCheckoutOperation extends GitBranchOperation {
|
||||
@NotNull String reference, @Nullable String newBranch, boolean force) {
|
||||
GitCompoundResult compoundResult = new GitCompoundResult(myProject);
|
||||
for (GitRepository repository : repositories) {
|
||||
compoundResult.append(repository, myGit.checkout(repository, reference, newBranch, force));
|
||||
compoundResult.append(repository, myGit.checkout(repository, reference, newBranch, force, myDetach));
|
||||
}
|
||||
if (compoundResult.totalSuccess()) {
|
||||
return true;
|
||||
|
||||
@@ -77,7 +77,11 @@ public interface Git {
|
||||
@NotNull GitLineHandlerListener... listeners);
|
||||
|
||||
@NotNull
|
||||
GitCommandResult checkout(@NotNull GitRepository repository, @NotNull String reference, @Nullable String newBranch, boolean force,
|
||||
GitCommandResult checkout(@NotNull GitRepository repository,
|
||||
@NotNull String reference,
|
||||
@Nullable String newBranch,
|
||||
boolean force,
|
||||
boolean detach,
|
||||
@NotNull GitLineHandlerListener... listeners);
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -236,10 +236,11 @@ public class GitImpl implements Git {
|
||||
@NotNull
|
||||
@Override
|
||||
public GitCommandResult checkout(@NotNull GitRepository repository,
|
||||
@NotNull String reference,
|
||||
@Nullable String newBranch,
|
||||
boolean force,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
@NotNull String reference,
|
||||
@Nullable String newBranch,
|
||||
boolean force,
|
||||
boolean detach,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.CHECKOUT);
|
||||
h.setSilent(false);
|
||||
h.setStdoutSuppressed(false);
|
||||
@@ -247,7 +248,7 @@ public class GitImpl implements Git {
|
||||
h.addParameters("--force");
|
||||
}
|
||||
if (newBranch == null) { // simply checkout
|
||||
h.addParameters(reference);
|
||||
h.addParameters(detach ? reference + "^0" : reference); // we could use `--detach` here, but it is supported only since 1.7.5.
|
||||
}
|
||||
else { // checkout reference as new branch
|
||||
h.addParameters("-b", newBranch, reference);
|
||||
|
||||
@@ -89,8 +89,10 @@ public class GitRebaseEditor extends DialogWrapper implements DataProvider {
|
||||
myCommitsTable.setDefaultRenderer(String.class, new ColoredTableCellRenderer() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) {
|
||||
append(value.toString());
|
||||
SpeedSearchUtil.applySpeedSearchHighlighting(myCommitsTable, this, true, selected);
|
||||
if (value != null) {
|
||||
append(value.toString());
|
||||
SpeedSearchUtil.applySpeedSearchHighlighting(myCommitsTable, this, true, selected);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ class GitBranchPopupActions {
|
||||
.showInputDialog(myProject, "Enter reference (branch, tag) name or commit hash", "Checkout", Messages.getQuestionIcon());
|
||||
if (reference != null) {
|
||||
GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class);
|
||||
brancher.checkout(reference, Collections.singletonList(myRepository), null);
|
||||
brancher.checkout(reference, true, Collections.singletonList(myRepository), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class GitBranchPopupActions {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class);
|
||||
brancher.checkout(myBranchName, myRepositories, null);
|
||||
brancher.checkout(myBranchName, false, myRepositories, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ class GitBranchWorkerTest extends GitPlatformTest {
|
||||
|
||||
def checkoutBranch(String name, def uiHandler) {
|
||||
GitBranchWorker brancher = new GitBranchWorker(myProject, myPlatformFacade, myGit, uiHandler as GitBranchUiHandler)
|
||||
brancher.checkout(name, myRepositories)
|
||||
brancher.checkout(name, false, myRepositories)
|
||||
}
|
||||
|
||||
def mergeBranch(String name, def uiHandler) {
|
||||
|
||||
+9
@@ -33,6 +33,7 @@ public class TrelloIntegrationTest extends LiveIntegrationTestCase<TrelloReposit
|
||||
|
||||
private static final String CARD_1_1_1_NAME = "Card 1-1-1";
|
||||
private static final String CARD_1_1_1_ID = "53c416d8b4bd36fb078446e5";
|
||||
private static final String CARD_1_1_1_NUMBER = "1";
|
||||
|
||||
// Labels and colors
|
||||
private static final String LABELS_AND_COLORS_BOARD_NAME = "Labels and Colors";
|
||||
@@ -217,6 +218,14 @@ public class TrelloIntegrationTest extends LiveIntegrationTestCase<TrelloReposit
|
||||
assertEquals(BACKLOG_LIST_ID, card.getIdList());
|
||||
}
|
||||
|
||||
// IDEA-139903
|
||||
public void testCardBoardLocalNumber() throws Exception {
|
||||
final TrelloCard card = myRepository.fetchCardById(CARD_1_1_1_ID);
|
||||
assertNotNull(card);
|
||||
assertEquals(CARD_1_1_1_ID, card.getId());
|
||||
assertEquals(CARD_1_1_1_NUMBER, new TrelloTask(card, myRepository).getNumber());
|
||||
}
|
||||
|
||||
static void assertObjectsNamed(@NotNull String message, @NotNull Collection<? extends TrelloModel> objects, @NotNull String... names) {
|
||||
assertEquals(message, ContainerUtil.newHashSet(names), ContainerUtil.map2Set(objects, new Function<TrelloModel, String>() {
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 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.
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.uiDesigner;
|
||||
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.uiDesigner.core.Spacer;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -32,7 +34,7 @@ abstract class DesignSpacer extends Spacer{
|
||||
|
||||
protected static final int SPRING_PRERIOD = 4;
|
||||
|
||||
protected static final Color ourColor1 = new Color(8,8,108);
|
||||
protected static final Color ourColor2 = new Color(3,26,142);
|
||||
protected static final Color ourColor3 = Color.BLACK;
|
||||
protected static final Color ourColor1 = new JBColor(new Color(8,8,108), Gray._168);
|
||||
protected static final Color ourColor2 = new JBColor(new Color(3, 26, 142), Gray._128);
|
||||
protected static final Color ourColor3 = new JBColor(Gray._0, Gray._128);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<fileEditorProvider implementation="org.jetbrains.plugins.ipnb.editor.IpnbEditorProvider"/>
|
||||
<fileTypeFactory implementation="org.jetbrains.plugins.ipnb.IpnbFileTypeFactory"/>
|
||||
|
||||
<projectConfigurable groupId="tools" instance="org.jetbrains.plugins.ipnb.configuration.IpnbConfigurable"
|
||||
<projectConfigurable groupId="language" instance="org.jetbrains.plugins.ipnb.configuration.IpnbConfigurable"
|
||||
id="org.jetbrains.plugins.ipnb.configuration.IpnbConfigurable" displayName="IPython Notebook"
|
||||
nonDefaultProject="true"/>
|
||||
<projectService serviceInterface="org.jetbrains.plugins.ipnb.configuration.IpnbSettings"
|
||||
|
||||
Reference in New Issue
Block a user