From 756554179da7983572fe74abec810f3be9fb1a98 Mon Sep 17 00:00:00 2001 From: Marco Maccaferri Date: Mon, 24 Dec 2018 09:38:52 +0100 Subject: [PATCH] Updated editor tab stops handling --- src/com/maccasoft/tools/Application.java | 47 ++++++- src/com/maccasoft/tools/Preferences.java | 30 +++- .../maccasoft/tools/PreferencesDialog.java | 67 +++++---- .../maccasoft/tools/editor/SourceEditor.java | 130 ++++++++---------- 4 files changed, 170 insertions(+), 104 deletions(-) diff --git a/src/com/maccasoft/tools/Application.java b/src/com/maccasoft/tools/Application.java index 02984c0..6757fde 100644 --- a/src/com/maccasoft/tools/Application.java +++ b/src/com/maccasoft/tools/Application.java @@ -151,6 +151,32 @@ public class Application { tab.getEditor().setShowLineNumbers(((Boolean) evt.getNewValue()).booleanValue()); } } + else if (Preferences.PROP_TABWIDTH.equals(evt.getPropertyName())) { + CTabItem[] tabItem = tabFolder.getItems(); + for (int i = 0; i < tabItem.length; i++) { + SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData(); + tab.getEditor().setTabWidth(((Integer) evt.getNewValue()).intValue()); + } + } + else if (Preferences.PROP_USE_TABSTOPS.equals(evt.getPropertyName())) { + CTabItem[] tabItem = tabFolder.getItems(); + for (int i = 0; i < tabItem.length; i++) { + SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData(); + tab.getEditor().setUseTabstops(((Boolean) evt.getNewValue()).booleanValue()); + } + } + else if (Preferences.PROP_MNEMONIC_COLUMN.equals(evt.getPropertyName()) || Preferences.PROP_ARGUMENT_COLUMN.equals(evt.getPropertyName()) + || Preferences.PROP_COMMENT_COLUMN.equals(evt.getPropertyName())) { + CTabItem[] tabItem = tabFolder.getItems(); + for (int i = 0; i < tabItem.length; i++) { + SourceEditorTab tab = (SourceEditorTab) tabItem[i].getData(); + tab.getEditor().setTabStops(new int[] { + preferences.getMnemonicColumn(), + preferences.getArgumentColumn(), + preferences.getCommentColumn() + }); + } + } } }; @@ -292,8 +318,7 @@ public class Application { tab.setText(file.getName()); tab.setToolTipText(file.getAbsolutePath()); tab.setFile(file); - tab.getEditor().setShowLineNumbers(preferences.isShowLineNumbers()); - tab.getEditor().setFont(preferences.getEditorFont()); + applyEditoTabPreferences(tab); } }); } @@ -1117,9 +1142,8 @@ public class Application { private void handleFileNew() { SourceEditorTab tab = new SourceEditorTab(tabFolder, ""); tab.setText(getDefaultName()); + applyEditoTabPreferences(tab); tab.setFocus(); - tab.getEditor().setShowLineNumbers(preferences.isShowLineNumbers()); - tab.getEditor().setFont(preferences.getEditorFont()); } String getDefaultName() { @@ -1228,8 +1252,7 @@ public class Application { tab.setText(file.getName()); tab.setToolTipText(file.getAbsolutePath()); tab.setFile(file); - tab.getEditor().setShowLineNumbers(preferences.isShowLineNumbers()); - tab.getEditor().setFont(preferences.getEditorFont()); + applyEditoTabPreferences(tab); tabFolder.setSelection(tab.getTabItem()); tab.setFocus(); @@ -1239,6 +1262,18 @@ public class Application { }, true); } + void applyEditoTabPreferences(SourceEditorTab tab) { + tab.getEditor().setShowLineNumbers(preferences.isShowLineNumbers()); + tab.getEditor().setFont(preferences.getEditorFont()); + tab.getEditor().setTabWidth(preferences.getTabWidth()); + tab.getEditor().setTabStops(new int[] { + preferences.getMnemonicColumn(), + preferences.getArgumentColumn(), + preferences.getCommentColumn() + }); + tab.getEditor().setUseTabstops(preferences.isUseTabstops()); + } + private void handleFileSave() throws IOException { CTabItem tabItem = tabFolder.getSelection(); if (tabItem == null) { diff --git a/src/com/maccasoft/tools/Preferences.java b/src/com/maccasoft/tools/Preferences.java index 1957bb9..970b161 100644 --- a/src/com/maccasoft/tools/Preferences.java +++ b/src/com/maccasoft/tools/Preferences.java @@ -28,6 +28,11 @@ public class Preferences { public static final String PROP_ROOTS = "roots"; public static final String PROP_EDITOR_FONT = "editorFont"; public static final String PROP_SHOW_LINE_NUMBERS = "showLineNumbers"; + public static final String PROP_MNEMONIC_COLUMN = "mnemonicColumn"; + public static final String PROP_ARGUMENT_COLUMN = "argumentColumn"; + public static final String PROP_COMMENT_COLUMN = "commentColumn"; + public static final String PROP_USE_TABSTOPS = "useTabstops"; + public static final String PROP_TABWIDTH = "tabWidth"; public static final String PREFERENCES_NAME = ".z80-tools"; @@ -67,6 +72,8 @@ public class Preferences { int commentColumn; int labelCase; int mnemonicCase; + boolean useTabstops; + int tabWidth; boolean generateBinary; boolean generateHex; @@ -83,6 +90,7 @@ public class Preferences { showLineNumbers = true; reloadOpenTabs = true; + tabWidth = 4; mnemonicColumn = 16; argumentColumn = mnemonicColumn + 6; commentColumn = mnemonicColumn + 40; @@ -176,7 +184,7 @@ public class Preferences { } public void setMnemonicColumn(int mnemonicColumn) { - this.mnemonicColumn = mnemonicColumn; + changeSupport.firePropertyChange(PROP_MNEMONIC_COLUMN, this.mnemonicColumn, this.mnemonicColumn = mnemonicColumn); } public int getArgumentColumn() { @@ -184,7 +192,7 @@ public class Preferences { } public void setArgumentColumn(int argumentColumn) { - this.argumentColumn = argumentColumn; + changeSupport.firePropertyChange(PROP_ARGUMENT_COLUMN, this.argumentColumn, this.argumentColumn = argumentColumn); } public int getCommentColumn() { @@ -192,7 +200,7 @@ public class Preferences { } public void setCommentColumn(int commentColumn) { - this.commentColumn = commentColumn; + changeSupport.firePropertyChange(PROP_COMMENT_COLUMN, this.commentColumn, this.commentColumn = commentColumn); } public int getLabelCase() { @@ -211,6 +219,22 @@ public class Preferences { this.mnemonicCase = mnemonicCase; } + public boolean isUseTabstops() { + return useTabstops; + } + + public void setUseTabstops(boolean useTabstops) { + changeSupport.firePropertyChange(PROP_USE_TABSTOPS, this.useTabstops, this.useTabstops = useTabstops); + } + + public int getTabWidth() { + return tabWidth; + } + + public void setTabWidth(int tabWidth) { + changeSupport.firePropertyChange(PROP_TABWIDTH, this.tabWidth, this.tabWidth = tabWidth); + } + public boolean isGenerateBinary() { return generateBinary; } diff --git a/src/com/maccasoft/tools/PreferencesDialog.java b/src/com/maccasoft/tools/PreferencesDialog.java index 5cfad8c..b552342 100644 --- a/src/com/maccasoft/tools/PreferencesDialog.java +++ b/src/com/maccasoft/tools/PreferencesDialog.java @@ -45,6 +45,8 @@ public class PreferencesDialog extends Dialog { Text editorFont; Button editorFontBrowse; Button showLineNumbers; + Text tabWidth; + Button useTabstops; Button reloadOpenTabs; Text mnemonicColumn; @@ -131,6 +133,19 @@ public class PreferencesDialog extends Dialog { showLineNumbers.setText("Show line numbers"); showLineNumbers.setSelection(preferences.isShowLineNumbers()); + label = new Label(composite, SWT.NONE); + label.setText("Tab width"); + + tabWidth = new Text(composite, SWT.BORDER); + tabWidth.setLayoutData(new GridData(convertWidthInCharsToPixels(4), SWT.DEFAULT)); + tabWidth.setText(String.valueOf(preferences.getTabWidth())); + + new Label(composite, SWT.NONE); + + useTabstops = new Button(composite, SWT.CHECK); + useTabstops.setText("Use formatter tabstops"); + useTabstops.setSelection(preferences.isUseTabstops()); + new Label(composite, SWT.NONE); reloadOpenTabs = new Button(composite, SWT.CHECK); @@ -143,26 +158,7 @@ public class PreferencesDialog extends Dialog { addSeparator(composite); - label = new Label(composite, SWT.NONE); - label.setText("Compiler output"); - - Composite group = new Composite(composite, SWT.NONE); - layout = new GridLayout(3, false); - layout.marginWidth = layout.marginHeight = 0; - group.setLayout(layout); - group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); - - generateBinary = new Button(group, SWT.CHECK); - generateBinary.setText("Binary"); - generateBinary.setSelection(preferences.isGenerateBinary()); - - generateHex = new Button(group, SWT.CHECK); - generateHex.setText("Intel Hex"); - generateHex.setSelection(preferences.isGenerateHex()); - - generateListing = new Button(group, SWT.CHECK); - generateListing.setText("Listing"); - generateListing.setSelection(preferences.isGenerateListing()); + createCompilerGroup(composite); addSeparator(composite); @@ -289,19 +285,19 @@ public class PreferencesDialog extends Dialog { Label label = new Label(parent, SWT.NONE); label.setText("Mnemonic column"); mnemonicColumn = new Text(parent, SWT.BORDER); - mnemonicColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(3), SWT.DEFAULT)); + mnemonicColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(4), SWT.DEFAULT)); mnemonicColumn.setText(String.valueOf(preferences.getMnemonicColumn())); label = new Label(parent, SWT.NONE); label.setText("Arguments column"); argumentColumn = new Text(parent, SWT.BORDER); - argumentColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(3), SWT.DEFAULT)); + argumentColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(4), SWT.DEFAULT)); argumentColumn.setText(String.valueOf(preferences.getArgumentColumn())); label = new Label(parent, SWT.NONE); label.setText("Comment column"); commentColumn = new Text(parent, SWT.BORDER); - commentColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(3), SWT.DEFAULT)); + commentColumn.setLayoutData(new GridData(convertWidthInCharsToPixels(4), SWT.DEFAULT)); commentColumn.setText(String.valueOf(preferences.getCommentColumn())); label = new Label(parent, SWT.NONE); @@ -325,6 +321,29 @@ public class PreferencesDialog extends Dialog { mnemonicCase.select(preferences.getMnemonicCase()); } + void createCompilerGroup(Composite parent) { + Label label = new Label(parent, SWT.NONE); + label.setText("Compiler output"); + + Composite group = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(3, false); + layout.marginWidth = layout.marginHeight = 0; + group.setLayout(layout); + group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + generateBinary = new Button(group, SWT.CHECK); + generateBinary.setText("Binary"); + generateBinary.setSelection(preferences.isGenerateBinary()); + + generateHex = new Button(group, SWT.CHECK); + generateHex.setText("Intel Hex"); + generateHex.setSelection(preferences.isGenerateHex()); + + generateListing = new Button(group, SWT.CHECK); + generateListing.setText("Listing"); + generateListing.setSelection(preferences.isGenerateListing()); + } + void addSeparator(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, ((GridLayout) parent.getLayout()).numColumns, 1)); @@ -337,6 +356,8 @@ public class PreferencesDialog extends Dialog { preferences.setEditorFont(editorFont.getText().equals(defaultFont) ? null : editorFont.getText()); preferences.setShowLineNumbers(showLineNumbers.getSelection()); + preferences.setTabWidth(Integer.valueOf(tabWidth.getText())); + preferences.setUseTabstops(useTabstops.getSelection()); preferences.setReloadOpenTabs(reloadOpenTabs.getSelection()); preferences.setMnemonicColumn(Integer.valueOf(mnemonicColumn.getText())); diff --git a/src/com/maccasoft/tools/editor/SourceEditor.java b/src/com/maccasoft/tools/editor/SourceEditor.java index d186bf5..0bbba5d 100644 --- a/src/com/maccasoft/tools/editor/SourceEditor.java +++ b/src/com/maccasoft/tools/editor/SourceEditor.java @@ -84,6 +84,8 @@ public class SourceEditor { boolean ignoreRedo; boolean showLineNumbers = true; + int[] tabStops; + boolean useTabstops; class TextChange { @@ -675,26 +677,10 @@ public class SourceEditor { } sb.insert(index, text.getLineDelimiter()); - if (lineOffset > 0 && lineText.charAt(lineOffset - 1) == '{') { - String temp = sb.toString(); - for (i = 0; i < text.getTabs(); i++) { - sb.append(' '); - } - offset += sb.length(); - sb.append(temp); - sb.append('}'); - if (lineOffset > 1 && lineText.charAt(lineOffset - 2) == '{') { - sb.append('}'); - } - } - else { - offset += sb.length(); - } - text.setRedraw(false); try { text.insert(sb.toString()); - text.setCaretOffset(offset); + text.setCaretOffset(offset + sb.length()); } finally { text.setRedraw(true); } @@ -1020,47 +1006,26 @@ public class SourceEditor { int offset = text.getCaretOffset(); int lineNumber = text.getLineAtOffset(offset); int lineStart = text.getOffsetAtLine(lineNumber); - int lineOffset = offset - lineStart; - String line = text.getLine(lineNumber); - int nonBlankOffset = 0; - while (nonBlankOffset < line.length() && (line.charAt(nonBlankOffset) == ' ' || line.charAt(nonBlankOffset) == '\t')) { - nonBlankOffset++; - } - - int prevTabStop = -1; - - if (nonBlankOffset == lineOffset) { - while (lineNumber > 0) { - line = text.getLine(--lineNumber); - if ("".equals(line.trim())) { - continue; - } - - nonBlankOffset = 0; - while (nonBlankOffset < line.length() && (line.charAt(nonBlankOffset) == ' ' || line.charAt(nonBlankOffset) == '\t')) { - nonBlankOffset++; - } - if (nonBlankOffset > lineOffset) { - prevTabStop = nonBlankOffset; - break; + int tabStop = ((lineOffset + text.getTabs()) / text.getTabs()) * text.getTabs(); + if (useTabstops && tabStops != null) { + for (int i = tabStops.length - 1; i >= 0; i--) { + if (lineOffset < tabStops[i]) { + tabStop = tabStops[i]; } } } - if (prevTabStop == -1) { - prevTabStop = ((lineOffset + text.getTabs()) / text.getTabs()) * text.getTabs(); - } StringBuilder sb = new StringBuilder(); - while (sb.length() < (prevTabStop - lineOffset)) { - sb.append(" "); + while (sb.length() < (tabStop - lineOffset)) { + sb.append(' '); } text.setRedraw(false); try { text.insert(sb.toString()); - text.setCaretOffset(lineStart + prevTabStop); + text.setCaretOffset(lineStart + tabStop); text.showSelection(); } finally { text.setRedraw(true); @@ -1072,45 +1037,39 @@ public class SourceEditor { int lineNumber = text.getLineAtOffset(offset); int lineStart = text.getOffsetAtLine(lineNumber); - if (offset == lineStart) { + if (offset == lineStart || !useTabstops) { return true; } int lineOffset = offset - lineStart; - String line = text.getLine(lineNumber); - int nonBlankOffset = 0; - while (nonBlankOffset < line.length() && (line.charAt(nonBlankOffset) == ' ' || line.charAt(nonBlankOffset) == '\t')) { - nonBlankOffset++; - } - if (nonBlankOffset != lineOffset) { - return true; + int tabStop = (lineOffset / text.getTabs()) * text.getTabs(); + if (tabStop == lineOffset) { + tabStop -= text.getTabs(); } - int prevTabStop = -1; - while (lineNumber > 0) { - line = text.getLine(--lineNumber); - if ("".equals(line.trim())) { - continue; - } - - nonBlankOffset = 0; - while (nonBlankOffset < line.length() && (line.charAt(nonBlankOffset) == ' ' || line.charAt(nonBlankOffset) == '\t')) { - nonBlankOffset++; - } - if (nonBlankOffset < lineOffset) { - prevTabStop = nonBlankOffset; - break; + if (tabStops != null) { + for (int i = 0; i < tabStops.length; i++) { + if (tabStops[i] < lineOffset) { + tabStop = tabStops[i]; + } } } - if (prevTabStop == -1) { - prevTabStop = ((lineOffset - 1) / text.getTabs()) * text.getTabs(); + + String s = text.getLine(lineNumber).substring(tabStop, lineOffset); + while (s.endsWith(" ")) { + s = s.substring(0, s.length() - 1); + } + if (s.length() != 0) { + s = s + " "; + if ((s.length() + tabStop) >= lineOffset) { + return true; + } } text.setRedraw(false); try { - text.setSelection(lineStart + prevTabStop, offset); - text.insert(""); + text.replaceTextRange(lineStart + tabStop, lineOffset - tabStop, s); text.showSelection(); } finally { text.setRedraw(true); @@ -1118,4 +1077,31 @@ public class SourceEditor { return false; } + + public int[] getTabStops() { + return tabStops; + } + + public void setTabStops(int[] tabStops) { + this.tabStops = new int[tabStops.length + 1]; + this.tabStops[0] = 0; + System.arraycopy(tabStops, 0, this.tabStops, 1, tabStops.length); + } + + public boolean isUseTabstops() { + return useTabstops; + } + + public void setUseTabstops(boolean useTabstops) { + this.useTabstops = useTabstops; + } + + public void setTabWidth(int width) { + text.setTabs(width); + } + + public int getTabWidth() { + return text.getTabs(); + } + }