mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-127205 Specify Editor Tab Width
This commit is contained in:
@@ -72,6 +72,7 @@ public class UISettings implements PersistentStateComponent<UISettings>, Exporta
|
||||
public int RECENT_FILES_LIMIT = 50;
|
||||
public int CONSOLE_COMMAND_HISTORY_LIMIT = 300;
|
||||
public int EDITOR_TAB_LIMIT = 10;
|
||||
public int EDITOR_TAB_TITLE_LIMIT = 30;
|
||||
public boolean ANIMATE_WINDOWS = true;
|
||||
public int ANIMATION_SPEED = 2000; // Pixels per second
|
||||
public boolean SHOW_TOOL_WINDOW_NUMBERS = true;
|
||||
|
||||
+28
-7
@@ -3,7 +3,7 @@
|
||||
<grid id="27dc6" binding="myRootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="527"/>
|
||||
<xy x="20" y="20" width="500" height="585"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -108,7 +108,7 @@
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="eb8d0" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
|
||||
<grid id="eb8d0" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="10">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -119,7 +119,7 @@
|
||||
</clientProperties>
|
||||
<border type="none" title-resource-bundle="messages/ApplicationBundle" title-key="group.tab.closing.policy"/>
|
||||
<children>
|
||||
<grid id="5a5a7" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="5a5a7" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -129,7 +129,9 @@
|
||||
<children>
|
||||
<component id="527a6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="60" height="27"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="editbox.tab.limit"/>
|
||||
@@ -138,19 +140,38 @@
|
||||
<component id="16477" class="javax.swing.JTextField" binding="myEditorTabLimitField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="30" height="-1"/>
|
||||
<preferred-size width="30" height="27"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="15"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2479d" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="messages/ApplicationBundle" key="editbox.tab.title.limit"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3499c" class="javax.swing.JTextField" binding="myTabTitleLimitField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="30" height="27"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<columns value="2"/>
|
||||
<text value="30"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="9b723" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -184,7 +205,7 @@
|
||||
<grid id="611cc" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="2">
|
||||
<margin top="10" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
|
||||
+22
-4
@@ -45,6 +45,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
|
||||
private JCheckBox myShowCloseButtonOnCheckBox;
|
||||
private JCheckBox myShowDirectoryInTabCheckBox;
|
||||
private JRadioButton myActivateRightNeighbouringTabRadioButton;
|
||||
private JTextField myTabTitleLimitField;
|
||||
|
||||
public EditorTabsConfigurable() {
|
||||
myEditorTabPlacement.setModel(new DefaultComboBoxModel(new Object[]{
|
||||
@@ -119,6 +120,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
|
||||
myHideKnownExtensions.setSelected(uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS);
|
||||
myShowDirectoryInTabCheckBox.setSelected(uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES);
|
||||
myEditorTabLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_LIMIT));
|
||||
myTabTitleLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_TITLE_LIMIT));
|
||||
myShowCloseButtonOnCheckBox.setSelected(uiSettings.SHOW_CLOSE_BUTTON);
|
||||
|
||||
if (uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST) {
|
||||
@@ -171,14 +173,29 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
|
||||
uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE = myActivateRightNeighbouringTabRadioButton.isSelected();
|
||||
|
||||
String temp = myEditorTabLimitField.getText();
|
||||
if(temp.trim().length() > 0){
|
||||
if (temp.trim().length() > 0) {
|
||||
try {
|
||||
int newEditorTabLimit = Integer.parseInt(temp);
|
||||
if(newEditorTabLimit>0&&newEditorTabLimit!=uiSettings.EDITOR_TAB_LIMIT){
|
||||
uiSettings.EDITOR_TAB_LIMIT=newEditorTabLimit;
|
||||
if (newEditorTabLimit > 0 && newEditorTabLimit != uiSettings.EDITOR_TAB_LIMIT) {
|
||||
uiSettings.EDITOR_TAB_LIMIT = newEditorTabLimit;
|
||||
uiSettingsChanged = true;
|
||||
}
|
||||
}catch (NumberFormatException ignored){}
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
temp = myTabTitleLimitField.getText();
|
||||
if (temp.trim().length() > 0) {
|
||||
try {
|
||||
int newTabTitleLimit = Integer.parseInt(temp);
|
||||
newTabTitleLimit = Math.max(10, Math.min(100, newTabTitleLimit));
|
||||
if (newTabTitleLimit != uiSettings.EDITOR_TAB_TITLE_LIMIT){
|
||||
uiSettings.EDITOR_TAB_TITLE_LIMIT = newTabTitleLimit;
|
||||
uiSettingsChanged = true;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
if(uiSettingsChanged){
|
||||
uiSettings.fireUISettingsChanged();
|
||||
@@ -191,6 +208,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
|
||||
boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK);
|
||||
isModified |= isModified(myShowTabsTooltipsCheckBox, uiSettings.SHOW_TABS_TOOLTIPS);
|
||||
isModified |= isModified(myEditorTabLimitField, uiSettings.EDITOR_TAB_LIMIT);
|
||||
isModified |= isModified(myTabTitleLimitField, uiSettings.EDITOR_TAB_TITLE_LIMIT);
|
||||
int tabPlacement = ((Integer)myEditorTabPlacement.getSelectedItem()).intValue();
|
||||
isModified |= tabPlacement != uiSettings.EDITOR_TAB_PLACEMENT;
|
||||
isModified |= myHideKnownExtensions.isSelected() != uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS;
|
||||
|
||||
@@ -92,6 +92,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
|
||||
* out of its container. (IDEA-61536)
|
||||
*/
|
||||
private WeakReference<TabInfo> myPreviousSelection = new WeakReference<TabInfo>(null);
|
||||
private boolean myTitleShortened;
|
||||
|
||||
public TabInfo(final JComponent component) {
|
||||
myComponent = component;
|
||||
@@ -392,6 +393,14 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
|
||||
return myPreviousSelection.get();
|
||||
}
|
||||
|
||||
public boolean isTitleShortened() {
|
||||
return myTitleShortened;
|
||||
}
|
||||
|
||||
public void setTitleIsShortened(boolean titleIsShortened) {
|
||||
myTitleShortened = titleIsShortened;
|
||||
}
|
||||
|
||||
public interface DragOutDelegate {
|
||||
|
||||
void dragOutStarted(MouseEvent mouseEvent, TabInfo info);
|
||||
|
||||
@@ -44,6 +44,7 @@ import java.util.List;
|
||||
*/
|
||||
public class JBEditorTabs extends JBTabsImpl {
|
||||
public static final String TABS_ALPHABETICAL_KEY = "tabs.alphabetical";
|
||||
static final String TABS_CHORTEN_TITLE_IF_NEED = "tabs.shorten.title.if.need";
|
||||
private JBEditorTabsPainter myDarkPainter = new DarculaEditorTabsPainter();
|
||||
private JBEditorTabsPainter myDefaultPainter = new DefaultEditorTabsPainter();
|
||||
|
||||
@@ -60,6 +61,13 @@ public class JBEditorTabs extends JBTabsImpl {
|
||||
return super.createSingleRowLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TabLabel createTabLabel(TabInfo info) {
|
||||
TabLabel label = super.createTabLabel(info);
|
||||
label.putClientProperty(TABS_CHORTEN_TITLE_IF_NEED, Boolean.TRUE);
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditorTabs() {
|
||||
return true;
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.ui.tabs.JBTabsPosition;
|
||||
@@ -317,6 +318,16 @@ public class TabLabel extends JPanel {
|
||||
|
||||
|
||||
public void setText(final SimpleColoredText text) {
|
||||
myInfo.setTitleIsShortened(false);
|
||||
if (text != null && text.getTexts().size() == 1 && Boolean.TRUE == getClientProperty(JBEditorTabs.TABS_CHORTEN_TITLE_IF_NEED)) {
|
||||
String title = text.getTexts().get(0);
|
||||
if (title.length() > UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT) {
|
||||
SimpleTextAttributes attributes = text.getAttributes().get(0);
|
||||
text.clear();
|
||||
text.append(StringUtil.getShortened(title, UISettings.getInstance().EDITOR_TAB_TITLE_LIMIT), attributes);
|
||||
myInfo.setTitleIsShortened(true);
|
||||
}
|
||||
}
|
||||
myLabel.change(new Runnable() {
|
||||
public void run() {
|
||||
myLabel.clear();
|
||||
|
||||
+2
@@ -277,6 +277,8 @@ public final class EditorTabbedContainer implements Disposable, CloseAction.Clos
|
||||
myTabs.getTabAt(index).setTooltipText(text);
|
||||
}
|
||||
|
||||
public boolean isTitleShortened(int index) { return myTabs.getTabAt(index).isTitleShortened(); }
|
||||
|
||||
public void setBackgroundColorAt(final int index, final Color color) {
|
||||
myTabs.getTabAt(index).setTabColor(color);
|
||||
}
|
||||
|
||||
@@ -464,6 +464,10 @@ public class EditorWindow {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTitleShortenedAt(int index) {
|
||||
return myTabbedPane != null && myTabbedPane.isTitleShortened(index);
|
||||
}
|
||||
|
||||
private void setBackgroundColorAt(final int index, final Color color) {
|
||||
if (myTabbedPane != null) {
|
||||
myTabbedPane.setBackgroundColorAt(index, color);
|
||||
@@ -908,7 +912,9 @@ public class EditorWindow {
|
||||
final int index = findEditorIndex(findFileComposite(file));
|
||||
if (index != -1) {
|
||||
setTitleAt(index, EditorTabbedContainer.calcTabTitle(getManager().getProject(), file));
|
||||
setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS ? getManager().getFileTooltipText(file) : null);
|
||||
setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS || isTitleShortenedAt(index)
|
||||
? getManager().getFileTooltipText(file)
|
||||
: null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +360,7 @@ label.collapse.by.default=Collapse by default:
|
||||
checkbox.show.code.folding.outline=Show code folding outline
|
||||
group.tab.appearance=Tab Appearance
|
||||
editbox.tab.limit=Tab limit:
|
||||
editbox.tab.title.limit=Tab title limit:
|
||||
combobox.editor.tab.placement=Placement:
|
||||
checkbox.editor.tabs.in.single.row=Show tabs in single row
|
||||
checkbox.editor.tabs.show.close.button=Show "close" button on editor tabs
|
||||
|
||||
@@ -2658,6 +2658,56 @@ public class StringUtil extends StringUtilRt {
|
||||
return s.startsWith(smallPart.toLowerCase()) && bigPart.toLowerCase().startsWith(s);
|
||||
}
|
||||
|
||||
public static String getShortened(String s, int maxWidth) {
|
||||
int length = s.length();
|
||||
if (isEmpty(s) || length <= maxWidth) return s;
|
||||
ArrayList<String> words = new ArrayList<String>();
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char ch = s.charAt(i);
|
||||
|
||||
if (i == length - 1) {
|
||||
builder.append(ch);
|
||||
words.add(builder.toString());
|
||||
builder.delete(0, builder.length());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > 0 && (ch == '/' || ch == '.' || Character.isUpperCase(ch))) {
|
||||
words.add(builder.toString());
|
||||
builder.delete(0, builder.length());
|
||||
}
|
||||
builder.append(ch);
|
||||
}
|
||||
|
||||
int removedLength = 0;
|
||||
|
||||
String toPaste = "...";
|
||||
int index;
|
||||
while (true) {
|
||||
index = Math.max(0, words.size() / 2 - 1);
|
||||
String aWord = words.get(index);
|
||||
words.remove(index);
|
||||
if (words.size() < 2) {
|
||||
int toCut = length - removedLength - maxWidth + 3;
|
||||
int pos = (aWord.length() - toCut) / 2;
|
||||
toPaste = aWord.substring(0, pos) + "..." + aWord.substring(pos+toCut);
|
||||
break;
|
||||
}
|
||||
removedLength += aWord.length();
|
||||
if (length - removedLength <= maxWidth - 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
String word = words.get(i);
|
||||
if (i == index || words.size() == 1) builder.append(toPaste);
|
||||
builder.append(word);
|
||||
}
|
||||
return builder.toString().replaceAll("\\.{4,}", "...");
|
||||
}
|
||||
|
||||
/**
|
||||
* Expirable CharSequence. Very useful to control external library execution time,
|
||||
* i.e. when java.util.regex.Pattern match goes out of control.
|
||||
|
||||
@@ -195,4 +195,15 @@ public class StringUtilTest extends TestCase {
|
||||
assertEquals(Arrays.asList("\n", "\r\n", "\n", "\r\n", "\r", "\r", "aa\r", "bb\r\n", "cc\n", "\r", "dd\n", "\n", "\r\n", "\r"),
|
||||
Arrays.asList(StringUtil.splitByLinesKeepSeparators("\n\r\n\n\r\n\r\raa\rbb\r\ncc\n\rdd\n\n\r\n\r")));
|
||||
}
|
||||
|
||||
public void testShortened() {
|
||||
String[] names = {"AVeryVeeryLongClassName.java", "com.test.SomeJAVAClassName.java", "strangelowercaseclassname.java"};
|
||||
for (String name : names) {
|
||||
for (int i = name.length() + 1; i > 15; i--) {
|
||||
String shortened = StringUtil.getShortened(name, i);
|
||||
assertTrue(shortened.length() <= i);
|
||||
assertTrue(!shortened.contains("...."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user