diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java index f358b1ba7bed579e96240fbe551c43bf03646783..155b1717fe154a707982a4b52c0ef0c455b2be08 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetFindReplaceTarget.java @@ -25,6 +25,11 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.data.DBDAttributeBinding; import org.jkiss.dbeaver.model.struct.DBSDataContainer; @@ -48,18 +53,27 @@ import java.util.regex.PatternSyntaxException; class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3 { private static final Log log = Log.getLog(SpreadsheetFindReplaceTarget.class); + private static SpreadsheetFindReplaceTarget instance; - private final SpreadsheetPresentation owner; + /** Uses {@link Object#hashCode()} to identity the current owner and determine whether he was changed or not. */ + private int ownerIdentity; private Pattern searchPattern; private Color scopeHighlightColor; private boolean replaceAll; private boolean sessionActive = false; private List originalSelection = null; - SpreadsheetFindReplaceTarget(SpreadsheetPresentation owner) - { - this.owner = owner; - this.scopeHighlightColor = UIStyles.getDefaultTextColor("AbstractTextEditor.Color.FindScope", SWT.COLOR_LIST_SELECTION); + public static synchronized SpreadsheetFindReplaceTarget getInstance() { + if (instance == null) { + instance = new SpreadsheetFindReplaceTarget(); + instance.scopeHighlightColor = UIStyles.getDefaultTextColor("AbstractTextEditor.Color.FindScope", SWT.COLOR_LIST_SELECTION); + } + return instance; + } + + public synchronized SpreadsheetFindReplaceTarget owned(@NotNull SpreadsheetPresentation newOwner) { + refreshOwner(newOwner); + return this; } public boolean isSessionActive() { @@ -89,6 +103,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public Point getSelection() { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return new Point(0, 0); + } Collection rowSelection = owner.getSpreadsheet().getRowSelection(); int minRow = rowSelection.stream().mapToInt(v -> v).min().orElse(-1); int maxRow = rowSelection.stream().mapToInt(v -> v).max().orElse(-1); @@ -99,6 +117,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public String getSelectionText() { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return ""; + } GridPos selection = (GridPos) owner.getSelection().getFirstElement(); if (selection == null) { return ""; @@ -112,7 +134,8 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public boolean isEditable() { - return owner.getController().getReadOnlyStatus() == null; + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + return owner != null && owner.getController().getReadOnlyStatus() == null; } @Override @@ -124,18 +147,26 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public void beginSession() { + final SpreadsheetPresentation owner = getActiveSpreadsheet(false); + if (owner == null) { + return; + } this.sessionActive = true; - this.owner.getControl().redraw(); + owner.getControl().redraw(); this.originalSelection = new ArrayList<>(owner.getSpreadsheet().getSelection()); - this.owner.highlightRows(-1, -1, null); + owner.highlightRows(-1, -1, null); } @Override public void endSession() { + final SpreadsheetPresentation owner = getActiveSpreadsheet(false); + if (owner == null) { + return; + } this.sessionActive = false; this.searchPattern = null; - Control control = this.owner.getControl(); + Control control = owner.getControl(); if (control != null && !control.isDisposed()) { owner.getSpreadsheet().deselectAll(); owner.getSpreadsheet().selectCells(this.originalSelection); @@ -150,6 +181,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public void setScope(IRegion scope) { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return; + } if (scope == null || scope.getLength() == 0) { owner.highlightRows(-1, -1, null); if (scope == null) { @@ -170,6 +205,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public void setSelection(int offset, int length) { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return; + } int columnCount = owner.getSpreadsheet().getColumnCount(); List selRows = new ArrayList<>(); for (int rowNum = 0; rowNum < length; rowNum++) { @@ -196,6 +235,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public int findAndSelect(int offset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord, boolean regExSearch) { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return - 1; + } searchPattern = null; ResultSetModel model = owner.getController().getModel(); @@ -295,6 +338,10 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public void replaceSelection(String text, boolean regExReplace) { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return; + } GridPos selection = (GridPos) owner.getSelection().getFirstElement(); if (selection == null) { return; @@ -319,8 +366,52 @@ class SpreadsheetFindReplaceTarget implements IFindReplaceTarget, IFindReplaceTa @Override public String toString() { + final SpreadsheetPresentation owner = getActiveSpreadsheet(); + if (owner == null) { + return super.toString(); + } DBSDataContainer dataContainer = owner.getController().getDataContainer(); return "Target: " + (dataContainer == null ? null : dataContainer.getName()); } + private void refreshOwner(@NotNull SpreadsheetPresentation newOwner) { + if (this.ownerIdentity == newOwner.hashCode()) { + return; + } + final boolean refreshSession = this.sessionActive; + final Pattern searchPattern = this.searchPattern; + if (refreshSession) { + this.endSession(); + } + this.ownerIdentity = newOwner.hashCode(); + if (refreshSession) { + this.beginSession(); + this.searchPattern = searchPattern; + } + } + + @Nullable + private SpreadsheetPresentation getActiveSpreadsheet() { + return getActiveSpreadsheet(true); + } + + @Nullable + private SpreadsheetPresentation getActiveSpreadsheet(boolean refreshActiveSpreadsheet) { + final IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (workbenchWindow == null) { + return null; + } + final IEditorPart activeEditor = workbenchWindow.getActivePage().getActiveEditor(); + if (activeEditor == null) { + return null; + } + final SpreadsheetPresentation spreadsheet = activeEditor.getAdapter(SpreadsheetPresentation.class); + if (spreadsheet == null) { + return null; + } + if (refreshActiveSpreadsheet) { + refreshOwner(spreadsheet); + } + return spreadsheet; + } } diff --git a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java index be95897c4d60c436ea25174bbc19b2d14949c85f..b09f1f8cdc43de9b489dd7bb205e667855563992 100644 --- a/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java +++ b/plugins/org.jkiss.dbeaver.ui.editors.data/src/org/jkiss/dbeaver/ui/controls/resultset/spreadsheet/SpreadsheetPresentation.java @@ -128,8 +128,6 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe private final Map openEditors = new HashMap<>(); - private SpreadsheetFindReplaceTarget findReplaceTarget; - // UI modifiers private Color backgroundAdded; private Color backgroundDeleted; @@ -165,11 +163,6 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe private Color highlightScopeColor; private boolean useNativeNumbersFormat; - public SpreadsheetPresentation() { - findReplaceTarget = new SpreadsheetFindReplaceTarget(this); - - } - public Spreadsheet getSpreadsheet() { return spreadsheet; } @@ -1366,7 +1359,7 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe }); return adapter.cast(page); } else if (adapter == IFindReplaceTarget.class) { - return adapter.cast(findReplaceTarget); + return adapter.cast(SpreadsheetFindReplaceTarget.getInstance().owned(this)); } return null; } @@ -1983,6 +1976,10 @@ public class SpreadsheetPresentation extends AbstractPresentation implements IRe ResultSetRow row = (ResultSetRow) (!recordMode ? rowElement : colElement); DBDAttributeBinding attribute = (DBDAttributeBinding)(!recordMode ? colElement : rowElement); + final SpreadsheetFindReplaceTarget findReplaceTarget = SpreadsheetFindReplaceTarget + .getInstance() + .owned(SpreadsheetPresentation.this); + if (findReplaceTarget.isSessionActive()) { boolean hasScope = highlightScopeFirstLine >= 0 && highlightScopeLastLine >= 0; boolean inScope = hasScope && row.getVisualNumber() >= highlightScopeFirstLine && row.getVisualNumber() <= highlightScopeLastLine;