diff --git a/sql12/build.xml b/sql12/build.xml index 037360ea33..4abd287625 100644 --- a/sql12/build.xml +++ b/sql12/build.xml @@ -8,7 +8,7 @@ - + diff --git a/sql12/core/doc/changes.txt b/sql12/core/doc/changes.txt index 3cac6986f5..b195c6c7fa 100755 --- a/sql12/core/doc/changes.txt +++ b/sql12/core/doc/changes.txt @@ -6,7 +6,80 @@ Not yet released, available in our GIT repository, snapshots and future releases Enhancements: -Security: Introduced option to use a key password for encrypting Alias passwords. +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/88 + The keyboard short cuts tab now contains the action's description (tooltip). + See menu File --> Global Preferences --> tab "Keyboard shortcuts" + + +Bug fixes: + +Oracle Plugin: Fixed typo, DB Ouptut --> DB Output + + +5.1.0 (03/26/2026) +================== + +Enhancements: + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/87 + The right mouse menu of UI-tables now offers to toggle columns between a monospaced font and the default font. + See the right mouse menu entry named "Toggle selected columns monospaced". + +The UI-table's "Copy separated by ..." right mouse menu function now allows + to display the copy result in a cell data dialog. + +The UI-table's "Copy separated by ..." right mouse menu function now allows + to concatenate cell values without separator. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/81 + Session Scripts Plugin: Session startup scripts now support running bookmarks + by @runbookmark the same way the SQL editor does. + +Session Scripts Plugin: Aliases combo box of the Session startup scripts frame now + sorts Aliases alphabetically and puts the ones on top which have Session startup scripts defined. + See menu Plugins --> Session Scripts ... + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/80 + SQL results displayed in their own window can be rerun automatically, too. + The UI behavior of SQL results displayed in their own window was improved. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/80 + SQL results can be rerun automatically after a configurable number of seconds. + To give access to this function the SQL result's rerun button was made switchable. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/81 + Bookmarks Plugin: A bookmark's statement can be run from within the SQL editor use @runbookmark + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/75 + The options "Allow to run all SQLs in editor" and "Allow to run a SQL in all open Sessions" + are now switched off by default. See menu File --> Global Preferences tab SQL. + Note: This change applies only to SQuirreL user directories that did not already + contain these options in their prefs.xml file. The path to SQuirreL's user directory is displayed + in SQuirrel's window title. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/79 + MS Excel file export: The MS Excel section of the file export dialog offers two new options: + 1. Option to define the name of the Excel sheet tab that is created inside the Excel file. + 2. Option to replace Excel sheet tabs in existing Excel files. + Note that those two (as several other) options will apply to automated exports, too. + To learn about automated exports see the link at the bottom of the file export dialog. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/76 + Cell data popup and cell detail display now offer right mouse menus to + Base64/Base32/Hex-decode selected text. The decoded text is written to the message panel. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/75 + New function to execute a SQL in multiple Sessions: + The new Session toolbar button "Run SQL in all open Sessions" (ctrl+alt+shift+ENTER) + executes the current SQL in all open Sessions. + The feature can be switched off at menu File --> Global Preferences --> tab SQL + --> checkbox "Allow to run a SQL in all open Sessions" + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/74 + Multiple selected Aliases can be selected and connected to. + +https://github.com/squirrel-sql-client/squirrel-sql-code/issues/73 + Security: Introduced option to use a key password for encrypting Alias passwords. When a key password is used SQuirreL can decrypt Alias-passwords only after the key password was entered. SQuirreL stores the key password in memory only. As a consequence the key password must be entered after SQuirreL was started and before an Alias, that uses password encryption, can be connected to. @@ -34,6 +107,13 @@ DB2 Plugin: The table details in the Object tree has a new tab Bug fixes: +Fixed "java.beans.IntrospectionException: Method not found" when creating an application dump. + See menu File --> Dump Application + +Deleting or editing SQL table results or Object tree "Content"-tables rose NullPointerException when + a table had one or more columns of type LONGVARCHAR and LONGVARCHAR types were chosen to be left out of generated WHERE clauses. + See menu File --> Global Preferences --> tab "Data type controls" --> section "CHAR, VARCHAR, LONGVARCHAR" + Alias find dialog (ctrl+alt+shift+g or ctrl+alt+shift+f): Modifying an Alias folder raised NullPointerException. diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/Application.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/Application.java index dc98aa17db..51e0954086 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/Application.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/Application.java @@ -23,7 +23,6 @@ */ import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -267,13 +266,7 @@ public void startup() _desktopStyle = new DesktopStyle(_globalPreferences); preferencesHaveChanged(null); - _globalPreferences.addPropertyChangeListener(new PropertyChangeListener() - { - public void propertyChange(PropertyChangeEvent evt) - { - preferencesHaveChanged(evt); - } - }); + _globalPreferences.addPropertyChangeListener(evt -> preferencesHaveChanged(evt)); SquirrelSplashScreen splash = null; if (args.getShowSplashScreen()) diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/Version.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/Version.java index 2203e371b7..3f5575693e 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/Version.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/Version.java @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - import java.io.IOException; import java.io.InputStream; import java.util.Properties; + +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; /** * Application version information. * @@ -35,7 +35,7 @@ public class Version * No I18n/StringManager here. This class is used to early. The right Locale may not have been set yet. */ private static final String APP_NAME = "SQuirreL SQL Client"; - private static final String COPYRIGHT = "Copyright (c) 2001-2025\nColin Bell, Gerd Wagner, Rob Manning and others"; + private static final String COPYRIGHT = "Copyright (c) 2001-2026\nColin Bell, Gerd Wagner, Rob Manning and others"; private static final String WEB_SITE = "http://www.squirrelsql.org"; private static final String WEB_SITE2 = "https://squirrelsql.org"; diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/action/ActionRegistry.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/action/ActionRegistry.java index 1f0ea21b37..1ceb0bb4af 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/action/ActionRegistry.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/action/ActionRegistry.java @@ -50,6 +50,7 @@ import net.sourceforge.squirrel_sql.client.session.action.EscapeDateAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlAction; +import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction; import net.sourceforge.squirrel_sql.client.session.action.FilterObjectsAction; import net.sourceforge.squirrel_sql.client.session.action.FindColumnsAction; import net.sourceforge.squirrel_sql.client.session.action.FindColumnsInObjectTreeNodesAction; @@ -184,6 +185,7 @@ public void registerToolsPopupActions(ActionCollection ac, ToolsPopupController toolsPopupController.addAction("redo", sqlPanel.getRedoAction()); toolsPopupController.addAction("runsql", ac.get(ExecuteSqlAction.class)); toolsPopupController.addAction("runallsqls", ac.get(ExecuteAllSqlsAction.class)); + toolsPopupController.addAction("runsqlinallsession", ac.get(ExecuteSqlInAllSessionsAction.class)); toolsPopupController.addAction("filenew", ac.get(FileNewAction.class)); toolsPopupController.addAction("filedetach", ac.get(FileDetachAction.class)); toolsPopupController.addAction("fileopen", ac.get(FileOpenAction.class)); @@ -325,6 +327,7 @@ public void preloadActions(ActionCollection actionCollection) actionCollection.add(new DumpSessionAction(app)); actionCollection.add(new ExecuteSqlAction(app)); actionCollection.add(new ExecuteAllSqlsAction(app)); + actionCollection.add(new ExecuteSqlInAllSessionsAction()); actionCollection.add(new ExitAction(app)); actionCollection.add(new FileNewAction(app)); actionCollection.add(new FileDetachAction(app)); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/cli/CliSQLExecuterHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/cli/CliSQLExecuterHandler.java index 5e8d1c69ec..359bdbf121 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/cli/CliSQLExecuterHandler.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/cli/CliSQLExecuterHandler.java @@ -1,5 +1,13 @@ package net.sourceforge.squirrel_sql.client.cli; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.sql.SQLException; +import java.util.ArrayList; + import net.sourceforge.squirrel_sql.client.session.SQLExecutionInfo; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetUpdateableTableModel; @@ -11,14 +19,6 @@ import net.sourceforge.squirrel_sql.fw.sql.querytokenizer.QueryHolder; import net.sourceforge.squirrel_sql.fw.util.Utilities; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.sql.SQLException; -import java.util.ArrayList; - public class CliSQLExecuterHandler extends CliSQLExecuterHandlerAdapter { private CliSession _cliSession; @@ -124,7 +124,7 @@ public void sqlResultSetAvailable(ResultSetWrapper rst, SQLExecutionInfo info, I DialectFactory.getDialectType(_cliSession.getMetaData()); - rsds.setSqlExecutionTabResultSet(rst, null, dialectType); + rsds.readDataFromJdbcResultSetForSqlExecution(rst, null, dialectType); ResultAsText resultAsText = new ResultAsText(rsds.getDataSetDefinition().getColumnDefinitions(), true, line -> onAddLine(line)); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesAndDriversManager.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesAndDriversManager.java index 22bba25d2e..2a2543a362 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesAndDriversManager.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesAndDriversManager.java @@ -18,6 +18,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.db.listholder.AliasListHolder; import net.sourceforge.squirrel_sql.client.gui.db.listholder.DriverListHolder; @@ -28,20 +36,15 @@ import net.sourceforge.squirrel_sql.fw.sql.ISQLDriver; import net.sourceforge.squirrel_sql.fw.sql.SQLDriver; import net.sourceforge.squirrel_sql.fw.sql.SQLDriverManager; -import net.sourceforge.squirrel_sql.fw.util.*; +import net.sourceforge.squirrel_sql.fw.util.IMessageHandler; +import net.sourceforge.squirrel_sql.fw.util.IObjectCacheChangeListener; +import net.sourceforge.squirrel_sql.fw.util.NullMessageHandler; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; import net.sourceforge.squirrel_sql.fw.xml.XMLException; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - public class AliasesAndDriversManager { private final static StringManager s_stringMgr = StringManagerFactory.getStringManager(AliasesAndDriversManager.class); @@ -248,12 +251,12 @@ public SQLAlias getAlias(IIdentifier id) return _aliasListHolder.get(id); } - public Iterator aliases() + public Iterator aliases() { return _aliasListHolder.getAll().iterator(); } - public List getAliasList() + public List getAliasList() { return _aliasListHolder.getAll(); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesList.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesList.java index c85b062983..7d282aa24f 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesList.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/AliasesList.java @@ -1,5 +1,13 @@ package net.sourceforge.squirrel_sql.client.gui.db; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JPanel; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.WindowManager; @@ -7,13 +15,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.StringUtilities; -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.List; - /* * Copyright (C) 2001-2004 Colin Bell * colbell@users.sourceforge.net @@ -165,6 +166,12 @@ public SQLAlias getSelectedAlias(MouseEvent evt) return getCurrentImpl().getSelectedAlias(evt); } + @Override + public List getAllSelectedAliases() + { + return getCurrentImpl().getAllSelectedAliases(); + } + @Override public SQLAlias getLeadSelectionValue() { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseList.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseList.java index 107ebdee14..f9d5187421 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseList.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseList.java @@ -1,16 +1,18 @@ package net.sourceforge.squirrel_sql.client.gui.db; -import net.sourceforge.squirrel_sql.fw.gui.SortedListModel; -import net.sourceforge.squirrel_sql.client.ApplicationListener; -import net.sourceforge.squirrel_sql.client.IApplication; - -import javax.swing.*; -import javax.swing.event.ListDataEvent; -import javax.swing.event.ListDataListener; -import java.awt.*; -import java.awt.event.MouseListener; +import java.awt.Dimension; +import java.awt.Point; import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; import java.util.ArrayList; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.gui.SortedListModel; import net.sourceforge.squirrel_sql.fw.props.Props; public abstract class BaseList implements IBaseList @@ -27,10 +29,17 @@ public String getToolTipText(MouseEvent event) private JScrollPane _comp = new JScrollPane(_list); - public BaseList(SortedListModel sortedListModel, IApplication app) + public BaseList(SortedListModel sortedListModel, boolean allowMultipleSelection) { _list.setModel(sortedListModel); - getList().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + if(allowMultipleSelection) + { + getList().getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + } + else + { + getList().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + } // Add listener to listen for items added/removed from list. _list.getModel().addListDataListener(new ListDataListener() @@ -51,14 +60,7 @@ public void contentsChanged(ListDataEvent evt) _comp.setPreferredSize(new Dimension(100, 100)); - app.addApplicationListener(new ApplicationListener() - { - public void saveApplicationState() - { - onSaveApplicationState(); - } - }); - + Main.getApplication().addApplicationListener(() -> onSaveApplicationState()); setSelIxFromPrefs(); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseListInternalFrame.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseListInternalFrame.java index 6b4eb126cf..2e841a12c0 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseListInternalFrame.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/BaseListInternalFrame.java @@ -18,6 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JFrame; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DockWidget; import net.sourceforge.squirrel_sql.fw.gui.BasePopupMenu; @@ -27,11 +33,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - abstract class BaseListInternalFrame extends DockWidget { private static final ILogger s_log = LoggerController.createLogger(BaseListInternalFrame.class); @@ -89,13 +90,6 @@ private void onMousePress(MouseEvent evt) { if (evt.isPopupTrigger()) { - - // If the user wants to select for Right mouse clicks then change the selection before popup appears - if (Main.getApplication().getSquirrelPreferences().getSelectOnRightMouseClick()) - { - _uiFactory.getList().selectListEntryAtPoint(evt.getPoint()); - } - if (_popupMenu == null) { _popupMenu = _uiFactory.getPopupMenu(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/DriversList.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/DriversList.java index dfb632538d..04f72afdcf 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/DriversList.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/DriversList.java @@ -18,18 +18,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.ToolTipManager; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.preferences.SquirrelPreferences; import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; import net.sourceforge.squirrel_sql.fw.sql.ISQLDriver; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.MouseEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; /** * This is a JList that dispays all the ISQLDriver * objects. @@ -61,7 +60,7 @@ public class DriversList extends BaseList implements IDriversList */ public DriversList(IApplication app) throws IllegalArgumentException { - super(new DriversListModel(), app); + super(new DriversListModel(), false); _app = app; _model = (DriversListModel) getList().getModel(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/IAliasesList.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/IAliasesList.java index bcaccd95c9..e46c96273c 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/IAliasesList.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/IAliasesList.java @@ -1,6 +1,7 @@ package net.sourceforge.squirrel_sql.client.gui.db; import java.awt.event.MouseEvent; +import java.util.List; /* * Copyright (C) 2004 Colin Bell @@ -29,6 +30,8 @@ public interface IAliasesList extends IBaseList */ SQLAlias getSelectedAlias(MouseEvent evt); + List getAllSelectedAliases(); + void sortAliases(); void requestFocus(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JListAliasesListImpl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JListAliasesListImpl.java index a64ea2df06..190920ed5f 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JListAliasesListImpl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JListAliasesListImpl.java @@ -1,5 +1,14 @@ package net.sourceforge.squirrel_sql.client.gui.db; +import java.awt.BorderLayout; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.util.List; +import javax.swing.JList; +import javax.swing.SwingUtilities; +import javax.swing.event.ListDataEvent; +import javax.swing.event.ListDataListener; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.db.aliascolor.ListAliasColorSelectionHandler; @@ -7,15 +16,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.JList; -import javax.swing.SwingUtilities; -import javax.swing.event.ListDataEvent; -import javax.swing.event.ListDataListener; -import java.awt.BorderLayout; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseEvent; - /* * Copyright (C) 2001-2004 Colin Bell * colbell@users.sourceforge.net @@ -53,7 +53,7 @@ public class JListAliasesListImpl extends BaseList implements IAliasesList public JListAliasesListImpl(IApplication app, AliasesListModel aliasesListModel, AliasListSelectionListener selectionListener) { - super(aliasesListModel, app); + super(aliasesListModel, true); _model = aliasesListModel; getList().setLayout(new BorderLayout()); @@ -160,6 +160,12 @@ public SQLAlias getSelectedAlias(MouseEvent evt) return (SQLAlias)getList().getSelectedValue(); } + @Override + public List getAllSelectedAliases() + { + return getList().getSelectedValuesList(); + } + public void sortAliases() { final SQLAlias selectedAlias = getSelectedAlias(null); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JTreeAliasesListImpl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JTreeAliasesListImpl.java index 21f2e3915d..abb2a28d05 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JTreeAliasesListImpl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/db/JTreeAliasesListImpl.java @@ -12,6 +12,7 @@ import java.awt.event.MouseListener; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import javax.activation.DataHandler; @@ -29,7 +30,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; - import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.db.aliascolor.TreeAliasColorSelectionHandler; @@ -544,6 +544,16 @@ else if(selNode.getUserObject() instanceof AliasFolder) _tree.setSelectionPath(new TreePath(treeModel.getPathToRoot(newNode))); } + public List getAllSelectedAliases() + { + return + Arrays.stream(_tree.getSelectionPaths()) + .map(p -> p.getLastPathComponent()) + .filter(n -> n instanceof DefaultMutableTreeNode dmt && dmt.getUserObject() instanceof SQLAlias) + .map(n -> (SQLAlias)((DefaultMutableTreeNode) n).getUserObject()) + .toList(); + } + public SQLAlias getSelectedAlias(MouseEvent evt) { TreePath path = _tree.getSelectionPath(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/desktopcontainer/docktabdesktop/DockTabDesktopPane.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/desktopcontainer/docktabdesktop/DockTabDesktopPane.java index e0caec2a9e..8c7537d8a4 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/desktopcontainer/docktabdesktop/DockTabDesktopPane.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/desktopcontainer/docktabdesktop/DockTabDesktopPane.java @@ -1,9 +1,41 @@ package net.sourceforge.squirrel_sql.client.gui.desktopcontainer.docktabdesktop; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.ArrayList; +import java.util.HashSet; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JToggleButton; +import javax.swing.KeyStroke; +import javax.swing.WindowConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import net.sourceforge.squirrel_sql.client.ApplicationListener; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.*; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DockDelegate; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DockWidget; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.IDesktopContainer; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.IWidget; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.TabDelegate; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.TabWidget; import net.sourceforge.squirrel_sql.client.gui.mainframe.SquirrelDesktopManager; import net.sourceforge.squirrel_sql.client.mainframe.action.CloseAllButCurrentSessionsAction; import net.sourceforge.squirrel_sql.client.mainframe.action.CloseAllSessionsAction; @@ -11,22 +43,12 @@ import net.sourceforge.squirrel_sql.client.session.action.CloseSessionWindowAction; import net.sourceforge.squirrel_sql.client.session.action.GoToAliasSessionAction; import net.sourceforge.squirrel_sql.client.session.action.RenameSessionAction; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.ButtonTabComponent; import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.SmallTabButton; import net.sourceforge.squirrel_sql.fw.resources.Resources; -import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.util.ArrayList; -import java.util.HashSet; - // public class DockTabDesktopPane extends JComponent implements IDesktopContainer { @@ -602,7 +624,7 @@ private JMenuItem createMenu(Action action) JMenuItem ret = new JMenuItem(action); String accel = (String) action.getValue(Resources.ACCELERATOR_STRING); - Main.getApplication().getShortcutManager().setAccelerator(ret, KeyStroke.getKeyStroke(accel), action); + Main.getApplication().getShortcutManager().setAccelerator(ret, KeyStroke.getKeyStroke(accel), action, ShortCutDescriptionReader.of(action)); return ret; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/mainframe/MainFrameMenuBar.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/mainframe/MainFrameMenuBar.java index e3d41a85be..b73862ab4a 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/mainframe/MainFrameMenuBar.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/mainframe/MainFrameMenuBar.java @@ -105,6 +105,7 @@ import net.sourceforge.squirrel_sql.client.session.action.EscapeDateAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlAction; +import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction; import net.sourceforge.squirrel_sql.client.session.action.FindColumnsAction; import net.sourceforge.squirrel_sql.client.session.action.FormatSQLAction; import net.sourceforge.squirrel_sql.client.session.action.GoToAliasSessionAction; @@ -428,14 +429,12 @@ private JMenu createSessionMenu(Resources rsrc) addToMenu(rsrc, FindColumnsAction.class, menu); addToMenu(rsrc, ExecuteSqlAction.class, menu); addToMenu(rsrc, ExecuteAllSqlsAction.class, menu); + addToMenu(rsrc, ExecuteSqlInAllSessionsAction.class, menu); menu.add(createTransactionMenu(rsrc)); addToMenu(rsrc, SQLFilterAction.class, menu); menu.addSeparator(); addToMenu(rsrc, ViewObjectAtCursorInObjectTreeAction.class, menu); - menu.addSeparator(); menu.add(createSessionWindowFileMenu(rsrc)); - addToMenu(rsrc, ChangeTrackAction.class, menu); - menu.addSeparator(); menu.add(createSavedSessionMenu(rsrc)); menu.addSeparator(); addToMenu(rsrc, ShowNativeSQLAction.class, menu); @@ -655,6 +654,7 @@ private JMenu createSessionWindowFileMenu(Resources rsrc) addToMenu(rsrc, FileAppendAction.class, menu); addToMenu(rsrc, FilePrintAction.class, menu); addToMenu(rsrc, FileReloadAction.class, menu); + addToMenu(rsrc, ChangeTrackAction.class, menu); return menu; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SQLInternalFrameToolBar.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SQLInternalFrameToolBar.java index 7791e5367f..dd0cfddd7a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SQLInternalFrameToolBar.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SQLInternalFrameToolBar.java @@ -6,6 +6,7 @@ import net.sourceforge.squirrel_sql.client.session.action.ChangeTrackAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlAction; +import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction; import net.sourceforge.squirrel_sql.client.session.action.GoToLastEditLocationAction; import net.sourceforge.squirrel_sql.client.session.action.NextSqlAction; import net.sourceforge.squirrel_sql.client.session.action.PreviousSqlAction; @@ -45,6 +46,7 @@ private void createGUI(ISession session, ISQLPanelAPI panel) add(actions.get(ExecuteSqlAction.class)); addSeparator(); add(actions.get(ExecuteAllSqlsAction.class)); + add(actions.get(ExecuteSqlInAllSessionsAction.class)); addSeparator(); add(actions.get(FileNewAction.class)); add(actions.get(FileDetachAction.class)); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SessionPanelToolBar.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SessionPanelToolBar.java index 6a21f3a9ab..7a6013ee4a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SessionPanelToolBar.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/gui/session/SessionPanelToolBar.java @@ -6,6 +6,7 @@ import net.sourceforge.squirrel_sql.client.session.action.ChangeTrackAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction; import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlAction; +import net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction; import net.sourceforge.squirrel_sql.client.session.action.FindColumnsAction; import net.sourceforge.squirrel_sql.client.session.action.GoToLastEditLocationAction; import net.sourceforge.squirrel_sql.client.session.action.NextSqlAction; @@ -76,6 +77,7 @@ private void createGUI(ISession session) add(actions.get(ExecuteSqlAction.class)); addSeparator(); add(actions.get(ExecuteAllSqlsAction.class)); + add(actions.get(ExecuteSqlInAllSessionsAction.class)); addSeparator(); // actions.get(ExecuteSqlAction.class).setEnabled(false); add(actions.get(SQLFilterAction.class)); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/mainframe/action/ConnectToAliasAction.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/mainframe/action/ConnectToAliasAction.java index 6ea21a214a..056cd83e57 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/mainframe/action/ConnectToAliasAction.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/mainframe/action/ConnectToAliasAction.java @@ -18,12 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.event.ActionEvent; +import java.util.List; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.gui.db.IAliasesList; import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias; -import java.awt.event.ActionEvent; - public class ConnectToAliasAction extends AliasAction { /** @@ -51,11 +51,9 @@ public ConnectToAliasAction(IApplication app, IAliasesList list) */ public void actionPerformed(ActionEvent evt) { - moveToFrontAndSelectAliasFrame(); - final SQLAlias alias = _aliases.getSelectedAlias(null); - if (alias != null) - { - new ConnectToAliasCommand(alias).executeConnect(); - } + moveToFrontAndSelectAliasFrame(); + List selectedAliases = _aliases.getAllSelectedAliases(); + + selectedAliases.forEach(a -> new ConnectToAliasCommand(a).executeConnect()); } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/DefaultSessionPlugin.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/DefaultSessionPlugin.java index 6b50476681..7bcc03073e 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/DefaultSessionPlugin.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/DefaultSessionPlugin.java @@ -20,14 +20,13 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import javax.swing.JMenu; +import javax.swing.JMenu; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.event.SessionAdapter; import net.sourceforge.squirrel_sql.client.session.event.SessionEvent; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.INodeExpander; import net.sourceforge.squirrel_sql.client.session.properties.ISessionPropertiesPanel; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; @@ -59,6 +58,12 @@ public boolean allowsSessionStartedInBackground() return false; } + @Override + public int getSessionStartedCallRank() + { + return 0; + } + /** * Called when a session shutdown. * diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/ISessionPlugin.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/ISessionPlugin.java index 86d19d7fa1..b40572f728 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/ISessionPlugin.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/ISessionPlugin.java @@ -19,11 +19,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.INodeExpander; import net.sourceforge.squirrel_sql.client.session.properties.ISessionPropertiesPanel; +import net.sourceforge.squirrel_sql.fw.sql.DatabaseObjectType; /** * Base interface for all plugins associated with a session. */ @@ -61,6 +61,13 @@ public interface ISessionPlugin extends IPlugin */ PluginSessionCallback sessionStarted(ISession session); + /** + * Allows to influence the order in which {@link #sessionStarted(ISession)} is called with respect to other SessionPlugins. + * Safely influencing the order is possible only when {@link #allowsSessionStartedInBackground()} returns false. + */ + int getSessionStartedCallRank(); + + /** * Called when a session shutdown. */ diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfo.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfo.java index 99bcfaee7b..8b0d16307c 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfo.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfo.java @@ -34,7 +34,6 @@ public interface IPropertyNames String IS_LOADED = "isLoaded"; String PLUGIN_CLASS_NAME = "pluginClassName"; String VERSION = "version"; - String WEB_SITE = "webSite"; } private String _pluginClassName; diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfoBeanInfo.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfoBeanInfo.java index 27ffe71d46..0587fba221 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfoBeanInfo.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginInfoBeanInfo.java @@ -21,6 +21,8 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.beans.SimpleBeanInfo; +import java.util.ArrayList; +import java.util.List; /** * This is the BeanInfo class for PluginInfo. @@ -32,7 +34,7 @@ public final class PluginInfoBeanInfo extends SimpleBeanInfo private interface IPropNames extends PluginInfo.IPropertyNames { - // Empty body, purely to shorten the interface name for convienience. + // Empty body, purely to shorten the interface name for convenience. } /** @@ -46,22 +48,17 @@ public PropertyDescriptor[] getPropertyDescriptors() { try { - PropertyDescriptor[] s_descr = new PropertyDescriptor[8]; + List s_descr = new ArrayList<>(); - s_descr[0] = - new PropertyDescriptor(IPropNames.PLUGIN_CLASS_NAME, PluginInfo.class, "getPluginClassName", null); - s_descr[1] = new PropertyDescriptor(IPropNames.IS_LOADED, PluginInfo.class, "isLoaded", null); - s_descr[2] = - new PropertyDescriptor(IPropNames.INTERNAL_NAME, PluginInfo.class, "getInternalName", null); - s_descr[3] = - new PropertyDescriptor(IPropNames.DESCRIPTIVE_NAME, PluginInfo.class, "getDescriptiveName", null); - s_descr[4] = new PropertyDescriptor(IPropNames.AUTHOR, PluginInfo.class, "getAuthor", null); - s_descr[5] = - new PropertyDescriptor(IPropNames.CONTRIBUTORS, PluginInfo.class, "getContributors", null); - s_descr[6] = new PropertyDescriptor(IPropNames.WEB_SITE, PluginInfo.class, "getWebSite", null); - s_descr[7] = new PropertyDescriptor(IPropNames.VERSION, PluginInfo.class, "getVersion", null); + s_descr.add(new PropertyDescriptor(IPropNames.PLUGIN_CLASS_NAME, PluginInfo.class, "getPluginClassName", null)); + s_descr.add(new PropertyDescriptor(IPropNames.IS_LOADED, PluginInfo.class, "isLoaded", null)); + s_descr.add(new PropertyDescriptor(IPropNames.INTERNAL_NAME, PluginInfo.class, "getInternalName", null)); + s_descr.add(new PropertyDescriptor(IPropNames.DESCRIPTIVE_NAME, PluginInfo.class, "getDescriptiveName", null)); + s_descr.add(new PropertyDescriptor(IPropNames.AUTHOR, PluginInfo.class, "getAuthor", null)); + s_descr.add(new PropertyDescriptor(IPropNames.CONTRIBUTORS, PluginInfo.class, "getContributors", null)); + s_descr.add(new PropertyDescriptor(IPropNames.VERSION, PluginInfo.class, "getVersion", null)); - return s_descr; + return s_descr.toArray(new PropertyDescriptor[0]); } catch (IntrospectionException e) { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginManager.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginManager.java index c26d6a4aa1..9228587fff 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginManager.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/plugin/PluginManager.java @@ -21,6 +21,20 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import net.sourceforge.squirrel_sql.client.ApplicationArguments; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias; @@ -45,21 +59,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - /** * Manages plugins for the application. * @@ -178,42 +177,47 @@ public synchronized void sessionStarted(final ISession session) final List plugins = new ArrayList(); _activeSessions.put(session.getIdentifier(), plugins); - ArrayList startInFG = new ArrayList(); - final ArrayList startInBG = new ArrayList(); + ArrayList startInFG = new ArrayList<>(); + final ArrayList startInBG = new ArrayList<>(); for (Iterator it = _sessionPlugins.iterator(); it.hasNext();) { SessionPluginInfo spi = it.next(); - if (spi.getSessionPlugin().allowsSessionStartedInBackground()) + if(spi.getSessionPlugin().allowsSessionStartedInBackground()) { startInBG.add(spi); - } else + } + else { startInFG.add(spi); } - } session.setPluginsfinishedLoading(true); - for (Iterator it = startInFG.iterator(); it.hasNext();) - { - SessionPluginInfo spi = it.next(); - sendSessionStarted(session, spi, plugins); - } + + startInFG.sort((spi1, spi2) -> compareBySessionStartedCallRank(spi1, spi2)); + for(SessionPluginInfo spi : startInFG) + { + sendSessionStarted(session, spi, plugins); + } session.getApplication().getThreadPool().addTask(new Runnable() { public void run() { - for (Iterator it = startInBG.iterator(); it.hasNext();) - { - SessionPluginInfo spi = it.next(); - sendSessionStarted(session, spi, plugins); - } + for(SessionPluginInfo spi : startInBG) + { + sendSessionStarted(session, spi, plugins); + } session.setPluginsfinishedLoading(true); } }); } + private int compareBySessionStartedCallRank(SessionPluginInfo spi1, SessionPluginInfo spi2) + { + return Integer.compare(spi1.getSessionPlugin().getSessionStartedCallRank(), spi2.getSessionPlugin().getSessionStartedCallRank()); + } + private void sendSessionStarted(ISession session, SessionPluginInfo spi, List plugins) { try @@ -222,30 +226,17 @@ private void sendSessionStarted(ISession session, SessionPluginInfo spi, List list = - _pluginSessionCallbacksBySessionID.get(session.getIdentifier()); - if (null == list) - { - list = new ArrayList(); - _pluginSessionCallbacksBySessionID.put(session.getIdentifier(), list); - } - list.add(pluginSessionCallback); - + List list = _pluginSessionCallbacksBySessionID.computeIfAbsent(session.getIdentifier(), k -> new ArrayList<>()); + list.add(pluginSessionCallback); plugins.add(spi); } - } catch (final Throwable th) + } + catch(final Throwable th) { - final String msg = - s_stringMgr.getString("PluginManager.error.sessionstarted", spi.getPlugin().getDescriptiveName()); - s_log.error(msg, th); - GUIUtils.processOnSwingEventThread(new Runnable() - { - public void run() - { - _app.showErrorDialog(msg, th); - } - }); + final String msg =s_stringMgr.getString("PluginManager.error.sessionstarted", spi.getPlugin().getDescriptiveName()); + s_log.error(msg, th); + GUIUtils.processOnSwingEventThread(() -> _app.showErrorDialog(msg, th)); } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/I18NStrings.properties index d5ab22254f..efaf97d4fb 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/I18NStrings.properties @@ -82,6 +82,7 @@ SQLPreferencesPanel.largeScriptStmtCount.note=Note: If the number of statements SQLPreferencesPanel.copy.quoted.sql.to.clip=In quotes functions should copy quoted SQLs to clipboard SQLPreferencesPanel.allow.run.all.sqls.in.editor=Allow to run all SQLs in editor +SQLPreferencesPanel.allow.run.sql.in.all.sessions=Allow to run a SQL in all open Sessions SQLPreferencesPanel.title=SQL diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesController.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesController.java index 70fd9a2692..5c91214f6a 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesController.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesController.java @@ -18,6 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Color; +import java.awt.Component; +import javax.swing.JColorChooser; +import javax.swing.JFileChooser; +import javax.swing.JScrollPane; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.session.mainpanel.changetrack.ChangeTrackPrefsPanelController; @@ -28,12 +33,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.JColorChooser; -import javax.swing.JFileChooser; -import javax.swing.JScrollPane; -import java.awt.Color; -import java.awt.Component; - /** * This preferences panel allows maintenance of SQL preferences. * @author Colin Bell @@ -78,6 +77,7 @@ void loadData() _panel.queryTimeout.setInt(prefs.getQueryTimeout()); _panel.chkCopyQuotedSqlsToClip.setSelected(prefs.getCopyQuotedSqlsToClip()); _panel.chkAllowRunAllSQLsInEditor.setSelected(prefs.getAllowRunAllSQLsInEditor()); + _panel.chkAllowRunSqlInAllSessions.setSelected(prefs.getAllowRunSqlInAllSessions()); _panel.chkMarkCurrentSql.setSelected(prefs.isMarkCurrentSql()); _panel.getCurrentSqlMarkColorIcon().setColor(new Color(prefs.getCurrentSqlMarkColorRGB())); @@ -113,6 +113,7 @@ public void applyChanges() prefs.setCopyQuotedSqlsToClip(_panel.chkCopyQuotedSqlsToClip.isSelected()); prefs.setAllowRunAllSQLsInEditor(_panel.chkAllowRunAllSQLsInEditor.isSelected()); + prefs.setAllowRunSqlInAllSessions(_panel.chkAllowRunSqlInAllSessions.isSelected()); prefs.setMarkCurrentSql(_panel.chkMarkCurrentSql.isSelected()); prefs.setCurrentSqlMarkColorRGB((_panel.getCurrentSqlMarkColorIcon()).getColor().getRGB()); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesPanel.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesPanel.java index 238480d604..e0ead47375 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesPanel.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SQLPreferencesPanel.java @@ -1,14 +1,10 @@ package net.sourceforge.squirrel_sql.client.preferences; -import net.sourceforge.squirrel_sql.client.session.mainpanel.changetrack.ChangeTrackPrefsPanel; -import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabheader.ResultTabHeaderPrefsPanel; -import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; -import net.sourceforge.squirrel_sql.fw.gui.IntegerField; -import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; -import net.sourceforge.squirrel_sql.fw.gui.OutputLabel; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; @@ -18,11 +14,14 @@ import javax.swing.JRadioButton; import javax.swing.JTextField; import javax.swing.SwingConstants; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; +import net.sourceforge.squirrel_sql.client.session.mainpanel.changetrack.ChangeTrackPrefsPanel; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabheader.ResultTabHeaderPrefsPanel; +import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; +import net.sourceforge.squirrel_sql.fw.gui.IntegerField; +import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; +import net.sourceforge.squirrel_sql.fw.gui.OutputLabel; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; public final class SQLPreferencesPanel extends JPanel { @@ -39,6 +38,7 @@ public final class SQLPreferencesPanel extends JPanel IntegerField queryTimeout = new IntegerField(); JCheckBox chkCopyQuotedSqlsToClip = new JCheckBox(s_stringMgr.getString("SQLPreferencesPanel.copy.quoted.sql.to.clip")); JCheckBox chkAllowRunAllSQLsInEditor = new JCheckBox(s_stringMgr.getString("SQLPreferencesPanel.allow.run.all.sqls.in.editor")); + JCheckBox chkAllowRunSqlInAllSessions = new JCheckBox(s_stringMgr.getString("SQLPreferencesPanel.allow.run.sql.in.all.sessions")); JCheckBox chkMarkCurrentSql = new JCheckBox(s_stringMgr.getString("SQLPreferencesPanel.mark.current.sql")); JButton btnCurrentSqlMarkColorRGB = new JButton(); @@ -149,35 +149,40 @@ private JPanel createGeneralPanel(ResultTabHeaderPrefsPanel resultTabHeaderPrefs gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = GridBagConstraints.REMAINDER; + pnl.add(chkAllowRunSqlInAllSessions, gbc); + + gbc.gridx = 0; + gbc.gridy = 6; + gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.NONE; pnl.add(createCurrentSqlMarkPanel(), gbc); gbc.gridx = 0; - gbc.gridy = 6; + gbc.gridy = 7; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.NONE; pnl.add(chkUseStatementSeparatorAsSqlToExecuteBounds, gbc); gbc.gridx = 0; - gbc.gridy = 7; + gbc.gridy = 8; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; pnl.add(resultTabHeaderPrefsPanel , gbc); gbc.gridx = 0; - gbc.gridy = 8; + gbc.gridy = 9; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; pnl.add(createReloadSQLContentsPanel(), gbc); gbc.gridx = 0; - gbc.gridy = 9; + gbc.gridy = 10; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.NONE; pnl.add(createMaxTextOutputColumnWidthPanel(), gbc); gbc.gridx = 0; - gbc.gridy = 10; + gbc.gridy = 11; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.NONE; pnl.add(chkNotifyExternalFileChanges, gbc); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferences.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferences.java index ff537a2aef..bf19877be7 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferences.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferences.java @@ -20,6 +20,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Color; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.Serializable; +import java.sql.DriverManager; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import net.sourceforge.squirrel_sql.client.action.ActionKeys; import net.sourceforge.squirrel_sql.client.gui.db.mainframetitle.PositionInMainFrameTitle; import net.sourceforge.squirrel_sql.client.gui.mainframe.MainFrameWindowState; @@ -36,16 +45,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; import net.sourceforge.squirrel_sql.fw.xml.XMLBeanReader; import net.sourceforge.squirrel_sql.fw.xml.XMLBeanWriter; - -import java.awt.Color; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.Serializable; -import java.sql.DriverManager; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; /** * This class represents the application preferences. * @@ -63,6 +62,7 @@ public interface IPropertyNames String LARGE_SCRIPT_STMT_COUNT = "largeScriptStmtCount"; String COPY_QUOTED_SQLS_TO_CLIP = "copyQuotedSqlsToClip"; String ALLOW_RUN_ALL_SQLS_IN_EDITOR = "allowRunAllSQLsInEditor"; + String ALLOW_RUN_SQLS_IN_ALL_OPEN_SESSIONS = "allowRunSqlInAllSessions"; String MARK_CURRENT_SQL = "markCurrentSql"; String CURRENT_SQL_MARK_COLOR_RGB = "currentSqlMarkColorRGB"; @@ -213,9 +213,11 @@ public interface IJdbcDebugTypes private boolean _copyQuotedSqlsToClip; - private boolean _allowRunAllSQLsInEditor = true; + private boolean _allowRunAllSQLsInEditor = false; + + private boolean _allowRunSqlInAllSessions = false; - /** Show tooltips for controls. */ + /** Show tooltips for controls. */ private boolean _showToolTips = true; /** Use scrollable tabbed panes. JDK 1.4 and above only. */ @@ -1331,7 +1333,7 @@ public void setCopyQuotedSqlsToClip(boolean copyQuotedSqlsToClip) public boolean getAllowRunAllSQLsInEditor() { - return _allowRunAllSQLsInEditor; + return isAllowRunAllSQLsInEditor(); } public boolean isAllowRunAllSQLsInEditor() @@ -1344,7 +1346,23 @@ public void setAllowRunAllSQLsInEditor(boolean allowRunAllSQLsInEditor) _allowRunAllSQLsInEditor = allowRunAllSQLsInEditor; } - public boolean isMarkCurrentSql() + public boolean getAllowRunSqlInAllSessions() + { + return isAllowRunSqlInAllSessions(); + } + + public boolean isAllowRunSqlInAllSessions() + { + return _allowRunSqlInAllSessions; + } + + public void setAllowRunSqlInAllSessions(boolean allowRunSqlInAllSessions) + { + _allowRunSqlInAllSessions = allowRunSqlInAllSessions; + } + + + public boolean isMarkCurrentSql() { return _markCurrentSql; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferencesBeanInfo.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferencesBeanInfo.java index 135a7412c6..5f5db1ab2d 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferencesBeanInfo.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/SquirrelPreferencesBeanInfo.java @@ -19,12 +19,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.fw.util.Utilities; - import java.beans.IndexedPropertyDescriptor; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.beans.SimpleBeanInfo; +import net.sourceforge.squirrel_sql.fw.util.Utilities; /** * This is the BeanInfo class for SquirrelPreferences. @@ -57,6 +56,7 @@ public PropertyDescriptor[] getPropertyDescriptors() prop(LARGE_SCRIPT_STMT_COUNT, SquirrelPreferences.class, "getLargeScriptStmtCount", "setLargeScriptStmtCount"), prop(ALLOW_RUN_ALL_SQLS_IN_EDITOR, SquirrelPreferences.class, "isAllowRunAllSQLsInEditor", "setAllowRunAllSQLsInEditor"), + prop(ALLOW_RUN_SQLS_IN_ALL_OPEN_SESSIONS, SquirrelPreferences.class, "isAllowRunSqlInAllSessions", "setAllowRunSqlInAllSessions"), prop(MARK_CURRENT_SQL, SquirrelPreferences.class, "isMarkCurrentSql", "setMarkCurrentSql"), prop(CURRENT_SQL_MARK_COLOR_RGB, SquirrelPreferences.class, "getCurrentSqlMarkColorRGB", "setCurrentSqlMarkColorRGB"), diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/I18NStrings.properties index 49b8a4476c..1ce8842791 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/I18NStrings.properties @@ -1,12 +1,13 @@ keystroke.prefs.title=Keyboard shortcuts keystroke.prefs.hint=Configure keyboard shortcuts -ShortcutPrefsCtrl.column.actionName=Action Name +ShortcutPrefsCtrl.column.actionName=Action name ShortcutPrefsCtrl.column.validKeyStroke=Valid shortcut ShortcutPrefsCtrl.column.defaultKeyStroke=Default shortcut +ShortcutPrefsCtrl.column.description=Action description ShortcutPrefsPanel.lbl.edit.shortcut=Enter shortcut: -ShortcutPrefsPanel.txt.shortcut.formated=Selected action: "{0}" (Default shortcut: {1}) +ShortcutPrefsPanel.txt.shortcut.formated_extended=Selected action: "{0}" / Default shortcut: {1} / Description: {2} ShortcutPrefsPanel.btn.apply=Apply shortcut ShortcutPrefsPanel.btn.remove=Remove shortcut diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/ShortcutPrefsCtrl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/ShortcutPrefsCtrl.java index 739eab771f..e906ae75a2 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/ShortcutPrefsCtrl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/preferences/shortcut/ShortcutPrefsCtrl.java @@ -1,5 +1,14 @@ package net.sourceforge.squirrel_sql.client.preferences.shortcut; +import java.awt.Color; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.List; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.shortcut.Shortcut; import net.sourceforge.squirrel_sql.client.shortcut.ShortcutUtil; @@ -10,16 +19,7 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.Utilities; - -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.KeyStroke; -import javax.swing.ListSelectionModel; -import javax.swing.SwingUtilities; -import java.awt.Color; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.util.List; +import org.apache.commons.lang3.StringUtils; public class ShortcutPrefsCtrl @@ -30,10 +30,12 @@ public class ShortcutPrefsCtrl private static final String PREF_KEY_ACTION_NAME_COL_WIDTH = "ShortcutPrefsCtrl.column.actionName.width"; private static final String PREF_KEY_VALID_SHORTCUT_COL_WIDTH = "ShortcutPrefsCtrl.column.validShortcut.width"; private static final String PREF_KEY_DEFAULT_SHORTCUT_COL_WIDTH = "ShortcutPrefsCtrl.column.defaultShortcut.width"; + private static final String PREF_KEY_ACTION_DESCRIPTION_COL_WIDTH = "ShortcutPrefsCtrl.column.actionDescription.width"; public static final String COL_HEADER_ACTION_NAME = s_stringMgr.getString("ShortcutPrefsCtrl.column.actionName"); public static final String COL_HEADER_VALID_SHORTCUT = s_stringMgr.getString("ShortcutPrefsCtrl.column.validKeyStroke"); public static final String COL_HEADER_DEFAULT_SHORTCUT = s_stringMgr.getString("ShortcutPrefsCtrl.column.defaultKeyStroke"); + public static final String COL_HEADER_ACTION_DESCRIPTION = s_stringMgr.getString("ShortcutPrefsCtrl.column.description"); private ShortcutPrefsPanel _shortcutPrefsPanel = new ShortcutPrefsPanel(); private KeyStroke _currentKeyStroke; @@ -46,7 +48,7 @@ public void applyChanges() Props.putInt(PREF_KEY_ACTION_NAME_COL_WIDTH, _shortcutPrefsPanel.tblShortcuts.getColumnWidthForHeader(COL_HEADER_ACTION_NAME)); Props.putInt(PREF_KEY_VALID_SHORTCUT_COL_WIDTH, _shortcutPrefsPanel.tblShortcuts.getColumnWidthForHeader(COL_HEADER_VALID_SHORTCUT)); Props.putInt(PREF_KEY_DEFAULT_SHORTCUT_COL_WIDTH, _shortcutPrefsPanel.tblShortcuts.getColumnWidthForHeader(COL_HEADER_DEFAULT_SHORTCUT)); - + Props.putInt(PREF_KEY_ACTION_DESCRIPTION_COL_WIDTH, _shortcutPrefsPanel.tblShortcuts.getColumnWidthForHeader(COL_HEADER_ACTION_DESCRIPTION)); Main.getApplication().getShortcutManager().save(); @@ -60,17 +62,22 @@ public JPanel getPanel() _shortcutDataSet = new JavabeanArrayDataSet(Shortcut.class); _shortcutDataSet.setColHeader("actionName", COL_HEADER_ACTION_NAME); - _shortcutDataSet.setColPos("actionName", 1); + _shortcutDataSet.setColPos("actionName", 0); _shortcutDataSet.setAbsoluteWidht("actionName", Props.getInt(PREF_KEY_ACTION_NAME_COL_WIDTH, 200)); _shortcutDataSet.setColHeader("validKeyStroke", COL_HEADER_VALID_SHORTCUT); - _shortcutDataSet.setColPos("validKeyStroke", 2); + _shortcutDataSet.setColPos("validKeyStroke", 1); _shortcutDataSet.setAbsoluteWidht("validKeyStroke", Props.getInt(PREF_KEY_VALID_SHORTCUT_COL_WIDTH, 200)); _shortcutDataSet.setColHeader("defaultKeyStroke", COL_HEADER_DEFAULT_SHORTCUT); _shortcutDataSet.setColPos("defaultKeyStroke", 2); _shortcutDataSet.setAbsoluteWidht("defaultKeyStroke", Props.getInt(PREF_KEY_DEFAULT_SHORTCUT_COL_WIDTH, 200)); + _shortcutDataSet.setColHeader("actionDescription", COL_HEADER_ACTION_DESCRIPTION); + _shortcutDataSet.setColPos("actionDescription", 3); + _shortcutDataSet.setAbsoluteWidht("actionDescription", Props.getInt(PREF_KEY_ACTION_DESCRIPTION_COL_WIDTH, 200)); + + _shortcutDataSet.setIgnoreProperty("userKeyStroke"); displayShortcuts(); @@ -108,7 +115,7 @@ private Color onGetCellColor(int row, int column, boolean isSelected) { int modelColumn = _shortcutPrefsPanel.tblShortcuts.getTable().getColumnModel().getColumn(column).getModelIndex(); - if(2 != modelColumn) + if(1 != modelColumn) { return null; } @@ -156,15 +163,20 @@ private void onSelectedShortcutChanged() if(0 == _shortcutPrefsPanel.tblShortcuts.getSelectedModelRows().length) { - _shortcutPrefsPanel.txtSelectedShortcut.setText(s_stringMgr.getString("ShortcutPrefsPanel.txt.shortcut.formated", "", "", "", "")); return; - } - Shortcut selectedShortcut = getSelectedShortcut(); - _shortcutPrefsPanel.txtSelectedShortcut.setText(s_stringMgr.getString("ShortcutPrefsPanel.txt.shortcut.formated", selectedShortcut.getActionName(), selectedShortcut.getDefaultKeyStroke())); + _shortcutPrefsPanel.txtSelectedShortcut.setText(s_stringMgr.getString("ShortcutPrefsPanel.txt.shortcut.formated_extended", selectedShortcut.getActionName(), selectedShortcut.getDefaultKeyStroke(), getDescription(selectedShortcut))); + + _shortcutPrefsPanel.txtSelectedShortcut.setCaretPosition(0); + } + + private String getDescription(Shortcut selectedShortcut) + { + return StringUtils.isBlank(selectedShortcut.getActionDescription()) ? "" : selectedShortcut.getActionDescription(); } private void displayShortcuts() diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/SquirrelResources.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/SquirrelResources.java index dfc6c220fa..c759804f1f 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/SquirrelResources.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/SquirrelResources.java @@ -231,6 +231,9 @@ public interface IImageNames String BOOKMARK_SINGLE = "bookmark_single"; String PASSWORD_12X12 = "password12x12"; + + String RUN_TIMER = "runTimer"; + String RUN_TIMER_STOP = "runTimerStop"; } public SquirrelResources(String rsrcBundleBaseName) diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/multiSessionExec.png b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/multiSessionExec.png new file mode 100644 index 0000000000..31ddc1e8f4 Binary files /dev/null and b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/multiSessionExec.png differ diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimer.png b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimer.png new file mode 100644 index 0000000000..5f36b5520a Binary files /dev/null and b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimer.png differ diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimerStop.png b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimerStop.png new file mode 100644 index 0000000000..6ffaaf3ca9 Binary files /dev/null and b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/images/runTimerStop.png differ diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/squirrel.properties b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/squirrel.properties index ba57eeeb7b..8341057bc5 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/squirrel.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/resources/squirrel.properties @@ -224,6 +224,9 @@ bookmark_single.image=bookmark_single.png password12x12.image=password12x12.png +runTimer.image=runTimer.png +runTimerStop.image=runTimerStop.png + ######## # Configuration information for ObjectTreeInternalFrame. ######## @@ -582,6 +585,10 @@ action.net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction.i action.net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction.name=Run all SQLs action.net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction.tooltip=Run all SQLs in editor +action.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction.image=multiSessionExec.png +action.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction.name=Run SQL in all open Sessions +action.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction.tooltip=Run SQL in all open Sessions + action.net.sourceforge.squirrel_sql.client.session.action.DropSelectedTablesAction.image= action.net.sourceforge.squirrel_sql.client.session.action.DropSelectedTablesAction.name=Drop action.net.sourceforge.squirrel_sql.client.session.action.DropSelectedTablesAction.tooltip=Drop the selected table(s) @@ -1423,6 +1430,9 @@ menuitem.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlAction.mne menuitem.net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction.accelerator=alt shift ENTER menuitem.net.sourceforge.squirrel_sql.client.session.action.ExecuteAllSqlsAction.mnemonic= +menuitem.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction.accelerator=control alt shift ENTER +menuitem.net.sourceforge.squirrel_sql.client.session.action.ExecuteSqlInAllSessionsAction.mnemonic= + menuitem.net.sourceforge.squirrel_sql.client.session.action.file.FileOpenAction.accelerator= menuitem.net.sourceforge.squirrel_sql.client.session.action.file.FileOpenAction.mnemonic=O @@ -1471,7 +1481,7 @@ menuitem.net.sourceforge.squirrel_sql.client.session.action.PreviousSessionActio # Conflicts with 'close all result tabs'. Does this really need a short cut ? #menuitem.net.sourceforge.squirrel_sql.client.session.action.reconnect.ReconnectAction.accelerator=control shift T menuitem.net.sourceforge.squirrel_sql.client.session.action.reconnect.ReconnectAction.accelerator=control alt T -menuitem.net.sourceforge.squirrel_sql.client.session.action.reconnect.ReconnectAction.mnemonic=T +menuitem.net.sourceforge.squirrel_sql.client.session.action.reconnect.ReconnectAction.mnemonic=t menuitem.net.sourceforge.squirrel_sql.client.session.action.RedoAction.accelerator= control R menuitem.net.sourceforge.squirrel_sql.client.session.action.RedoAction.mnemonic=R diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/DataSetUpdateableTableModelImpl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/DataSetUpdateableTableModelImpl.java index fc2701f77c..d39e35a1c6 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/DataSetUpdateableTableModelImpl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/DataSetUpdateableTableModelImpl.java @@ -1,5 +1,14 @@ package net.sourceforge.squirrel_sql.client.session; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Vector; +import javax.swing.JOptionPane; + import net.sourceforge.squirrel_sql.client.session.mainpanel.sqltypecheck.ReadOnlySessionCheck; import net.sourceforge.squirrel_sql.client.session.properties.EditWhereCols; import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; @@ -22,15 +31,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.JOptionPane; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Vector; - public class DataSetUpdateableTableModelImpl implements IDataSetUpdateableTableModel { @@ -646,29 +646,37 @@ private List getWhereClause( // the user has restricted the set of columns to use. // If this name is NOT in the list, then skip it; otherwise we fall through // and use the column in the WHERE clause - if (colNames.get(colDefs[i].getColumnName()) == null) + if( colNames.get(colDefs[i].getColumnName()) == null ) + { continue; // go on to the next item + } } // for the column that is being changed, use the value // passed in by the caller (which may be either the // current value or the new replacement value) Object value = values[i]; - if (i == col) + if( i == col ) + { value = colValue; + } - // convert user representation of null into an actual null - if (value != null && value.toString().equals(StringUtilities.NULL_AS_STRING)) + if( value != null && value.toString().equals(StringUtilities.NULL_AS_STRING) ) + { + // convert user representation of null into an actual null value = null; + } // do different things depending on data type ISQLDatabaseMetaData md = _session.getMetaData(); IWhereClausePart clausePart = CellComponentFactory.getWhereClauseValue(colDefs[i], value, md); - if (clausePart.shouldBeUsed()) - // Now we know that the part should not we ignoredshould + if( null != clausePart && clausePart.shouldBeUsed() ) + { + // Now we know that the part should not be ignored clauseParts.add(clausePart); + } } return clauseParts; @@ -676,7 +684,7 @@ private List getWhereClause( } catch (Exception e) { - throw new RuntimeException(e); + throw Utilities.wrapRuntime(e); } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/ISQLPanelAPI.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/ISQLPanelAPI.java index fc090eb707..07ba1a597a 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/ISQLPanelAPI.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/ISQLPanelAPI.java @@ -19,6 +19,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.util.ArrayList; +import javax.swing.Action; +import javax.swing.JMenu; +import javax.swing.JMenuItem; import net.sourceforge.squirrel_sql.client.session.action.UndoRedoActionContext; import net.sourceforge.squirrel_sql.client.session.event.ISQLExecutionListener; import net.sourceforge.squirrel_sql.client.session.event.ISQLPanelListener; @@ -30,11 +34,6 @@ import net.sourceforge.squirrel_sql.client.session.mainpanel.changetrack.ChangeTracker; import net.sourceforge.squirrel_sql.client.session.mainpanel.sqltab.SQLPanelSplitter; -import javax.swing.Action; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import java.util.ArrayList; - /** * This interface defines the API through which plugins can work with the SQL * panel. @@ -198,8 +197,9 @@ public interface ISQLPanelAPI extends IFileEditorAPI void executeAllSQLs(); + void executeSQL(String sqlScriptToBeExecuted); - /** + /** * Close all the SQL result tabs. */ void closeAllSQLResultTabs(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/SQLPanelAPI.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/SQLPanelAPI.java index cf1b833e3e..67fed227fc 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/SQLPanelAPI.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/SQLPanelAPI.java @@ -21,6 +21,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Frame; +import java.util.ArrayList; +import javax.swing.Action; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JTextArea; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.action.ActionCollection; import net.sourceforge.squirrel_sql.client.gui.session.ToolsPopupController; @@ -61,13 +67,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.Action; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JTextArea; -import java.awt.Frame; -import java.util.ArrayList; - /** * This class is the API through which plugins can work with the SQL Panel. * @@ -520,6 +519,12 @@ public void executeAllSQLs() _panel.runAllSqlsExecuter(); } + @Override + public void executeSQL(String sqlToBeExecuted) + { + _panel.getSQLExecPanel().executeSQL(sqlToBeExecuted); + } + /** * Close all the SQL result tabs. */ diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/ExecuteSqlInAllSessionsAction.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/ExecuteSqlInAllSessionsAction.java new file mode 100644 index 0000000000..210e6ee5a6 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/ExecuteSqlInAllSessionsAction.java @@ -0,0 +1,45 @@ +package net.sourceforge.squirrel_sql.client.session.action; + +import java.awt.event.ActionEvent; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.client.action.SquirrelAction; +import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; +import net.sourceforge.squirrel_sql.client.session.ISession; + +public class ExecuteSqlInAllSessionsAction extends SquirrelAction implements ISQLPanelAction +{ + private ISQLPanelAPI _panel; + + public ExecuteSqlInAllSessionsAction() + { + super(Main.getApplication()); + setEnabled(false); + } + + @Override + public void actionPerformed(ActionEvent evt) + { + String sqlToBeExecuted = _panel.getSQLScriptToBeExecuted(); + + _panel.executeSQL(sqlToBeExecuted); + + for(ISession openSession : Main.getApplication().getSessionManager().getOpenSessions()) + { + if(openSession == _panel.getSession()) + { + continue; + } + + openSession.getSessionInternalFrame().getMainSQLPanelAPI().executeSQL(sqlToBeExecuted); + } + + System.out.println("ExecuteSqlInAllSessionsAction.actionPerformed END"); + } + + @Override + public void setSQLPanel(ISQLPanelAPI panel) + { + _panel = panel; + setEnabled(null != _panel && getApplication().getSquirrelPreferences().isAllowRunSqlInAllSessions()); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/syntax/rsyntax/SquirreLRSyntaxTextAreaUI.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/syntax/rsyntax/SquirreLRSyntaxTextAreaUI.java index 3fd23c93f2..5304b0fc11 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/syntax/rsyntax/SquirreLRSyntaxTextAreaUI.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/action/syntax/rsyntax/SquirreLRSyntaxTextAreaUI.java @@ -1,7 +1,19 @@ package net.sourceforge.squirrel_sql.client.session.action.syntax.rsyntax; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.Action; +import javax.swing.InputMap; +import javax.swing.KeyStroke; +import javax.swing.UIManager; +import javax.swing.plaf.InputMapUIResource; +import javax.swing.text.EditorKit; +import javax.swing.text.JTextComponent; +import javax.swing.text.TextAction; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.session.mainpanel.IUndoHandler; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; import net.sourceforge.squirrel_sql.fw.gui.stdtextpopup.TextActionUtil; import net.sourceforge.squirrel_sql.fw.gui.stdtextpopup.TextBeginAction; import net.sourceforge.squirrel_sql.fw.gui.stdtextpopup.TextBeginLineAction; @@ -17,18 +29,6 @@ import org.fife.ui.rtextarea.RTextArea; import org.fife.ui.rtextarea.RTextAreaEditorKit; -import javax.swing.Action; -import javax.swing.InputMap; -import javax.swing.KeyStroke; -import javax.swing.UIManager; -import javax.swing.plaf.InputMapUIResource; -import javax.swing.text.EditorKit; -import javax.swing.text.JTextComponent; -import javax.swing.text.TextAction; -import java.awt.event.ActionEvent; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; - public class SquirreLRSyntaxTextAreaUI extends RSyntaxTextAreaUI { private static final KeyStroke RS_KEY_STROKE_TO_UPPER_CASE = KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); @@ -192,26 +192,37 @@ public static Action getActionForName(SquirrelRSyntaxTextArea squirrelRSyntaxTex public static KeyStroke getToUpperCaseKeyStroke() { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaUpperSelectionCaseAction, SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_TO_UPPER_CASE)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaUpperSelectionCaseAction, + SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_TO_UPPER_CASE, + ShortCutDescriptionReader.of())); } public static KeyStroke getToLowerCaseKeyStroke() { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLowerSelectionCaseAction, SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_TO_LOWER_CASE)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLowerSelectionCaseAction, + SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_TO_LOWER_CASE, + ShortCutDescriptionReader.of())); } public static KeyStroke getLineUpKeyStroke() { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLineUpAction, SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_LINE_UP)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLineUpAction, + SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_LINE_UP, + ShortCutDescriptionReader.of())); + } public static KeyStroke getLineDownKeyStroke() { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLineDownAction, SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_LINE_DOWN)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.rtaLineDownAction, + SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_LINE_DOWN, + ShortCutDescriptionReader.of())); } public static KeyStroke getSelectWordStroke() { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.selectWordAction, SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_SELECT_WORD)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(RTextAreaEditorKit.selectWordAction, + SquirreLRSyntaxTextAreaUI.RS_KEY_STROKE_SELECT_WORD, + ShortCutDescriptionReader.of())); } @Override diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/IResultTab.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/IResultTab.java index 3f751d1ce3..046cc25d07 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/IResultTab.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/IResultTab.java @@ -18,6 +18,11 @@ */ package net.sourceforge.squirrel_sql.client.session.mainpanel; +import java.awt.Window; +import java.awt.event.ActionEvent; +import javax.swing.JComponent; +import javax.swing.JTabbedPane; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.ReRunChooserCtrl; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; import net.sourceforge.squirrel_sql.fw.datasetviewer.TableState; import net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.markduplicates.MarkDuplicatesChooserController; @@ -25,11 +30,6 @@ import net.sourceforge.squirrel_sql.fw.datasetviewer.tablefind.GlobalFindRemoteControl; import net.sourceforge.squirrel_sql.fw.id.IntegerIdentifier; -import javax.swing.JComponent; -import javax.swing.JTabbedPane; -import java.awt.Window; -import java.awt.event.ActionEvent; - public interface IResultTab { /** @@ -51,6 +51,8 @@ public interface IResultTab void disposeTab(); void addResultTabCloseListener(ResultTabCloseListener l); + void removeResultTabCloseListener(ResultTabCloseListener l); + void returnToTabbedPane(); @@ -70,8 +72,10 @@ public interface IResultTab void reRunSQL(); + void reRunSqlWithTimerRepeats(int repeatSeconds); TableState getResultSortableTableState(); + void applyResultSortableTableState(TableState tableState); void toggleShowFindPanel(); @@ -106,4 +110,21 @@ public interface IResultTab void setSQLResultTabSelected(); GlobalFindRemoteControl getDataSetViewerFindRemoteControlOfSQLQueryResultTabOrNull(); + + /** + * Is called before the {@link ResultTabCloseListener] of the previous {@link ResultTab} is fired. + */ + void aboutToBeReplacedBy(ResultTab tab); + + /** + * Is called before the {@link ResultTabCloseListener] of the previous {@link ResultTab} is fired. + */ + void aboutToBeReplacedBy(ResultTab newResultTab, ReRunChooserCtrl reRunChooserCtrl); + + void prepareBeingMovedToResultFrame(); + + /** + * @return The previous {@link ResultTabListener} + */ + ResultTabListener replaceResultTabListener(ResultTabListener resultTabListener); } \ No newline at end of file diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/RerunWithTimerRepeatsManager.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/RerunWithTimerRepeatsManager.java new file mode 100644 index 0000000000..afdfaedb97 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/RerunWithTimerRepeatsManager.java @@ -0,0 +1,77 @@ +package net.sourceforge.squirrel_sql.client.session.mainpanel; + +import java.util.List; +import javax.swing.Timer; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.ReRunChooserCtrl; + +public class RerunWithTimerRepeatsManager +{ + private Timer _timer; + private ResultTabCloseListener _resultTabCloseListener = () -> disposeTimer(); + + private record ResultTabData(ResultTab resultTab, ReRunChooserCtrl reRunChooserCtrl){} + + private boolean _newResultTabData; + private ResultTabData _currentResultTabData; + + void startTimerRepeats(int repeatSeconds, ResultTab resultTab, ReRunChooserCtrl reRunChooserCtrl) + { + initNewResultTabData(resultTab, reRunChooserCtrl); + + disposeTimer(); + _timer = new Timer(1000 * repeatSeconds, e -> onTimerTriggered()); + _timer.setRepeats(true); + _timer.start(); + onTimerTriggered(); + } + + private void onTimerTriggered() + { + // If the ResultTabData aren't new the rerun previously triggered is still running. + if(_newResultTabData) + { + _newResultTabData = false; + _currentResultTabData.resultTab.reRunSQLIntern(); + } + } + + void aboutToBeReplacedBy(ResultTab newResultTab, ReRunChooserCtrl newReRunChooserCtrl) + { + if(null == _timer || false == _timer.isRunning()) + { + return; + } + + initNewResultTabData(newResultTab, newReRunChooserCtrl); + } + + public void disposeTimer() + { + if(null == _timer) + { + return; + } + _timer.stop(); + List.of(_timer.getActionListeners()).forEach(l -> _timer.removeActionListener(l)); + } + + + private void initNewResultTabData(ResultTab resultTab, ReRunChooserCtrl reRunChooserCtrl) + { + if(null != _currentResultTabData) + { + _currentResultTabData.reRunChooserCtrl.cleanUp(); + + // Note: When this method is called by aboutToBeReplacedBy() this method will be called before the ResultTabCloseListener is fired. + // The following command makes sure that disposeTimer() isn't called when the ResultTab is replaced + _currentResultTabData.resultTab.removeResultTabCloseListener(_resultTabCloseListener); + } + + _currentResultTabData = new ResultTabData(resultTab, reRunChooserCtrl); + _currentResultTabData.reRunChooserCtrl.setResultTab(resultTab); + _currentResultTabData.reRunChooserCtrl.switchToStopButton(e -> disposeTimer()); + _currentResultTabData.resultTab.addResultTabCloseListener(_resultTabCloseListener); + _newResultTabData = true; + } + +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultFrame.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultFrame.java index 242d17a478..08161f764b 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultFrame.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultFrame.java @@ -20,6 +20,20 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.util.ArrayList; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget; @@ -29,20 +43,19 @@ import net.sourceforge.squirrel_sql.client.session.SQLExecutionInfo; import net.sourceforge.squirrel_sql.client.session.action.ReturnResultTabAction; import net.sourceforge.squirrel_sql.client.session.event.ISQLExecutionListener; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.ReRunChooserCtrl; import net.sourceforge.squirrel_sql.client.session.mainpanel.rowcolandsum.RowColAndSumController; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetUpdateableTableModel; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetDataSet; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetMetaDataDataSet; +import net.sourceforge.squirrel_sql.fw.datasetviewer.TableState; import net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.markduplicates.MarkDuplicatesChooserController; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.*; -import java.awt.*; -import java.util.ArrayList; - /** * JASON: Rename to ResultInternalFrame * Torn off frame that contains SQL results. @@ -65,33 +78,21 @@ public class ResultFrame extends SessionDialogWidget private TabButton _btnFindColumn; private MarkDuplicatesChooserController _markDuplicatesChooserController; private JCheckBox _chkOnTop; - private TabButton _btnReRun; private JPanel _centerPanel; private RowColAndSumController _rowColAndSumController = new RowColAndSumController(); + private final ResultTabListener _originalResultTabListener; + + private ReRunChooserCtrl _reRunChooserCtrl; - /** - * Ctor. - * - * - * - * - * - * @param session Current session. - * @param resultTab SQL results tab. - * - * @param resultTabFactory - * @param resultFrameListener - *@param isOnRerun @throws IllegalArgumentException - * If a null ISession or - * ResultTab passed. - */ public ResultFrame(final ISession session, IResultTab resultTab, ResultTabFactory resultTabFactory, ResultFrameListener resultFrameListener, boolean checkStayOnTop, boolean isOnRerun) { super(getFrameTitle(session, resultTab), true, true, true, true, session); _session = session; _resultTab = resultTab; + _originalResultTabListener = _resultTab.replaceResultTabListener((sql, resultTabToReplace) -> onRerun()); _resultTabFactory = resultTabFactory; _resultFrameListener = resultFrameListener; + _reRunChooserCtrl = new ReRunChooserCtrl(_resultTab); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); @@ -107,8 +108,6 @@ public ResultFrame(final ISession session, IResultTab resultTab, ResultTabFactor _chkOnTop.addActionListener(e -> onStayOnTopChanged()); - _btnReRun.addActionListener(e -> onRerun()); - _btnToggleFind.addActionListener(e -> onFind()); _btnFindColumn.addActionListener(e -> onFindColumn()); @@ -132,7 +131,7 @@ private void onFindColumn() private void onRerun() { _btnReturnToTab.setEnabled(false); - _btnReRun.setEnabled(false); + //_reRunChooserCtrl.setEnabled(false); _centerPanel.removeAll(); new SQLExecutionHandler(_resultTab, _session, _resultTab.getSqlString(), createSQLExecutionHandlerListener(), new ISQLExecutionListener[0]); } @@ -177,7 +176,7 @@ public void run() ErrorPanel errorPanel = _resultTabFactory.createErrorPanel(sqlExecErrorMsgs, lastExecutedStatement); errorPanel.hideCloseButton(); _centerPanel.add(errorPanel); - _btnReRun.setEnabled(true); + //_reRunChooserCtrl.setEnabled(true); } }); } @@ -189,7 +188,7 @@ private void onSetCancelPanel(final CancelPanelCtrl cancelPanelCtrl) public void run() { _centerPanel.removeAll(); - _centerPanel.add(cancelPanelCtrl.getPanel(), BorderLayout.CENTER); + _centerPanel.add(cancelPanelCtrl.getPanel()); } }); } @@ -203,31 +202,50 @@ private void onRemoveCancelPanel(final CancelPanelCtrl cancelPanelCtrl, IResultT private void onAddResultsTab(final SQLExecutionInfo info, final ResultSetDataSet rsds, final ResultSetMetaDataDataSet rsmdds, final IDataSetUpdateableTableModel creator, IResultTab resultTabToReplace) { // We start a new frame here because reusing the current one for the new result led to repaint problems - SwingUtilities.invokeLater(() -> showRerunResultsInNewFrame(info, creator, rsds, rsmdds)); + SwingUtilities.invokeLater(() -> showRerunResult(info, creator, rsds, rsmdds)); } - private void showRerunResultsInNewFrame(SQLExecutionInfo info, IDataSetUpdateableTableModel creator, ResultSetDataSet rsds, ResultSetMetaDataDataSet rsmdds) + private void showRerunResult(SQLExecutionInfo info, IDataSetUpdateableTableModel creator, ResultSetDataSet rsds, ResultSetMetaDataDataSet rsmdds) { try { _centerPanel.removeAll(); - ResultTab tab = _resultTabFactory.createResultTab(info, creator, rsds, rsmdds); - ResultFrame frame = new ResultFrame(_session, tab, _resultTabFactory, _resultFrameListener, _chkOnTop.isSelected(), true); - showFrame(frame, true); - setVisible(false); - dispose(); - _resultFrameListener.frameReplaced(ResultFrame.this, frame); + TableState tableState = null; + + if(null != _resultTab) + { + tableState = _resultTab.getResultSortableTableState(); + } + + ResultTab newResultTab = _resultTabFactory.createResultTab(info, creator, rsds, rsmdds); + _resultTab.aboutToBeReplacedBy(newResultTab, _reRunChooserCtrl); + + _resultTab = newResultTab; + _resultTab.replaceResultTabListener((sql, resultTabToReplace) -> onRerun()); + + JTabbedPane tabbedPaneOfResultTabs = _resultTab.getTabbedPaneOfResultTabs(); + GUIUtils.unconventionallyAddToParentWithRepaint(_centerPanel, tabbedPaneOfResultTabs); + _markDuplicatesChooserController.init(_resultTab); + _reRunChooserCtrl.setResultTab((ResultTab) _resultTab); + + if(null != tableState) + { + _resultTab.applyResultSortableTableState(tableState); + } + + _btnReturnToTab.setEnabled(true); + //_reRunChooserCtrl.setEnabled(true); } catch (Throwable t) { - _session.showErrorMessage(t); + Main.getApplication().getMessageHandler().showErrorMessage(t); } } private void showFrame(ResultFrame frame, boolean isOnRerun) { - _session.getApplication().getMainFrame().addWidget(frame); + Main.getApplication().getMainFrame().addWidget(frame); if (isOnRerun) { frame.setBounds(getBounds()); @@ -265,7 +283,6 @@ private JPanel createLeftButtonsPanel(ISession session, IApplication app, boolea gbc = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,5,0,5), 0,0); pnlButtons.add(_btnReturnToTab, gbc); - // i18n[resultFrame.stayOnTop=Stay on top] _chkOnTop = new JCheckBox(s_stringMgr.getString("resultFrame.stayOnTop")); gbc = new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,5,0,5), 0,0); pnlButtons.add(_chkOnTop, gbc); @@ -293,44 +310,29 @@ private JPanel createRightUpperPanel() public void updateRightUpperPanelLayout(JPanel panel) { - //_panel.invalidate(); - //SwingUtilities.invokeLater( () -> {_panel.revalidate(); _panel.getParent().revalidate(); _panel.getParent().getParent().revalidate();}); - //SwingUtilities.invokeLater( () -> _panel.repaint()); panel.revalidate(); - //panel.getParent().revalidate(); if (null != panel.getParent()) { panel.getParent().revalidate(); } - - //_panel.setBorder(BorderFactory.createLineBorder(Color.RED)); } private JPanel createRightButtonsPanel() { JPanel ret = new JPanel(new GridLayout(1,4)); - - ImageIcon iconReRun = Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.RERUN); - _btnReRun = new TabButton(iconReRun); - _btnReRun.setToolTipText(s_stringMgr.getString("ResultFrame.rerun")); - //gbc = new GridBagConstraints(3,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); - ret.add(_btnReRun); - + ret.add(_reRunChooserCtrl.getComponent()); _markDuplicatesChooserController = new MarkDuplicatesChooserController(_resultTab); _markDuplicatesChooserController.copyStateFrom(_resultTab.getMarkDuplicatesChooserController()); - //gbc = new GridBagConstraints(4,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); ret.add(_markDuplicatesChooserController.getComponent()); ImageIcon iconFindColumn = Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.FIND_COLUMN); _btnFindColumn = new TabButton(iconFindColumn); - //gbc = new GridBagConstraints(5,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); ret.add(_btnFindColumn); ImageIcon iconFind = Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.FIND); _btnToggleFind = new TabButton(iconFind); - //gbc = new GridBagConstraints(6,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,5), 0,0); ret.add(_btnToggleFind); return ret; @@ -371,6 +373,7 @@ public void returnToTabbedPane() { s_log.debug("ResultFrame.returnToTabbedPane()"); getContentPane().remove(_resultTab.getTabbedPaneOfResultTabs()); + _resultTab.replaceResultTabListener(_originalResultTabListener); _resultTab.returnToTabbedPane(); _resultTab = null; dispose(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTab.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTab.java index 1ab21186aa..9cccf86371 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTab.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTab.java @@ -23,6 +23,21 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory; import net.sourceforge.squirrel_sql.client.session.DataModelImplementationDetails; @@ -35,7 +50,7 @@ import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.CreateResultTabFrameAction; import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.FindInResultAction; import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.FindResultColumnAction; -import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.RerunCurrentSQLResultTabAction; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.ReRunChooserCtrl; import net.sourceforge.squirrel_sql.client.session.mainpanel.rowcolandsum.RowColAndSumController; import net.sourceforge.squirrel_sql.client.session.properties.SessionProperties; import net.sourceforge.squirrel_sql.fw.datasetviewer.BaseDataSetViewerDestination; @@ -65,22 +80,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.JComponent; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; -import javax.swing.SwingUtilities; -import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.List; - public class ResultTab extends JPanel implements IHasIdentifier, IResultTab { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ResultTab.class); @@ -139,6 +138,9 @@ public class ResultTab extends JPanel implements IHasIdentifier, IResultTab private List _resultTabCloseListenerList = new ArrayList<>(); + private ReRunChooserCtrl _reRunChooserCtrl; + private RerunWithTimerRepeatsManager _rerunWithTimerRepeatsManager = new RerunWithTimerRepeatsManager(); + /** * Ctor. * @@ -158,6 +160,7 @@ public ResultTab(ISession session, SQLResultExecuterPanelFacade sqlResultExecute { _resultTabListener = resultTabListener; _session = session; + _reRunChooserCtrl = new ReRunChooserCtrl(this); _queryInfoPanel = new QueryInfoPanel(_session); _sqlResultExecuterPanelFacade = sqlResultExecuterPanelFacade; @@ -381,6 +384,12 @@ public void addResultTabCloseListener(ResultTabCloseListener l) _resultTabCloseListenerList.add(l); } + @Override + public void removeResultTabCloseListener(ResultTabCloseListener l) + { + _resultTabCloseListenerList.remove(l); + } + public void disposeTab() { if (_metaDataDataSetViewerFindHandler != null) @@ -438,10 +447,22 @@ public JComponent getCompleteResultTab() */ public void reRunSQL() { - _resultTabListener.rerunSQL(_exInfo.getQueryHolder().getOriginalQuery(), ResultTab.this); + reRunSQLIntern(); } - - /** + + @Override + public void reRunSqlWithTimerRepeats(int repeatSeconds) + { + _rerunWithTimerRepeatsManager.startTimerRepeats(repeatSeconds, this, _reRunChooserCtrl); + } + + void reRunSQLIntern() + { + _resultTabListener.rerunSQL(_exInfo.getQueryHolder().getOriginalQuery(), this); + } + + + /** * Session properties have changed so update GUI if required. * * @param propertyName Name of property that has changed. @@ -600,7 +621,7 @@ private JPanel createTopRightButtonsPanel() ret.add(_readMoreResultsHandler.getLoadingLabel(),gbc); gbc = new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2,10,0,0), 0,0); - ret.add(new TabButton(getRerunCurrentSQLResultTabAction()), gbc); + ret.add(_reRunChooserCtrl.getComponent(), gbc); _showCellDetailCtrl = new ShowCellDetailCtrl(this); gbc = new GridBagConstraints(2,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2,2,0,0), 0,0); @@ -632,16 +653,6 @@ private JPanel createTopRightButtonsPanel() return ret; } - private RerunCurrentSQLResultTabAction getRerunCurrentSQLResultTabAction() - { - RerunCurrentSQLResultTabAction rtn = new RerunCurrentSQLResultTabAction(this); - - rtn.setSQLPanel( _session.getSQLPanelAPIOfActiveSessionWindow() ); - - return rtn; - } - - @Override public void toggleShowFindPanel() { @@ -667,8 +678,6 @@ public GlobalFindRemoteControl getDataSetViewerFindRemoteControlOfSQLQueryResult return _resultDataSetViewerFindHandler.getDataSetViewerFindRemoteControlOrNull(); } - - @Override public void findColumn() { @@ -722,6 +731,7 @@ public TableState getResultSortableTableState() return _resultDataSetViewerFindHandler.getDataSetViewer().getResultSortableTableState(); } + @Override public void applyResultSortableTableState(TableState sortableTableState) { _resultDataSetViewerFindHandler.getDataSetViewer().applyResultSortableTableState(sortableTableState); @@ -812,4 +822,40 @@ protected void finalize() } } + + /** + * Is called before the {@link ResultTabCloseListener] of the previous {@link ResultTab} is fired. + */ + @Override + public void aboutToBeReplacedBy(ResultTab newResultTab) + { + aboutToBeReplacedBy(newResultTab, newResultTab._reRunChooserCtrl); + } + + /** + * Is called before the {@link ResultTabCloseListener] of the previous {@link ResultTab} is fired. + */ + @Override + public void aboutToBeReplacedBy(ResultTab newResultTab, ReRunChooserCtrl reRunChooserCtrl) + { + newResultTab._rerunWithTimerRepeatsManager = _rerunWithTimerRepeatsManager; + _rerunWithTimerRepeatsManager.aboutToBeReplacedBy(newResultTab, reRunChooserCtrl); + } + + @Override + public void prepareBeingMovedToResultFrame() + { + _rerunWithTimerRepeatsManager.disposeTimer(); + } + + /** + * @return The previous {@link ResultTabListener} + */ + @Override + public ResultTabListener replaceResultTabListener(ResultTabListener resultTabListener) + { + ResultTabListener previous = _resultTabListener; + _resultTabListener = resultTabListener; + return previous; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabFactory.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabFactory.java index 95b1ef62fc..a8bf1861f5 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabFactory.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabFactory.java @@ -1,5 +1,6 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel; +import java.util.ArrayList; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.SQLExecutionInfo; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; @@ -8,8 +9,6 @@ import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetMetaDataDataSet; import net.sourceforge.squirrel_sql.fw.id.IntegerIdentifierFactory; -import java.util.ArrayList; - public class ResultTabFactory { private IntegerIdentifierFactory _idFactory = new IntegerIdentifierFactory(); @@ -24,8 +23,7 @@ public ResultTabFactory(ISession session, SQLResultExecuterPanelFacade sqlResult public ResultTab createResultTab(SQLExecutionInfo exInfo, IDataSetUpdateableTableModel dataSetUpdateableTableModel, ResultSetDataSet rsds, ResultSetMetaDataDataSet mdds) throws DataSetException { - final ResultTabListener resultTabListener = (sql, resultTab) -> _sqlResultExecuterPanelFacade.rerunSQL(sql, resultTab); - + final ResultTabListener resultTabListener = (sql, resultTabToReplace) -> _sqlResultExecuterPanelFacade.rerunSQL(sql, resultTabToReplace); ResultTab tab = new ResultTab(_session, _sqlResultExecuterPanelFacade, _idFactory.createIdentifier(), exInfo, dataSetUpdateableTableModel, resultTabListener); tab.showResults(rsds, mdds); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabListener.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabListener.java index f32d5f05e1..330bb08c2e 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabListener.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/ResultTabListener.java @@ -2,5 +2,5 @@ public interface ResultTabListener { - void rerunSQL(String sql, IResultTab resultTab); + void rerunSQL(String sql, IResultTab resultTabToReplace); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLExecutionHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLExecutionHandler.java index 30acdc86c0..fb4ac0c1cf 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLExecutionHandler.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLExecutionHandler.java @@ -1,5 +1,10 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel; +import java.sql.SQLWarning; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; + import net.sourceforge.squirrel_sql.client.preferences.SquirrelPreferences; import net.sourceforge.squirrel_sql.client.session.ISQLExecuterHandler; import net.sourceforge.squirrel_sql.client.session.ISession; @@ -25,11 +30,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.sql.SQLWarning; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.Arrays; - /** * This class is the handler for the execution of sql against the SQLExecuterPanel */ @@ -396,7 +396,7 @@ public void sqlResultSetAvailable(ResultSetWrapper rs, SQLExecutionInfo info, ID // rsds.setContentsTabResultSet() reads the result set. So results processing on the DB is over // and this time is measured. None is interested in the time that it takes us to render Swing tables ... - info.resultsProcessingComplete(_rsds.setSqlExecutionTabResultSet(rs, null, dialectType)); + info.resultsProcessingComplete(_rsds.readDataFromJdbcResultSetForSqlExecution(rs, null, dialectType)); _executionHandlerListener.addResultsTab(info, _rsds, rsmdds, model, _resultTabToReplace); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLPanel.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLPanel.java index 771847dc6c..3b51f1ec55 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLPanel.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLPanel.java @@ -23,6 +23,28 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import javax.swing.Action; +import javax.swing.Box; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory; @@ -49,29 +71,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringUtilities; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; - -import javax.swing.Action; -import javax.swing.Box; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; /** * This is the panel where SQL scripts can be entered and executed. * @@ -397,6 +396,8 @@ public void sessionWorksheetOrTabClosing() _resultTabMatchingCurrentSqlHandler.close(); _sqlPanelListenerManager.fireSQLPanelParentClosing(); + + _panelAPI.closeAllSQLResultTabs(); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecuterPanelFacade.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecuterPanelFacade.java index d239eb1b62..759b19c03c 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecuterPanelFacade.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecuterPanelFacade.java @@ -8,7 +8,7 @@ public interface SQLResultExecuterPanelFacade void createSQLResultFrame(IResultTab resultTab); - void rerunSQL(String sql, IResultTab resultTab); + void rerunSQL(String sql, IResultTab resultTabToReplace); void removeErrorPanel(ErrorPanel errorPanel); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecutorPanel.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecutorPanel.java index ddc1bfe2e6..bafa4db851 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecutorPanel.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/SQLResultExecutorPanel.java @@ -18,6 +18,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory; import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanel; @@ -35,6 +51,7 @@ import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabheader.ResultTabAdder; import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabheader.ResultTabComponent; import net.sourceforge.squirrel_sql.client.session.properties.SessionProperties; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetUpdateableTableModel; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetDataSet; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetMetaDataDataSet; @@ -49,23 +66,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.Action; -import javax.swing.Icon; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JTabbedPane; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import java.awt.BorderLayout; -import java.awt.Component; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - /** * This is the panel where SQL scripts are executed and results presented. * @@ -144,9 +144,9 @@ public void createSQLResultFrame(IResultTab resultTab) } @Override - public void rerunSQL(String sql, IResultTab resultTab) + public void rerunSQL(String sql, IResultTab resultTabToReplace) { - SQLResultExecutorPanel.this.rerunSQL(sql, resultTab); + SQLResultExecutorPanel.this.rerunSQL(sql, resultTabToReplace); } @Override @@ -783,16 +783,11 @@ else if (null != resultTabToReplace) } else { + // We need to make sure this is fired before the ResultTabCloseListener of resultTabToReplace is fired. + resultTabToReplace.aboutToBeReplacedBy(tab); _resultTabClosing.closeTabAt(indexToReplace); _tabAdder.insert(getTabHeaderTitle(tab), tabIcon, tab, tab.getViewableSqlString(), indexToReplace); - - //final JLabel tabComponent = new JLabel(getTabHeaderTitle(tab)); - //_tabbedExecutionsPanel.setTabComponentAt(_tabbedExecutionsPanel.indexOfComponent(tab), tabComponent); - //if(null != tabIcon) - //{ - // _tabAdder.setIconAt(indexToReplace, tabIcon); - //} } } @@ -939,7 +934,7 @@ private void initAccelerator(Class actionClass, JMenuItem mnuI Action action = _session.getApplication().getActionCollection().get(actionClass); String accel = (String) action.getValue(Resources.ACCELERATOR_STRING); - Main.getApplication().getShortcutManager().setAccelerator(mnuItem, KeyStroke.getKeyStroke(accel), action); + Main.getApplication().getShortcutManager().setAccelerator(mnuItem, KeyStroke.getKeyStroke(accel), action, ShortCutDescriptionReader.of(action, mnuItem)); } public JTabbedPane getTabbedPane() diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TabButton.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TabButton.java index 39660aa1ca..d6a3d72ee7 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TabButton.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TabButton.java @@ -1,18 +1,19 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.JButton; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; -import javax.swing.*; - public class TabButton extends JButton { - TabButton(Action action) + public TabButton(Action action) { super(action); GUIUtils.styleAsTabButton(this); } - TabButton() + public TabButton() { this((Action) null); } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TimerHolder.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TimerHolder.java index 152661db4b..d94135c0d9 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TimerHolder.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/TimerHolder.java @@ -1,12 +1,11 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel; +import javax.swing.JCheckBox; +import javax.swing.JTextField; +import javax.swing.Timer; import net.sourceforge.squirrel_sql.client.session.mainpanel.notificationsound.FinishedNotificationSoundHandler; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetDataSet; -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - /** * This timer treatment seems to give better Session GCing behaviour. @@ -32,14 +31,7 @@ public TimerHolder(JTextField txtExecTimeCounter, JTextField txtNumberOfRowsRead _txtExecTimeCounter = txtExecTimeCounter; _txtNumberOfRowsRead = txtNumberOfRowsRead; - _timer = new Timer(300, new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - onUpdateExecutionTime(); - } - }); + _timer = new Timer(300, e -> onUpdateExecutionTime()); _timer.setRepeats(true); _timer.start(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/BasePreparedStatementTab.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/BasePreparedStatementTab.java index 2109744be5..468c569c3a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/BasePreparedStatementTab.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/BasePreparedStatementTab.java @@ -19,6 +19,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Component; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + import net.sourceforge.squirrel_sql.client.session.DataModelImplementationDetails; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.properties.SessionProperties; @@ -32,13 +39,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.awt.Component; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; - public abstract class BasePreparedStatementTab extends BaseObjectTab { /** Title to display for tab. */ @@ -168,7 +168,7 @@ protected void refreshComponent() throws DataSetException protected IDataSet createDataSetFromResultSet(ResultSet rs) throws DataSetException { final ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, getDialectType()); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, getDialectType()); if (!_firstRowOnly) { return rsds; diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/ContentsTab.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/ContentsTab.java index d690a46603..429a27f5c0 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/ContentsTab.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/ContentsTab.java @@ -24,6 +24,7 @@ import java.sql.SQLException; import java.sql.Statement; import javax.swing.JTable; + import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.session.SessionPanel; import net.sourceforge.squirrel_sql.client.session.DataSetUpdateableTableModelImpl; @@ -287,7 +288,7 @@ protected IDataSet createDataSet() throws DataSetException // distinguish this table from other tables in the DB. // We also include the URL used to connect to the DB so that // the same table/DB on different machines is treated differently. - rsds.setContentsTabResultSet(rs, _dataSetUpdateableTableModel.getFullTableName(), DialectFactory.getDialectType(md)); + rsds.readDataFromJdbcResultSetForObjectTreeContentTabs(rs, _dataSetUpdateableTableModel.getFullTableName(), DialectFactory.getDialectType(md)); SQLUtilities.closeResultSet(rs); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/RowCountTab.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/RowCountTab.java index de1330a5ff..a9fc8e38ce 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/RowCountTab.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/objecttree/tabs/table/RowCountTab.java @@ -77,7 +77,7 @@ protected IDataSet createDataSet() throws DataSetException try { final ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, getDialectType()); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, getDialectType()); return rsds; } finally diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/CreateResultTabFrameAction.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/CreateResultTabFrameAction.java index 02a7a14714..08529d19d1 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/CreateResultTabFrameAction.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/CreateResultTabFrameAction.java @@ -1,13 +1,12 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; +import java.awt.event.ActionEvent; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.action.SquirrelAction; import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.action.ISQLPanelAction; import net.sourceforge.squirrel_sql.client.session.mainpanel.ResultTab; -import java.awt.event.ActionEvent; - public class CreateResultTabFrameAction extends SquirrelAction implements ISQLPanelAction { private ResultTabProvider _resultTabProvider; @@ -36,6 +35,7 @@ public void actionPerformed(ActionEvent evt) { if(_resultTabProvider.hasResultTab()) { + _resultTabProvider.getResultTab().prepareBeingMovedToResultFrame(); _resultTabProvider.getResultTab().getSQLResultExecuterPanelFacade().createSQLResultFrame(_resultTabProvider.getResultTab()); } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/I18NStrings.properties new file mode 100644 index 0000000000..0c87740bc5 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/I18NStrings.properties @@ -0,0 +1,9 @@ + +ReRunChooserCtrl.rerun.timered=Rerun the current tab''s SQL Query with timer ({0}) + +ReRunChooserCtrl.rerun.timered.stop=Stop rerunning the current tab''s SQL Query + +RerunWithTimerRepeatsDlg.title=Rerun interval +RerunWithTimerRepeatsDlg.enter.repeat.interval.in.seconds=Enter rerun interval in seconds (0 means don't repeat) +RerunWithTimerRepeatsDlg.ok=Ok +RerunWithTimerRepeatsDlg.cancel=Cancel \ No newline at end of file diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/MarkDuplicatesToggleAction.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/MarkDuplicatesToggleAction.java index cf2efbfba3..ec13fea5f5 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/MarkDuplicatesToggleAction.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/MarkDuplicatesToggleAction.java @@ -1,13 +1,12 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; +import java.awt.event.ActionEvent; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.action.SquirrelAction; import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.action.ISQLPanelAction; import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; -import java.awt.event.ActionEvent; - public class MarkDuplicatesToggleAction extends SquirrelAction implements ISQLPanelAction { private ResultTabProvider _resultTabProvider; @@ -31,6 +30,18 @@ public MarkDuplicatesToggleAction() public void setSQLPanel(ISQLPanelAPI panel) { _resultTabProvider.setSQLPanelAPI(panel); + doEnable(); + } + + public void setResultTab(IResultTab resultTab) + { + _resultTabProvider.setResultTab(resultTab); + doEnable(); + } + + private void doEnable() + { + setEnabled(_resultTabProvider.hasResultTab()); } public void actionPerformed(ActionEvent evt) @@ -39,6 +50,5 @@ public void actionPerformed(ActionEvent evt) { _resultTabProvider.getResultTab().markDuplicates(evt); } - } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ReRunChooserCtrl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ReRunChooserCtrl.java new file mode 100644 index 0000000000..7d2318934a --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ReRunChooserCtrl.java @@ -0,0 +1,106 @@ +package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; +import java.util.stream.Stream; +import javax.swing.Action; +import javax.swing.JComponent; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; +import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; +import net.sourceforge.squirrel_sql.client.session.mainpanel.ResultTab; +import net.sourceforge.squirrel_sql.client.session.mainpanel.TabButton; +import net.sourceforge.squirrel_sql.client.shortcut.ShortcutUtil; +import net.sourceforge.squirrel_sql.fw.gui.buttonchooser.ButtonChooser; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; + +public class ReRunChooserCtrl +{ + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ReRunChooserCtrl.class); + + private final RerunCurrentSQLResultTabAction _actionDefault; + private final RerunCurrentSQLResultTabAction _actionTimerRepeats; + private final TabButton _btnReRunDefault; + private final TabButton _btnReRunTimerRepeats; + private final TabButton _btnReRunTimerRepeatsStop; + private ButtonChooser _btnChooser; + + + public ReRunChooserCtrl(IResultTab resultTab) + { + _btnChooser = new ButtonChooser(); + _actionDefault = createDefaultReRunAction(resultTab); + _actionTimerRepeats = createTimerRepeatsReRunAction(resultTab); + + _btnReRunDefault = new TabButton(_actionDefault); + _btnReRunTimerRepeats = new TabButton(_actionTimerRepeats); + _btnReRunTimerRepeatsStop = new TabButton(Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.RUN_TIMER_STOP)); + + _btnChooser.addButton(_btnReRunDefault); + _btnChooser.addButton(_btnReRunTimerRepeats); + + if(RerunResultTabMode.getCurrentMode() == RerunResultTabMode.DEFAULT) + { + _btnChooser.setSelectedButton(_btnReRunDefault); + } + else + { + _btnChooser.setSelectedButton(_btnReRunTimerRepeats); + } + + _btnChooser.setButtonSelectedListener( + (btnNew, btnOld) -> RerunResultTabMode.setCurrentMode(btnNew == _btnReRunDefault ? RerunResultTabMode.DEFAULT : RerunResultTabMode.TIMER_REPEATS)); + } + + private static RerunCurrentSQLResultTabAction createTimerRepeatsReRunAction(IResultTab resultTab) + { + RerunCurrentSQLResultTabAction ret = createDefaultReRunAction(resultTab); + + ret.putValue(Action.SMALL_ICON, Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.RUN_TIMER)); + String description = s_stringMgr.getString("ReRunChooserCtrl.rerun.timered", ShortcutUtil.getKeystrokeString(ret.getKeyStroke())); + ret.putValue(Action.SHORT_DESCRIPTION, description); + ret.putValue(Action.LONG_DESCRIPTION, description); + + return ret; + } + + private static RerunCurrentSQLResultTabAction createDefaultReRunAction(IResultTab resultTab) + { + RerunCurrentSQLResultTabAction ret = new RerunCurrentSQLResultTabAction(); + ret.setResultTab((ResultTab) resultTab); + return ret; + } + + public JComponent getComponent() + { + return _btnChooser.getComponent(); + } + + public void setResultTab(ResultTab resultTab) + { + _actionDefault.setResultTab(resultTab); + _actionTimerRepeats.setResultTab(resultTab); + } + + public void switchToStopButton(ActionListener stopListener) + { + cleanUp(); + _btnReRunTimerRepeatsStop.addActionListener(e -> onStopRepeats(stopListener, e)); + _btnReRunTimerRepeatsStop.setToolTipText(s_stringMgr.getString("ReRunChooserCtrl.rerun.timered.stop")); + _btnChooser.replaceButtonsBy(List.of(_btnReRunTimerRepeatsStop)); + } + + private void onStopRepeats(ActionListener stopListener, ActionEvent e) + { + stopListener.actionPerformed(e); + cleanUp(); + _btnChooser.replaceButtonsBy(List.of(_btnReRunDefault, _btnReRunTimerRepeats)); + } + + public void cleanUp() + { + Stream.of(_btnReRunTimerRepeatsStop.getActionListeners()).forEach(al -> _btnReRunTimerRepeatsStop.removeActionListener(al)); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunCurrentSQLResultTabAction.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunCurrentSQLResultTabAction.java index 0869ebacd8..01c09ff108 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunCurrentSQLResultTabAction.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunCurrentSQLResultTabAction.java @@ -1,18 +1,19 @@ package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; +import java.awt.Frame; +import java.awt.event.ActionEvent; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.action.SquirrelAction; import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.action.ISQLPanelAction; +import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; import net.sourceforge.squirrel_sql.client.session.mainpanel.ResultTab; -import java.awt.event.ActionEvent; - public class RerunCurrentSQLResultTabAction extends SquirrelAction implements ISQLPanelAction { private ResultTabProvider _resultTabProvider; - public RerunCurrentSQLResultTabAction(ResultTab resultTab) + public RerunCurrentSQLResultTabAction(ResultTab resultTab) { super(Main.getApplication()); _resultTabProvider = new ResultTabProvider(resultTab); @@ -25,15 +26,72 @@ public RerunCurrentSQLResultTabAction() public void setSQLPanel(ISQLPanelAPI panel) { - setEnabled(_resultTabProvider.setSQLPanelAPI(panel)); + _resultTabProvider.setSQLPanelAPI(panel); + doEnable(); } - public synchronized void actionPerformed(ActionEvent evt) + private void doEnable() { - if (_resultTabProvider.hasResultTab()) + setEnabled(_resultTabProvider.hasResultTab()); + } + + public void actionPerformed(ActionEvent evt) + { + if (false == _resultTabProvider.hasResultTab()) + { + return; + } + + switch(RerunResultTabMode.getCurrentMode()) { - _resultTabProvider.getResultTab().reRunSQL(); + case DEFAULT -> _resultTabProvider.getResultTab().reRunSQL(); + case TIMER_REPEATS -> rerunWithTimerRepeats(); } } + + private void rerunWithTimerRepeats() + { + IResultTab resultTab = _resultTabProvider.getResultTab(); + if(null == resultTab) + { + return; + } + + Frame parentWindow; + + ISQLPanelAPI sqlPanelApi = _resultTabProvider.getSqlPanelApiOrNull(); + if(null == sqlPanelApi) + { + parentWindow = Main.getApplication().getMainFrame(); + } + else + { + parentWindow = sqlPanelApi.getOwningFrame(); + } + + RerunWithTimerRepeatsCtrl rerunWithTimerRepeatsCtrl = new RerunWithTimerRepeatsCtrl(parentWindow); + + if(false == rerunWithTimerRepeatsCtrl.isOk()) + { + return; + } + + int repeatSeconds = rerunWithTimerRepeatsCtrl.getRepeatSeconds(); + + if(0 == repeatSeconds) + { + resultTab.reRunSQL(); + } + else + { + resultTab.reRunSqlWithTimerRepeats(repeatSeconds); + } + } + + public void setResultTab(ResultTab resultTab) + { + _resultTabProvider.setResultTab(resultTab); + doEnable(); + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunResultTabMode.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunResultTabMode.java new file mode 100644 index 0000000000..0bf2c6f9eb --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunResultTabMode.java @@ -0,0 +1,21 @@ +package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; + +import net.sourceforge.squirrel_sql.fw.props.Props; + +public enum RerunResultTabMode +{ + DEFAULT, + TIMER_REPEATS; + + private static final String PREF_RERUN_RESULT_TAB_MODE = "RerunResultTabMode.rerun.result.tab.mode"; + + static RerunResultTabMode getCurrentMode() + { + return RerunResultTabMode.valueOf(Props.getString(PREF_RERUN_RESULT_TAB_MODE, RerunResultTabMode.DEFAULT.name())); + } + + static void setCurrentMode(RerunResultTabMode mode) + { + Props.putString(PREF_RERUN_RESULT_TAB_MODE, mode.name()); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsCtrl.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsCtrl.java new file mode 100644 index 0000000000..17d5ff8e82 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsCtrl.java @@ -0,0 +1,52 @@ +package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; + +import java.awt.Frame; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.props.Props; + +public class RerunWithTimerRepeatsCtrl +{ + private static final String PREFS_KEY_REPEAT_INTERVAL = "RerunWithTimerRepeatsCtrl.repeat.interval"; + + private final RerunWithTimerRepeatsDlg _dlg; + private boolean _ok; + + public RerunWithTimerRepeatsCtrl(Frame parentWindow) + { + _dlg = new RerunWithTimerRepeatsDlg(parentWindow); + + _dlg.txtSeconds.setInt(Props.getInt(PREFS_KEY_REPEAT_INTERVAL, 5)); + + _dlg.btnOK.addActionListener(e -> onOk()); + _dlg.btnCancel.addActionListener(e -> close()); + + GUIUtils.initLocation(_dlg, 400, 130); + GUIUtils.enableCloseByEscape(_dlg); + + GUIUtils.forceFocus(_dlg.txtSeconds); + _dlg.setVisible(true); + } + + private void onOk() + { + _ok = true; + close(); + } + + private void close() + { + Props.putInt(PREFS_KEY_REPEAT_INTERVAL, _dlg.txtSeconds.getInt()); + _dlg.setVisible(true); + _dlg.dispose(); + } + + public boolean isOk() + { + return _ok; + } + + public int getRepeatSeconds() + { + return _dlg.txtSeconds.getInt(); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsDlg.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsDlg.java new file mode 100644 index 0000000000..a0ca24e9b6 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/RerunWithTimerRepeatsDlg.java @@ -0,0 +1,65 @@ +package net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions; + +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.gui.IntegerField; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; + +public class RerunWithTimerRepeatsDlg extends JDialog +{ + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(RerunWithTimerRepeatsDlg.class); + + IntegerField txtSeconds; + JButton btnOK; + JButton btnCancel; + + public RerunWithTimerRepeatsDlg(Frame parentWindow) + { + super(parentWindow, s_stringMgr.getString("RerunWithTimerRepeatsDlg.title"), true); + getContentPane().setLayout(new GridBagLayout()); + + GridBagConstraints gbc; + + gbc = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,5), 0,0); + getContentPane().add(new JLabel(s_stringMgr.getString("RerunWithTimerRepeatsDlg.enter.repeat.interval.in.seconds")), gbc); + + gbc = new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,5), 0,0); + txtSeconds = new IntegerField(5, 0); + GUIUtils.setPreferredWidth(txtSeconds, 100); + GUIUtils.setMinimumWidth(txtSeconds, 100); + getContentPane().add(txtSeconds, gbc); + + gbc = new GridBagConstraints(0,2,2,1,0,0,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10,5,0,5), 0,0); + getContentPane().add(createButtonPanel(), gbc); + + gbc = new GridBagConstraints(0,3,2,1,1,1,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0,0); + getContentPane().add(new JPanel(), gbc); + + getRootPane().setDefaultButton(btnOK); + } + + private JPanel createButtonPanel() + { + JPanel ret = new JPanel(new GridBagLayout()); + + GridBagConstraints gbc; + + gbc = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); + btnOK = new JButton(s_stringMgr.getString("RerunWithTimerRepeatsDlg.ok")); + ret.add(btnOK, gbc); + + gbc = new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,5,0,0), 0,0); + btnCancel = new JButton(s_stringMgr.getString("RerunWithTimerRepeatsDlg.cancel")); + ret.add(btnCancel, gbc); + + return ret; + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ResultTabProvider.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ResultTabProvider.java index 25068ecb3a..68f79e5d27 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ResultTabProvider.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/session/mainpanel/resulttabactions/ResultTabProvider.java @@ -3,20 +3,18 @@ import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; import net.sourceforge.squirrel_sql.client.session.mainpanel.ISQLResultExecutor; +import net.sourceforge.squirrel_sql.client.session.mainpanel.ResultTabCloseListener; public class ResultTabProvider { + private final ResultTabCloseListener _resultTabCloseListener = () -> _resultTab = null; + private ISQLPanelAPI _panel; private IResultTab _resultTab; public ResultTabProvider(IResultTab resultTab) { - _resultTab = resultTab; - - if(null != _resultTab) - { - _resultTab.addResultTabCloseListener(() -> _resultTab = null); - } + setResultTab(resultTab); } public boolean setSQLPanelAPI(ISQLPanelAPI panel) @@ -57,4 +55,20 @@ public ISQLPanelAPI getSqlPanelApiOrNull() { return _panel; } + + public void setResultTab(IResultTab resultTab) + { + if(null != _resultTab) + { + _resultTab.removeResultTabCloseListener(_resultTabCloseListener); + } + + _resultTab = resultTab; + + if(null != _resultTab) + { + _resultTab.addResultTabCloseListener(_resultTabCloseListener); + } + + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutDescriptionReader.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutDescriptionReader.java new file mode 100644 index 0000000000..4bc765dbb2 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutDescriptionReader.java @@ -0,0 +1,126 @@ +package net.sourceforge.squirrel_sql.client.shortcut; + +import java.util.MissingResourceException; +import javax.swing.Action; +import javax.swing.JMenuItem; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.resources.IResources; +import net.sourceforge.squirrel_sql.fw.resources.ResourceBundleHandler; +import net.sourceforge.squirrel_sql.fw.resources.Resources; +import org.apache.commons.lang3.StringUtils; + +public record ShortCutDescriptionReader(Action action, + Class actionClass, + JMenuItem mnuItem, + Resources resources, + ResourceBundleHandler bundleHandler, + String fullResourceKey) +{ + public static ShortCutDescriptionReader of(Action action) + { + return new ShortCutDescriptionReader(action, null, null, null, null, null); + } + + public static ShortCutDescriptionReader of(Action action, JMenuItem mnuItem) + { + return new ShortCutDescriptionReader(action, null, mnuItem, null, null, null); + } + + public static ShortCutDescriptionReader of(JMenuItem menuItem) + { + return new ShortCutDescriptionReader(null, null, menuItem, null, null, null); + } + + public static ShortCutDescriptionReader of(Resources resources, Class actionClass) + { + return new ShortCutDescriptionReader(null, actionClass, null, resources, null, null); + } + + public static ShortCutDescriptionReader of(Action action, String fullResourceKey, ResourceBundleHandler bundleHandler) + { + return new ShortCutDescriptionReader(action, null, null, null, bundleHandler, fullResourceKey); + } + + public static ShortCutDescriptionReader of() + { + return new ShortCutDescriptionReader(null, null, null, null, null, null); + } + + public String getDescription() + { + String description = null; + + Class actCls = actionClass; + + if(null == actCls && null != action) + { + actCls = action.getClass(); + } + + + if(null != resources && null != actCls) + { + description = resources.getTooltipFromResource(actCls); + } + + if(StringUtils.isBlank(description)) + { + Action act = action; + + if(null == act && null != actionClass) + { + act = Main.getApplication().getActionCollection().get(actionClass); + } + + if(null != act) + { + description = (null == act.getValue(Action.SHORT_DESCRIPTION) ? null : "" + act.getValue(Action.SHORT_DESCRIPTION)); + + if(StringUtils.isBlank(description)) + { + description = (null == act.getValue(Action.SHORT_DESCRIPTION) ? null : "" + act.getValue(Action.LONG_DESCRIPTION)); + } + } + } + + if(StringUtils.isBlank(description) && !StringUtils.isBlank(fullResourceKey)) + { + String resKey = fullResourceKey; + + if(fullResourceKey.startsWith(IResources.Keys.MENU_ITEM)) + { + resKey = StringUtils.replace(fullResourceKey, IResources.Keys.MENU_ITEM, IResources.Keys.ACTION, 1); + } + + if(null != resources) + { + try + { + description = resources.getTooltipFromResource(resKey); + } + catch(MissingResourceException e) + { + } + } + + if(StringUtils.isBlank(description) && null != bundleHandler) + { + try + { + description = bundleHandler.getResourceString(resKey, IResources.ActionProperties.TOOLTIP); + } + catch(MissingResourceException e) + { + } + } + } + + if(StringUtils.isBlank(description)) + { + description = null; + } + + return description; + } + +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutReader.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutReader.java index 9b502abc35..9b4356924e 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutReader.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortCutReader.java @@ -1,14 +1,13 @@ package net.sourceforge.squirrel_sql.client.shortcut; +import java.util.MissingResourceException; +import javax.swing.Action; +import javax.swing.KeyStroke; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.fw.resources.IResources; import net.sourceforge.squirrel_sql.fw.resources.ResourceBundleHandler; import net.sourceforge.squirrel_sql.fw.util.StringUtilities; -import javax.swing.Action; -import javax.swing.KeyStroke; -import java.util.MissingResourceException; - public class ShortCutReader { private ResourceBundleHandler _bundleHandler; @@ -63,7 +62,7 @@ private String _getShortcutAsString(String fullResourceKey, String actionName, A if (false == defaultShortCut && false == StringUtilities.isEmpty(actionName, true)) { // Possibly replace the standard shortcut with the user defined one. - ret = Main.getApplication().getShortcutManager().registerAccelerator(actionName, KeyStroke.getKeyStroke(ret)); + ret = Main.getApplication().getShortcutManager().registerAccelerator(actionName, KeyStroke.getKeyStroke(ret), ShortCutDescriptionReader.of(action, fullResourceKey, _bundleHandler)); } return ret; diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/Shortcut.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/Shortcut.java index e0f3bc4ee1..d45cf0fcf0 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/Shortcut.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/Shortcut.java @@ -1,20 +1,21 @@ package net.sourceforge.squirrel_sql.client.shortcut; -import org.jfree.chart.util.ObjectUtils; - import javax.swing.KeyStroke; +import org.jfree.chart.util.ObjectUtils; public class Shortcut { private final String _actionName; + private final String _actionDescription; private final KeyStroke _defaultKeyStroke; private KeyStroke _userKeyStroke; private boolean _userKeyStrokeEmpty; - public Shortcut(String actionName, KeyStroke defaultKeyStroke) + public Shortcut(String actionName, KeyStroke defaultKeyStroke, String actionDescription) { _actionName = actionName; _defaultKeyStroke = defaultKeyStroke; + _actionDescription = actionDescription; } /** @@ -57,6 +58,13 @@ public KeyStroke validKeyStroke() return _defaultKeyStroke; } + /** + * Used via reflection by JavabeanArrayDataSet + */ + public String getActionDescription() + { + return _actionDescription; + } public void setUserKeyStroke(KeyStroke userKeyStroke) { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortcutManager.java b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortcutManager.java index f49b51744e..6eee09d98a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortcutManager.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/client/shortcut/ShortcutManager.java @@ -5,15 +5,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.type.SimpleType; -import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.client.util.ApplicationFiles; -import net.sourceforge.squirrel_sql.fw.resources.Resources; -import net.sourceforge.squirrel_sql.fw.util.StringUtilities; -import net.sourceforge.squirrel_sql.fw.util.Utilities; - -import javax.swing.Action; -import javax.swing.JMenuItem; -import javax.swing.KeyStroke; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -22,6 +13,13 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import javax.swing.Action; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; +import net.sourceforge.squirrel_sql.client.util.ApplicationFiles; +import net.sourceforge.squirrel_sql.fw.resources.Resources; +import net.sourceforge.squirrel_sql.fw.util.StringUtilities; +import net.sourceforge.squirrel_sql.fw.util.Utilities; public class ShortcutManager { @@ -71,14 +69,14 @@ public List getShortcuts() return new ArrayList<>(_shortcuts); } - public KeyStroke setAccelerator(JMenuItem item, KeyStroke defaultKeyStroke, Action action) + public KeyStroke setAccelerator(JMenuItem item, KeyStroke defaultKeyStroke, Action action, ShortCutDescriptionReader descReader) { - return setAccelerator(item, defaultKeyStroke, (String) action.getValue(Action.NAME)); + return setAccelerator(item, defaultKeyStroke, (String) action.getValue(Action.NAME), descReader); } - public KeyStroke setAccelerator(JMenuItem item, KeyStroke defaultKeyStroke, String actionName) + public KeyStroke setAccelerator(JMenuItem item, KeyStroke defaultKeyStroke, String actionName, ShortCutDescriptionReader descReader) { - Shortcut shortcut = _registerAccelerator(actionName, defaultKeyStroke); + Shortcut shortcut = _registerAccelerator(actionName, defaultKeyStroke, descReader); item.setAccelerator(shortcut.validKeyStroke()); @@ -86,33 +84,28 @@ public KeyStroke setAccelerator(JMenuItem item, KeyStroke defaultKeyStroke, Stri } - public void registerAccelerator(Class actionClass) - { - registerAccelerator(actionClass, Main.getApplication().getResources()); - } - - public String registerAccelerator(Class actionClass, Resources resources) + public String registerAccelerator(Class actionClass, Resources resources, ShortCutDescriptionReader descReader) { String actionName = resources.getActionName(actionClass); KeyStroke defaultKeyStroke = resources.getShortCutReader().getDefaultShortcutAsKeyStroke(resources.getFullMenuItemKey(actionClass), actionName); - return _registerAccelerator(actionName, defaultKeyStroke).getValidKeyStroke(); + return _registerAccelerator(actionName, defaultKeyStroke, descReader).getValidKeyStroke(); } - public String registerAccelerator(String actionName, KeyStroke defaultKeyStroke) + public String registerAccelerator(String actionName, KeyStroke defaultKeyStroke, ShortCutDescriptionReader descReader) { - return _registerAccelerator(actionName, defaultKeyStroke).getValidKeyStroke(); + return _registerAccelerator(actionName, defaultKeyStroke, descReader).getValidKeyStroke(); } - private Shortcut _registerAccelerator(String actionName, KeyStroke defaultKeyStroke) + private Shortcut _registerAccelerator(String actionName, KeyStroke defaultKeyStroke, ShortCutDescriptionReader descReader) { if(StringUtilities.isEmpty(actionName, true)) { - return new Shortcut(actionName, defaultKeyStroke); + return new Shortcut(actionName, defaultKeyStroke, descReader.getDescription()); } - Shortcut ret = new Shortcut(actionName, defaultKeyStroke); + Shortcut ret = new Shortcut(actionName, defaultKeyStroke, descReader.getDescription()); String userShortCutString = _shortcutsJsonBeanLoadedAtStartUp.getShortcutByKey().get(ret.generateKey()); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/DataSetViewerTable.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/DataSetViewerTable.java index ed46978b3b..20a28aa7be 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/DataSetViewerTable.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/DataSetViewerTable.java @@ -1,5 +1,17 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.DefaultCellEditor; +import javax.swing.JOptionPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumnModel; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.CellComponentFactory; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.CellRenderer; @@ -15,19 +27,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.DefaultCellEditor; -import javax.swing.JOptionPane; -import javax.swing.JTable; -import javax.swing.table.DefaultTableColumnModel; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableColumnModel; -import java.awt.Graphics; -import java.awt.Point; -import java.awt.Rectangle; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; - /* * The JTable used for displaying all DB ResultSet info. */ @@ -51,6 +50,7 @@ public final class DataSetViewerTable extends JTable private ColoringService _coloringService; + private FontService _fontService; DataSetViewerTable(DataSetViewerTablePanel dataSetViewerTablePanel, IDataSetViewAccess dataSetViewAccess, IDataSetUpdateableModel dataSetUpdateableModel, int listSelectionMode, ISession session) @@ -80,6 +80,7 @@ public final class DataSetViewerTable extends JTable // Do in the end of constructor as we pass this as parameter. _coloringService = new ColoringService(this); + _fontService = new FontService(this); } @@ -283,6 +284,8 @@ else if (colWidth < IDataSetViewer.MIN_COLUMN_WIDTH * _multiplier) CellRenderer tableCellRenderer = CellComponentFactory.getTableCellRenderer(colDefs[i]); tableCellRenderer.setColoringService(_coloringService); + tableCellRenderer.setFontService(_fontService); + ExtTableColumn col = new ExtTableColumn(i, colWidth, tableCellRenderer, null); @@ -411,6 +414,11 @@ public ColoringService getColoringService() return _coloringService; } + public FontService getFontService() + { + return _fontService; + } + public void scrollToVisible(int viewRow, int viewCol) { Rectangle cellRect = getCellRect(viewRow, viewCol, true); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/FontService.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/FontService.java new file mode 100644 index 0000000000..299eb2e552 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/FontService.java @@ -0,0 +1,69 @@ +package net.sourceforge.squirrel_sql.fw.datasetviewer; + +import java.awt.Component; +import java.awt.Font; +import java.util.HashSet; +import java.util.Set; + +public class FontService +{ + public static final Font MONO_SPACED_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12); + + private final DataSetViewerTable _dataSetViewerTable; + private Font _originalCellFont = null; + private Set _monospacedColumns = new HashSet<>(); + + public FontService(DataSetViewerTable dataSetViewerTable) + { + _dataSetViewerTable = dataSetViewerTable; + _dataSetViewerTable.getButtonTableHeader().addColumnDragListener(() -> onColumnDragged()); + } + + private void onColumnDragged() + { + _monospacedColumns.clear(); + _dataSetViewerTable.repaint(); + } + + public void initCellFont(Component tableCellRendererComponent, int columnIx) + { + if (RowNumberTableColumn.ROW_NUMBER_MODEL_INDEX == _dataSetViewerTable.getColumnModel().getColumn(columnIx).getModelIndex()) + { + return; + } + + if(null == _originalCellFont) + { + _originalCellFont = tableCellRendererComponent.getFont(); + } + + if(_monospacedColumns.contains(columnIx)) + { + tableCellRendererComponent.setFont(MONO_SPACED_FONT); + } + else + { + tableCellRendererComponent.setFont(_originalCellFont); + } + } + + public void toggleMonoSpaced(int[] selectedColumnIndexes) + { + //List buf = List.of(Arrays.stream(selectedColumnIndexes).boxed().toArray(Integer[]::new)); + //_monospacedColumns.removeIf(ix -> false == buf.contains(ix)); + + for(int selectedColumn : selectedColumnIndexes) + { + if(_monospacedColumns.contains(selectedColumn)) + { + _monospacedColumns.remove(selectedColumn); + } + else + { + _monospacedColumns.add(selectedColumn); + } + } + + _dataSetViewerTable.repaint(); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/JavabeanArrayDataSet.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/JavabeanArrayDataSet.java index 69d5ebfa15..affeadfca7 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/JavabeanArrayDataSet.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/JavabeanArrayDataSet.java @@ -18,10 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.fw.util.EmptyIterator; -import net.sourceforge.squirrel_sql.fw.util.IMessageHandler; -import net.sourceforge.squirrel_sql.fw.util.Utilities; - import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; @@ -35,6 +31,9 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import net.sourceforge.squirrel_sql.fw.util.EmptyIterator; +import net.sourceforge.squirrel_sql.fw.util.IMessageHandler; +import net.sourceforge.squirrel_sql.fw.util.Utilities; public class JavabeanArrayDataSet implements IDataSet { @@ -48,10 +47,10 @@ public class JavabeanArrayDataSet implements IDataSet private Class _beanClass; private BeanPorpertyColumnDisplayDefinition[] _beanPorpertyColumnDisplayDefinitions; - private HashMap _headers = new HashMap(); - private HashMap _positions = new HashMap(); - private HashMap _absoluteWidths = new HashMap(); - private HashSet _ignoreProperties = new HashSet(); + private HashMap _headers = new HashMap<>(); + private HashMap _positions = new HashMap<>(); + private HashMap _absoluteWidths = new HashMap<>(); + private HashSet _ignoreProperties = new HashSet<>(); /** diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/ResultSetDataSet.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/ResultSetDataSet.java index 9b977c62ae..7d462a61df 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/ResultSetDataSet.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/ResultSetDataSet.java @@ -21,6 +21,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; + import net.sourceforge.squirrel_sql.fw.dialects.DialectType; import net.sourceforge.squirrel_sql.fw.sql.JDBCTypeMapper; import net.sourceforge.squirrel_sql.fw.sql.ResultSetReader; @@ -30,10 +38,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.sql.*; -import java.util.ArrayList; -import java.util.List; - public class ResultSetDataSet implements IDataSet { private final static ILogger s_log = LoggerController.createLogger(ResultSetDataSet.class); @@ -47,7 +51,7 @@ public class ResultSetDataSet implements IDataSet private DataSetDefinition _dataSetDefinition; - private List _alData; + private List _allData; /** * If true cancel has been requested. @@ -87,19 +91,6 @@ public ResultSetDataSet() this.tableColumnInfos = new TableColumnInfo[]{}; } - /** - * Form used by Tabs other than ContentsTab - * - * @param rs the ResultSet to set. - * @param dialectType the type of dialect in use. - * @throws DataSetException - */ - public int setResultSet(ResultSet rs, DialectType dialectType) throws DataSetException - { - return _setResultSet(new ResultSetWrapper(rs), null, null, false, false, dialectType); - } - - /** * Content Tab may wish to limit data read for big columns. * @@ -110,47 +101,39 @@ public void setLimitDataRead(boolean limitDataRead) this._limitDataRead = limitDataRead; } - /** - * Form used by ContentsTab, and for SQL results - * - * @param rs the ResultSet to set. - * @param fullTableName the fully-qualified table name - * @param dialectType the type of dialect in use. - * @throws DataSetException - */ - public int setContentsTabResultSet(ResultSet rs, String fullTableName, DialectType dialectType) throws DataSetException + public int readDataFromJdbcResultSetForObjectTreeContentTabs(ResultSet rs, String fullTableName, DialectType dialectType) throws DataSetException { - return _setResultSet(new ResultSetWrapper(rs), fullTableName, null, false, true, dialectType); + return _readDataFromJdbcResultSet(new ResultSetWrapper(rs), fullTableName, null, false, true, dialectType); } - public int setSqlExecutionTabResultSet(ResultSetWrapper rs, String fullTableName, DialectType dialectType) throws DataSetException + public int readDataFromJdbcResultSetForSqlExecution(ResultSetWrapper rs, String fullTableName, DialectType dialectType) throws DataSetException { - return _setResultSet(rs, fullTableName, null, false, true, dialectType); + return _readDataFromJdbcResultSet(rs, fullTableName, null, false, true, dialectType); } + public int readDataFromJdbcResultSetForDatabaseMetaData(ResultSet rs, int[] columnIndices, boolean computeWidths, DialectType dialectType) throws DataSetException + { + return _readDataFromJdbcResultSet(new ResultSetWrapper(rs), null, columnIndices, computeWidths, false, dialectType); + } - /** - * External method to read the contents of a ResultSet that is used by all - * Tab classes except ContentsTab. This tunrs all the data into strings for - * simplicity of operation. - */ - public int setResultSet(ResultSet rs, int[] columnIndices, boolean computeWidths, DialectType dialectType) throws DataSetException + public int readDataFromJdbcResultSetForGeneralPurpose(ResultSet rs, DialectType dialectType) throws DataSetException { - return _setResultSet(new ResultSetWrapper(rs), null, columnIndices, computeWidths, false, dialectType); + return _readDataFromJdbcResultSet(new ResultSetWrapper(rs), null, null, false, false, dialectType); } + /** * Internal method to read the contents of a ResultSet that is used by all * Tab classes * * @return The number of rows read from the ResultSet */ - private int _setResultSet(ResultSetWrapper rs, - String fullTableName, - int[] columnIndices, - boolean computeWidths, - boolean useColumnDefs, - DialectType dialectType) throws DataSetException + private int _readDataFromJdbcResultSet(ResultSetWrapper rs, + String fullTableName, + int[] columnIndices, + boolean computeWidths, + boolean useColumnDefs, + DialectType dialectType) throws DataSetException { reset(); _dialectType = dialectType; @@ -161,7 +144,7 @@ private int _setResultSet(ResultSetWrapper rs, } _iCurrent = -1; - _alData = new ArrayList<>(); + _allData = new ArrayList<>(); if (rs == null) { @@ -193,7 +176,7 @@ private int _setResultSet(ResultSetWrapper rs, { if (_cancel) { - return _alData.size(); + return _allData.size(); } Object[] row = createRow(columnIndices, useColumnDefs, colDefs, BlockMode.FIRST_BLOCK); @@ -204,11 +187,11 @@ private int _setResultSet(ResultSetWrapper rs, } else { - _alData.add(row); + _allData.add(row); } } - return _alData.size(); + return _allData.size(); // ColumnDisplayDefinition[] colDefs = createColumnDefinitions(md, // columnIndices, computeWidths); @@ -282,9 +265,9 @@ public synchronized boolean next(IMessageHandler msgHandler) throws DataSetException { // TODO: This should be handled with an Iterator - if (++_iCurrent < _alData.size()) + if (++_iCurrent < _allData.size()) { - _currentRow = _alData.get(_iCurrent); + _currentRow = _allData.get(_iCurrent); return true; } return false; @@ -327,9 +310,9 @@ private ColumnDisplayDefinition[] createColumnDefinitions( if (computeWidths) { colWidths = new int[_columnCount]; - for (int i = 0; i < _alData.size(); i++) + for (int i = 0; i < _allData.size(); i++) { - Object[] row = _alData.get(i); + Object[] row = _allData.get(i); for (int col = 0; i < _columnCount; i++) { if (row[col] != null) @@ -569,7 +552,7 @@ private void reset() _currentRow = null; _columnCount = 0; _dataSetDefinition = null; - _alData = null; + _allData = null; } public void resetCursor() @@ -587,9 +570,9 @@ public void resetCursor() */ public Object removeRow(int index) { - if (_alData.size() > index) + if (_allData.size() > index) { - return _alData.remove(index); + return _allData.remove(index); } else { @@ -617,7 +600,7 @@ public String toString() } - for (Object[] row : _alData) + for (Object[] row : _allData) { for (Object rowItem : row) { @@ -639,7 +622,7 @@ public String toString() public List getAllDataForReadOnly() { - return _alData; + return _allData; } public void readMoreResults() @@ -655,7 +638,7 @@ public void readMoreResults() } else { - _alData.add(row); + _allData.add(row); } } @@ -670,7 +653,7 @@ public void readMoreResults() public int currentRowCount() { - return _alData.size(); + return _allData.size(); } public boolean isAllResultsRead() @@ -696,6 +679,6 @@ public void closeStatementAndResultSet() public void replaceDataOnUserEdits(ArrayList updatedRows) { resetCursor(); - _alData = updatedRows; + _allData = updatedRows; } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/CellRenderer.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/CellRenderer.java index e4775f9912..90b12788ef 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/CellRenderer.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/CellRenderer.java @@ -1,11 +1,11 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent; -import net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.ColoringService; - +import java.awt.Component; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; -import java.awt.Component; +import net.sourceforge.squirrel_sql.fw.datasetviewer.FontService; +import net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.ColoringService; /** * The base component of a DefaultTableCellRenderer is a JLabel. @@ -16,6 +16,7 @@ public final class CellRenderer extends DefaultTableCellRenderer implements Squi { private final IDataTypeComponent _dataTypeObject; private ColoringService _coloringService; + private FontService _fontService; CellRenderer(IDataTypeComponent dataTypeObject) { @@ -50,6 +51,13 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole _coloringService.colorCell(this, _dataTypeObject, table, value, isSelected, hasFocus, row, column); } + if (null != _fontService) + { + + + _fontService.initCellFont(this, column); + } + BlobClobLoadCheck.check(_dataTypeObject, table, value, isSelected, hasFocus, row, column); return label; @@ -86,4 +94,9 @@ public void setColoringService(ColoringService coloringService) { _coloringService = coloringService; } + + public void setFontService(FontService fontService) + { + _fontService = fontService; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeString.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeString.java index 3332a93b46..abec087ee2 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeString.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeString.java @@ -18,32 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; -import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.EmptyWhereClausePart; -import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.IWhereClausePart; -import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.IsNullWhereClausePart; -import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.ParameterWhereClausePart; -import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogHandler; -import net.sourceforge.squirrel_sql.fw.gui.IntegerField; -import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; -import net.sourceforge.squirrel_sql.fw.gui.OkJPanel; -import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import net.sourceforge.squirrel_sql.fw.util.StringUtilities; -import net.sourceforge.squirrel_sql.fw.util.Utilities; - -import javax.swing.BorderFactory; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTable; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.text.JTextComponent; import java.awt.Color; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; @@ -60,6 +34,32 @@ import java.sql.ResultSet; import java.sql.Types; import java.util.Iterator; +import javax.swing.BorderFactory; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.text.JTextComponent; + +import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; +import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.EmptyWhereClausePart; +import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.IWhereClausePart; +import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.IsNullWhereClausePart; +import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.whereClause.ParameterWhereClausePart; +import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogHandler; +import net.sourceforge.squirrel_sql.fw.gui.IntegerField; +import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; +import net.sourceforge.squirrel_sql.fw.gui.OkJPanel; +import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; +import net.sourceforge.squirrel_sql.fw.util.StringUtilities; +import net.sourceforge.squirrel_sql.fw.util.Utilities; /** @@ -123,7 +123,7 @@ public class DataTypeString extends BaseDataTypeComponent * otherwise do not include it. * Oracle does not allow that type to be used in a WHERE clause */ - private static boolean _useLongInWhere = true; + private static boolean _useLongVarcharInWhere = true; /** @@ -163,10 +163,10 @@ private static void loadProperties() { if (makeNewlinesVisibleString != null && makeNewlinesVisibleString.equals("false")) _makeNewlinesVisibleInCell = false; - _useLongInWhere = true; // set to the default + _useLongVarcharInWhere = true; // set to the default String useLongInWhereString = DataTypeProps.getProperty(DataTypeString.class.getName(), "useLongInWhere"); if (useLongInWhereString != null && useLongInWhereString.equals("false")) - _useLongInWhere = false; + _useLongVarcharInWhere = false; LimitReadLengthFeatureUnstable._limitRead = false; // set to default String limitReadString = DataTypeProps.getProperty(DataTypeString.class.getName(), "limitRead"); @@ -542,27 +542,32 @@ public Object readResultSet(ResultSet rs, int index, boolean limitDataRead) * or whatever is appropriate for this column in the database. */ @Override - public IWhereClausePart getWhereClauseValue(Object value, ISQLDatabaseMetaData md) { + public IWhereClausePart getWhereClauseValue(Object value, ISQLDatabaseMetaData md) + { // first do special check to see if we should use LONGVARCHAR // in the WHERE clause. // (Oracle does not allow this.) - if (_colDef.getSqlType() == Types.LONGVARCHAR && - _useLongInWhere == false) - return null; // this column cannot be used in a WHERE clause + if( _colDef.getSqlType() == Types.LONGVARCHAR && _useLongVarcharInWhere == false ) + { + return null; // this column cannot be used in a WHERE clause + } - if (value == null || value.toString() == null ) + if( value == null || value.toString() == null ) + { return new IsNullWhereClausePart(_colDef); - else { + } + else + { // We cannot use this data in the WHERE clause if it has been truncated. // Since being truncated is the same as needing to re-read, // only use this in the WHERE clause if we do not need to re-read - if ( ! needToReRead(value)) + if( !needToReRead(value) ) { return new ParameterWhereClausePart(_colDef, value, this); } - else - { - return new EmptyWhereClausePart(); // value is truncated, so do not use in WHERE clause + else + { + return new EmptyWhereClausePart(); // value is truncated, so do not use in WHERE clause } } } @@ -842,7 +847,7 @@ public DataTypeStringPanel() { _makeNewlinesVisibleInCellChk.setSelected(_makeNewlinesVisibleInCell); // checkbox for using LONG in WHERE clause - _useLongInWhereChk.setSelected(_useLongInWhere); + _useLongInWhereChk.setSelected(_useLongVarcharInWhere); // checkbox for limit/no-limit on data read during initial table load _limitReadChk.setSelected(LimitReadLengthFeatureUnstable._limitRead); @@ -979,8 +984,8 @@ public void ok() { _makeNewlinesVisibleInCell = _makeNewlinesVisibleInCellChk.isSelected(); DataTypeProps.putDataTypeProperty(DataTypeString.class.getName(), "makeNewlinesVisibleInCell", Boolean.valueOf(_makeNewlinesVisibleInCell).toString()); - _useLongInWhere = _useLongInWhereChk.isSelected(); - DataTypeProps.putDataTypeProperty(DataTypeString.class.getName(), "useLongInWhere", Boolean.valueOf(_useLongInWhere).toString()); + _useLongVarcharInWhere = _useLongInWhereChk.isSelected(); + DataTypeProps.putDataTypeProperty(DataTypeString.class.getName(), "useLongInWhere", Boolean.valueOf(_useLongVarcharInWhere).toString()); LimitReadLengthFeatureUnstable._limitRead = _limitReadChk.isSelected(); DataTypeProps.putDataTypeProperty(DataTypeString.class.getName(), "limitRead", Boolean.valueOf(LimitReadLengthFeatureUnstable._limitRead).toString()); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialog.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialog.java index 5c255150b3..49067b59d8 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialog.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialog.java @@ -1,22 +1,17 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup; import java.awt.GridLayout; +import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JDialog; -import javax.swing.JTable; -import javax.swing.SwingUtilities; - import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; -import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.CellDisplayPanel; import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.CellDisplayPanelContent; import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.DisplayMode; import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.DisplayPanelListener; import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.ResultImageDisplayPanel; import net.sourceforge.squirrel_sql.fw.datasetviewer.tablefind.GlobalFindRemoteControl; -import net.sourceforge.squirrel_sql.fw.gui.CloseByEscapeListener; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; @@ -27,27 +22,14 @@ public class CellDataDialog extends JDialog private CellDisplayPanel _cellDisplayPanel; - public CellDataDialog(JTable parentTable, - String columnName, - int rowIx, - int colIx, - ColumnDisplayDefinition colDef, - Object objectToDisplay, - boolean isModelEditable) + public CellDataDialog(CellDataDialogState cellDataDialogState, Window parentWindow) { - super(SwingUtilities.windowForComponent(parentTable)); + super(parentWindow); getContentPane().setLayout(new GridLayout(1,1)); - initCellDisplayPanel(parentTable, columnName, rowIx, colIx, colDef, objectToDisplay, isModelEditable,false); + initCellDisplayPanel(cellDataDialogState); - GUIUtils.enableCloseByEscape(this, new CloseByEscapeListener() - { - @Override - public void willCloseByEscape(JDialog dialog) - { - cleanUp(); - } - }); + GUIUtils.enableCloseByEscape(this, dialog -> cleanUp()); addWindowListener(new WindowAdapter() { @@ -70,15 +52,10 @@ private void cleanUp() _cellDisplayPanel.cleanUp(); } - public void initCellDisplayPanel(JTable table, - String columnName, - int rowIx, - int colIx, - ColumnDisplayDefinition colDef, - Object value, - boolean isModelEditable, - boolean pinned) + public void initCellDisplayPanel(CellDataDialogState cellDataDialogState) { + + if(null != _cellDisplayPanel) { getContentPane().remove(_cellDisplayPanel); @@ -86,14 +63,14 @@ public void initCellDisplayPanel(JTable table, _cellDisplayPanel = null; } - setTitle(s_stringMgr.getString("cellDataPopup.valueofColumn", columnName)); + setTitle(s_stringMgr.getString("cellDataPopup.valueofColumn", cellDataDialogState.getCellName())); DisplayPanelListener displayPanelListener = new DisplayPanelListener() { @Override public void displayModeChanged() { - onDisplayModeChanged(colDef, value, rowIx, colIx, isModelEditable, table); + onDisplayModeChanged(cellDataDialogState); } @Override @@ -103,12 +80,12 @@ public void scaleImageToPanelSize() } }; - _cellDisplayPanel =new CellDisplayPanel(displayPanelListener,sticky -> onToggleSticky(sticky), pinned); + _cellDisplayPanel =new CellDisplayPanel(displayPanelListener,sticky -> onToggleSticky(sticky), cellDataDialogState.isPinned()); - _cellDisplayPanel.setCurrentColumnDisplayDefinition(colDef); + _cellDisplayPanel.setCurrentColumnDisplayDefinition(cellDataDialogState.getColDispDef()); getContentPane().add(_cellDisplayPanel); - onDisplayModeChanged(colDef, value, rowIx, colIx, isModelEditable, table); + onDisplayModeChanged(cellDataDialogState); } private void onScaleImageToPanelSize() @@ -132,28 +109,24 @@ private void onToggleSticky(boolean sticky) } } - private void onDisplayModeChanged(ColumnDisplayDefinition colDef, Object value, int row, int col, boolean isModelEditable, JTable table) + private void onDisplayModeChanged(CellDataDialogState cellDataDialogState) { CellDisplayPanelContent pnlToDisplay; if(DisplayMode.IMAGE == _cellDisplayPanel.getDisplayMode()) { - pnlToDisplay = new ResultImageDisplayPanel(colDef, - value, - isModelEditable, - row, - col, - () -> _cellDisplayPanel.getContentComponent().castToComponent().getSize(), - (DataSetViewerTable) table); + pnlToDisplay = new ResultImageDisplayPanel(cellDataDialogState, + () -> _cellDisplayPanel.getContentComponent().castToComponent().getSize() + ); } else { - CellDataColumnDataPanel cellDataPanel = new CellDataColumnDataPanel(value, colDef, isModelEditable); - cellDataPanel.setCellDataUpdateInfo(new CellDataUpdateInfo(row, col, table, this)); + CellDataColumnDataPanel cellDataPanel = new CellDataColumnDataPanel(cellDataDialogState.getValueToDisplay(), cellDataDialogState.getColDispDef(), cellDataDialogState.isEditable()); + cellDataPanel.setCellDataUpdateInfo(new CellDataUpdateInfo(cellDataDialogState, this)); pnlToDisplay = cellDataPanel; } - _cellDisplayPanel.setCurrentColumnDisplayDefinition(colDef); + _cellDisplayPanel.setCurrentColumnDisplayDefinition(cellDataDialogState.getColDispDef()); _cellDisplayPanel.setContentComponent(pnlToDisplay); _cellDisplayPanel.revalidate(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogEditableState.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogEditableState.java new file mode 100644 index 0000000000..5064c3f69d --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogEditableState.java @@ -0,0 +1,34 @@ +package net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup; + +import javax.swing.JTable; +import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; + +public class CellDataDialogEditableState +{ + private final JTable _table; + private final int _rowIx; + private final int _colIx; + + public CellDataDialogEditableState(JTable table, int rowIx, int colIx) + { + _table = table; + _rowIx = rowIx; + _colIx = colIx; + } + + + public int getRowIx() + { + return _rowIx; + } + + public int getColIx() + { + return _colIx; + } + + public DataSetViewerTable getDatasetViewerTable() + { + return (DataSetViewerTable) _table; + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogHandler.java index d7817ca61e..22d8d66bb7 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogHandler.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogHandler.java @@ -18,18 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; -import net.sourceforge.squirrel_sql.fw.datasetviewer.ExtTableColumn; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; -import net.sourceforge.squirrel_sql.fw.props.Props; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - -import javax.swing.CellEditor; -import javax.swing.JTable; -import javax.swing.SwingUtilities; -import javax.swing.table.TableColumn; import java.awt.Component; import java.awt.Dimension; import java.awt.Point; @@ -38,6 +26,17 @@ import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import javax.swing.CellEditor; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.TableColumn; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; +import net.sourceforge.squirrel_sql.fw.datasetviewer.ExtTableColumn; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.props.Props; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; /** * Generate a popup window to display and manipulate the @@ -116,7 +115,10 @@ public static void showSelectedValueInPinnedCellDataDialog(JTable table, boolean Object obj = table.getValueAt(selectedRow, selectedColumn); ColumnDisplayDefinition colDef = ((ExtTableColumn) column).getColumnDisplayDefinition(); - pinnedCellDataDialog.initCellDisplayPanel(table, table.getColumnName(selectedColumn), selectedRow, selectedColumn, colDef, obj, isModelEditable, true); + CellDataDialogState cellDataDialogState = + new CellDataDialogState(table.getColumnName(selectedColumn), colDef, obj, true, isModelEditable, table, selectedRow, selectedColumn); + + pinnedCellDataDialog.initCellDisplayPanel(cellDataDialogState); } @@ -130,7 +132,21 @@ private static void createAndShowCellDataDialog(JTable parentTable, boolean isModelEditable, MouseEvent evt) { - CellDataDialog cellDataDialog = new CellDataDialog(parentTable, columnName, rowIx, colIx, colDef, objectToDisplay, isModelEditable); + CellDataDialogState cellDataDialogState = + new CellDataDialogState(columnName, colDef, objectToDisplay, false, isModelEditable, parentTable, rowIx, colIx); + + createAndShowCellDataDialog(cellDataDialogState, SwingUtilities.windowForComponent(parentTable), evt); + } + + public static void createAndShowCellDataDialog(CellDataDialogState cellDataDialogState, Window parentWindow) + { + createAndShowCellDataDialog(cellDataDialogState, parentWindow, null); + } + + + public static void createAndShowCellDataDialog(CellDataDialogState cellDataDialogState, Window parentWindow, MouseEvent mouseEvent) + { + CellDataDialog cellDataDialog = new CellDataDialog(cellDataDialogState, parentWindow); cellDataDialog.pack(); @@ -162,16 +178,21 @@ private static void createAndShowCellDataDialog(JTable parentTable, } } - Window parentWindow = SwingUtilities.windowForComponent(parentTable); - Point dialogPos = parentWindow.getLocation(); - - dialogPos.x += SwingUtilities.convertPoint((Component) evt.getSource(), evt.getPoint(), parentWindow).x; - dialogPos.y += SwingUtilities.convertPoint((Component) evt.getSource(), evt.getPoint(), parentWindow).y; - - Rectangle dialogRect = GUIUtils.ensureBoundsOnOneScreen(new Rectangle(dialogPos.x, dialogPos.y, dim.width, dim.height)); + if(null != mouseEvent) + { + Point dialogPos = parentWindow.getLocation(); + dialogPos.x += SwingUtilities.convertPoint((Component) mouseEvent.getSource(), mouseEvent.getPoint(), parentWindow).x; + dialogPos.y += SwingUtilities.convertPoint((Component) mouseEvent.getSource(), mouseEvent.getPoint(), parentWindow).y; + Rectangle dialogRect = GUIUtils.ensureBoundsOnOneScreen(new Rectangle(dialogPos.x, dialogPos.y, dim.width, dim.height)); - cellDataDialog.setBounds(dialogRect); + cellDataDialog.setBounds(dialogRect); + } + else + { + cellDataDialog.setSize(dim); + GUIUtils.centerWithinParent(cellDataDialog); + } cellDataDialog.addWindowListener(new WindowAdapter() { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogState.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogState.java new file mode 100644 index 0000000000..f46c93743d --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataDialogState.java @@ -0,0 +1,75 @@ +package net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup; + +import java.sql.Types; +import javax.swing.JTable; +import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; + +public class CellDataDialogState +{ + private final String _columnName; + private final ColumnDisplayDefinition _colDef; + private final Object _valueToDisplay; + private final boolean _isModelEditable; + private final boolean _pinned; + private final CellDataDialogEditableState _cellDataDialogEditableState; + + public CellDataDialogState(String columnName, ColumnDisplayDefinition colDef, Object value, boolean pinned, boolean isModelEditable, JTable table, int rowIx, int colIx) + { + _columnName = columnName; + _colDef = colDef; + _valueToDisplay = value; + _isModelEditable = isModelEditable; + _pinned = pinned; + + _cellDataDialogEditableState = new CellDataDialogEditableState(table, rowIx, colIx); + } + + public CellDataDialogState(String dialogTitlePostfix, String value) + { + _columnName = dialogTitlePostfix; + _valueToDisplay = value; + + _colDef = new ColumnDisplayDefinition(100, dialogTitlePostfix); + _colDef.setSqlType(Types.VARCHAR); + _colDef.setSqlTypeName("VARCHAR"); + + _isModelEditable = false; + _pinned = false; + _cellDataDialogEditableState = null; + } + + public String getCellName() + { + return _columnName; + } + + public boolean isEditable() + { + return _isModelEditable; + } + + public ColumnDisplayDefinition getColDispDef() + { + return _colDef; + } + + public Object getValueToDisplay() + { + return _valueToDisplay; + } + + public boolean isPinned() + { + return _pinned; + } + + public CellDataDialogEditableState getEditableState() + { + if(false == isEditable()) + { + throw new IllegalStateException("Only to be called when updateable"); + } + + return _cellDataDialogEditableState; + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataUpdateInfo.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataUpdateInfo.java index 31ac5fa779..a5ff3b245d 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataUpdateInfo.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/CellDataUpdateInfo.java @@ -4,48 +4,44 @@ public class CellDataUpdateInfo { - private final int _row; - private final int _col; - private JTable _table; - private CellDataDialog _parentDialog; + private CellDataDialogState _cellDataDialogState; + private CellDataDialog _parentCellDataDialog; - public CellDataUpdateInfo(int row, int col, JTable table, CellDataDialog parentDialog) + public CellDataUpdateInfo(CellDataDialogState cellDataDialogState, CellDataDialog parentCellDataDialog) { - _row = row; - _col = col; - _table = table; - _parentDialog = parentDialog; + _cellDataDialogState = cellDataDialogState; + _parentCellDataDialog = parentCellDataDialog; } public int getRow() { - return _row; + return _cellDataDialogState.getEditableState().getRowIx(); } public int getCol() { - return _col; + return _cellDataDialogState.getEditableState().getColIx(); } public JTable getTable() { - return _table; + return _cellDataDialogState.getEditableState().getDatasetViewerTable(); } public void closeParentDialog() { - if(null == _parentDialog) + if(null == _parentCellDataDialog) { return; } - _parentDialog.setVisible(false); - _parentDialog.dispose(); + _parentCellDataDialog.setVisible(false); + _parentCellDataDialog.dispose(); } public void cleanUp() { - _parentDialog = null; - _table = null; + _parentCellDataDialog = null; + _cellDataDialogState = null; } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/DecodeSelection.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/DecodeSelection.java new file mode 100644 index 0000000000..154c55dcbc --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/DecodeSelection.java @@ -0,0 +1,92 @@ +package net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup; + +import java.nio.charset.StandardCharsets; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.RestorableRSyntaxTextArea; +import net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice.Base64DecodeHelper; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; +import net.sourceforge.squirrel_sql.fw.util.Utilities; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base32; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang3.StringUtils; + +public class DecodeSelection +{ + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(DecodeSelection.class); + + public static JMenu getParentMenu(RestorableRSyntaxTextArea textArea) + { + JMenu ret = new JMenu(s_stringMgr.getString("DecodeSelection.menu")); + ret.setToolTipText(s_stringMgr.getString("DecodeSelection.menu.tooltip")); + + JMenuItem menuItem; + + menuItem = new JMenuItem(s_stringMgr.getString("DecodeSelection.menu.item.decode.base64")); + menuItem.addActionListener(e -> decodeBase64(textArea)); + ret.add(menuItem); + + menuItem = new JMenuItem(s_stringMgr.getString("DecodeSelection.menu.item.decode.base32")); + menuItem.addActionListener(e -> decodeBase32(textArea)); + ret.add(menuItem); + + menuItem = new JMenuItem(s_stringMgr.getString("DecodeSelection.menu.item.decode.hex")); + menuItem.addActionListener(e -> decodeHex(textArea)); + ret.add(menuItem); + + return ret; + } + + private static void decodeHex(RestorableRSyntaxTextArea textArea) + { + try + { + String selectedText = textArea.getSelectedText(); + + if(StringUtils.isBlank(selectedText)) + { + Main.getApplication().getMessageHandler().showWarningMessage(s_stringMgr.getString("DecodeSelection.no.text.selected.to.decode")); + return; + } + + Main.getApplication().getMessageHandler().showMessage(new String(Hex.decodeHex(selectedText), StandardCharsets.UTF_8)); + } + catch(DecoderException e) + { + throw Utilities.wrapRuntime(e); + } + } + + private static void decodeBase32(RestorableRSyntaxTextArea textArea) + { + String selectedText = textArea.getSelectedText(); + + if(StringUtils.isBlank(selectedText)) + { + Main.getApplication().getMessageHandler().showWarningMessage(s_stringMgr.getString("DecodeSelection.no.text.selected.to.decode")); + return; + } + + Main.getApplication().getMessageHandler().showMessage(new String(new Base32().decode(selectedText), StandardCharsets.UTF_8)); + } + + private static void decodeBase64(RestorableRSyntaxTextArea textArea) + { + String selectedText = textArea.getSelectedText(); + + if(StringUtils.isBlank(selectedText)) + { + Main.getApplication().getMessageHandler().showWarningMessage(s_stringMgr.getString("DecodeSelection.no.text.selected.to.decode")); + return; + } + + Main.getApplication().getMessageHandler().showMessage( + new String(Base64DecodeHelper.decodeBase64OmittingInvalidBase64Chars(selectedText), StandardCharsets.UTF_8)); + + } + + +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/I18NStrings.properties index 2ad7968745..7373c9dae0 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/I18NStrings.properties @@ -75,4 +75,13 @@ popupEditableIoPanel.clipboard.vs.cell.data=Clipboard vs cell data PopupEditableIOPanel.no.word.wrap.without.line.wrap=Word wrap is -popupEditableIoPanel.cannot.update.binary.display.while.reformatted=Cannot update binary display while display is reformatted. \ No newline at end of file +popupEditableIoPanel.cannot.update.binary.display.while.reformatted=Cannot update binary display while display is reformatted. + +DecodeSelection.menu=Decode selection +DecodeSelection.menu.tooltip=Decode selected text to message panel + +DecodeSelection.menu.item.decode.base64=Decode Base64 to message panel +DecodeSelection.menu.item.decode.base32=Decode Base32 to message panel +DecodeSelection.menu.item.decode.hex=Decode HEX to message panel + +DecodeSelection.no.text.selected.to.decode=No text selected to decode diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/PopupEditableIOPanel.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/PopupEditableIOPanel.java index dc63bf3f9c..b6950aecbb 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/PopupEditableIOPanel.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/celldatapopup/PopupEditableIOPanel.java @@ -18,6 +18,33 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Path; +import java.sql.Types; +import java.util.Objects; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JToggleButton; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; import net.sourceforge.squirrel_sql.client.session.action.dbdiff.DBDIffService; @@ -44,34 +71,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JComboBox; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JToggleButton; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.file.Path; -import java.sql.Types; -import java.util.Objects; - /** * @author gwg * @@ -231,6 +230,7 @@ public PopupEditableIOPanel(ColumnDisplayDefinition colDef, Object value, boolea _popupMenu.add(_chkMnuWordWrap); _popupMenu.add(new XMLJsonReformatAction()); + _popupMenu.add(DecodeSelection.getParentMenu(_textArea)); _popupMenu.add(new CompareToClipAction()).setToolTipText(s_stringMgr.getString("popupEditableIoPanel.compare.to.clip.tooltip")); _popupMenu.setTextComponent(_textArea); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesChooserController.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesChooserController.java index 3f69398bd7..41b7d71afd 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesChooserController.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesChooserController.java @@ -1,30 +1,27 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.markduplicates; +import java.awt.event.ActionEvent; +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.JToggleButton; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; -import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.MarkDuplicatesToggleAction; -import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTablePanel; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; import net.sourceforge.squirrel_sql.fw.gui.buttonchooser.ButtonChooser; -import net.sourceforge.squirrel_sql.fw.gui.table.SortableTableModel; import net.sourceforge.squirrel_sql.fw.props.Props; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.AbstractButton; -import javax.swing.JComponent; -import javax.swing.JToggleButton; -import java.awt.event.ActionEvent; - public class MarkDuplicatesChooserController { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(MarkDuplicatesChooserController.class); - private final IDataSetViewer _sqlResultDataSetViewer; private ButtonChooser _toggleBtnChooser; private static final String PREF_MARK_DUPLICATES_MODE_LAST_MODE = "MarkDuplicatesMode.last.mode"; + private MarkDuplicatesStateHandler _markDuplicatesStateHandler = null; + private boolean _dontReactToEvents = false; @@ -40,23 +37,17 @@ public MarkDuplicatesChooserController(IResultTab resultTab) private MarkDuplicatesChooserController(IDataSetViewer dataSetViewer, IResultTab resultTab) { - _sqlResultDataSetViewer = dataSetViewer; _toggleBtnChooser = new ButtonChooser(); + _markDuplicatesStateHandler = new MarkDuplicatesStateHandler(e -> actionWasFired(e), + tableSortingAdmin -> onTableSorted(), + () -> onColumnMoved()); + + _markDuplicatesStateHandler.init(dataSetViewer, resultTab); + for (MarkDuplicatesMode mode : MarkDuplicatesMode.values()) { - JToggleButton btn; - if(null != resultTab) - { - // MarkDuplicatesToggleAction results in call of actionWasFired(...) - btn = new JToggleButton(new MarkDuplicatesToggleAction(resultTab)); - } - else - { - btn = new JToggleButton(); - btn.addActionListener(e -> actionWasFired(e)); - } - + JToggleButton btn = new JToggleButton(_markDuplicatesStateHandler.getAction()); btn.setIcon(mode.getIcon()); btn.setText(mode.getText()); btn.setToolTipText(mode.getToolTipText()); @@ -67,17 +58,6 @@ private MarkDuplicatesChooserController(IDataSetViewer dataSetViewer, IResultTab _toggleBtnChooser.setSelectedButton(getLastMode().findButton(_toggleBtnChooser)); _toggleBtnChooser.setButtonSelectedListener((newSelectedButton, formerSelectedButton) -> onButtonSelected((JToggleButton)newSelectedButton, (JToggleButton)formerSelectedButton)); - - if(_sqlResultDataSetViewer instanceof DataSetViewerTablePanel) - { - SortableTableModel sortableTableModel = ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getSortableTableModel(); - sortableTableModel.addSortingListener(tableSortingAdmin -> onTableSorted()); - } - - if(_sqlResultDataSetViewer instanceof DataSetViewerTablePanel) - { - ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getButtonTableHeader().setDraggedColumnListener(() -> onColumnMoved()); - } } private void onColumnMoved() @@ -190,7 +170,7 @@ public boolean actionWasFired(ActionEvent e) private void doMarkDuplicates() { - if(false == _sqlResultDataSetViewer instanceof DataSetViewerTablePanel) + if(false == _markDuplicatesStateHandler.hasDatasetViewerTablePanel()) { Main.getApplication().getMessageHandler().showWarningMessage(s_stringMgr.getString("MarkDuplicatesChooserController.mark.duplicates.for.table.output.only")); return; @@ -205,7 +185,7 @@ private void doMarkDuplicates() mode = MarkDuplicatesMode.getModeByButton(_toggleBtnChooser.getSelectedButton()); } - ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getColoringService().getMarkDuplicatesHandler().markDuplicates(mode); + _markDuplicatesStateHandler.markDuplicates(mode); } public void copyStateFrom(MarkDuplicatesChooserController controllerToCopyFrom) @@ -234,4 +214,12 @@ public void copyStateFrom(MarkDuplicatesChooserController controllerToCopyFrom) } } + public void init(IResultTab resultTab) + { + init(resultTab.getSQLResultDataSetViewer(), resultTab); + } + public void init(IDataSetViewer dataSetViewer, IResultTab resultTab) + { + _markDuplicatesStateHandler.init(dataSetViewer, resultTab); + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesStateHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesStateHandler.java new file mode 100644 index 0000000000..d28e70be3a --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/coloring/markduplicates/MarkDuplicatesStateHandler.java @@ -0,0 +1,103 @@ +package net.sourceforge.squirrel_sql.fw.datasetviewer.coloring.markduplicates; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.AbstractAction; +import javax.swing.Action; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; +import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.MarkDuplicatesToggleAction; +import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTablePanel; +import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.gui.table.ButtonTableHeaderColumnDragListener; +import net.sourceforge.squirrel_sql.fw.gui.table.SortableTableModel; +import net.sourceforge.squirrel_sql.fw.gui.table.SortingListener; + +public class MarkDuplicatesStateHandler +{ + private final ActionListener _noResultTabFallBackActionListener; + private final SortingListener _tableSortingListener; + private final ButtonTableHeaderColumnDragListener _buttonTableHeaderColumnDragListener; + private Action _actionProxy; + + private IDataSetViewer _sqlResultDataSetViewer; + private IResultTab _resultTab; + private MarkDuplicatesToggleAction _proxyDelegate; + + public MarkDuplicatesStateHandler(ActionListener noResultTabFallBackActionListener, + SortingListener tableSortingListener, + ButtonTableHeaderColumnDragListener buttonTableHeaderColumnDragListener) + { + _noResultTabFallBackActionListener = noResultTabFallBackActionListener; + _tableSortingListener = tableSortingListener; + _buttonTableHeaderColumnDragListener = buttonTableHeaderColumnDragListener; + + _actionProxy = new AbstractAction() + { + @Override + public void actionPerformed(ActionEvent e) + { + if(null == _proxyDelegate) + { + _noResultTabFallBackActionListener.actionPerformed(e); + } + else + { + _proxyDelegate.actionPerformed(e); + } + } + }; + + GUIUtils.copyAllActionProperties(Main.getApplication().getActionCollection().get(MarkDuplicatesToggleAction.class), _actionProxy); + } + + public Action getAction() + { + return _actionProxy; + } + + public void init(IDataSetViewer dataSetViewer, IResultTab resultTab) + { + _sqlResultDataSetViewer = dataSetViewer; + _resultTab = resultTab; + + _proxyDelegate = null; + if(null != _resultTab) + { + _proxyDelegate = new MarkDuplicatesToggleAction(_resultTab); + } + + if(null != _resultTab) + { + _sqlResultDataSetViewer = _resultTab.getSQLResultDataSetViewer(); + } + + if(_sqlResultDataSetViewer instanceof DataSetViewerTablePanel) + { + SortableTableModel sortableTableModel = ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getSortableTableModel(); + sortableTableModel.addSortingListener(_tableSortingListener); + } + + if(_sqlResultDataSetViewer instanceof DataSetViewerTablePanel) + { + ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getButtonTableHeader().addColumnDragListener(_buttonTableHeaderColumnDragListener); + } + } + + public boolean hasDatasetViewerTablePanel() + { + return _sqlResultDataSetViewer instanceof DataSetViewerTablePanel; + } + + /** + * Maybe should be moved to {@link MarkDuplicatesChooserController} + */ + public void markDuplicates(MarkDuplicatesMode mode) + { + if(hasDatasetViewerTablePanel()) + { + ((DataSetViewerTablePanel) _sqlResultDataSetViewer).getTable().getColoringService().getMarkDuplicatesHandler().markDuplicates(mode); + } + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultDataSetAndCellDetailDisplayHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultDataSetAndCellDetailDisplayHandler.java index 0ce27352c4..a7df7d59f5 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultDataSetAndCellDetailDisplayHandler.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultDataSetAndCellDetailDisplayHandler.java @@ -1,9 +1,16 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.beans.PropertyChangeEvent; +import javax.swing.BorderFactory; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTablePanel; import net.sourceforge.squirrel_sql.fw.datasetviewer.ExtTableColumn; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetViewer; import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataColumnDataPanel; +import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogState; import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataUpdateInfo; import net.sourceforge.squirrel_sql.fw.datasetviewer.tablefind.GlobalFindRemoteControl; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; @@ -11,13 +18,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.BorderFactory; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import java.awt.event.ComponentAdapter; -import java.awt.event.ComponentEvent; -import java.beans.PropertyChangeEvent; - public class ResultDataSetAndCellDetailDisplayHandler { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ResultDataSetAndCellDetailDisplayHandler.class); @@ -137,20 +137,19 @@ private void onRowColSelectionChanged(DataSetViewerTablePanel dataSetViewer, boo _rightCellDisplayPanel.setCurrentColumnDisplayDefinition(column.getColumnDisplayDefinition()); CellDisplayPanelContent pnlToDisplay; + + CellDataDialogState cellDataDialogState = new CellDataDialogState(column.getColumnDisplayDefinition().getColumnName(), column.getColumnDisplayDefinition(), value, false, dataSetViewer.isTableEditable(), dataSetViewer.getTable(), + rowLeadSelectionIndex, + colLeadSelectionIndex + ); if(DisplayMode.IMAGE == _rightCellDisplayPanel.getDisplayMode()) { - pnlToDisplay = new ResultImageDisplayPanel(column.getColumnDisplayDefinition(), - value, - dataSetViewer.isTableEditable(), - rowLeadSelectionIndex, - colLeadSelectionIndex, - () -> _rightCellDisplayPanel.getContentComponent().castToComponent().getSize(), - dataSetViewer.getTable()); + pnlToDisplay = new ResultImageDisplayPanel(cellDataDialogState, () -> _rightCellDisplayPanel.getContentComponent().castToComponent().getSize()); } else { CellDataColumnDataPanel panel = new CellDataColumnDataPanel(value, column.getColumnDisplayDefinition(), dataSetViewer.isTableEditable()); - panel.setCellDataUpdateInfo(new CellDataUpdateInfo(rowLeadSelectionIndex, colLeadSelectionIndex, dataSetViewer.getTable(), null)); + panel.setCellDataUpdateInfo(new CellDataUpdateInfo(cellDataDialogState, null)); pnlToDisplay = panel; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultImageDisplayPanel.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultImageDisplayPanel.java index 81d7a53bb1..6251968aa3 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultImageDisplayPanel.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ResultImageDisplayPanel.java @@ -23,7 +23,6 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingConstants; - import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.dnd.DropedFileExtractor; import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; @@ -33,6 +32,7 @@ import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.ClobDescriptor; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.DataTypeBlobProperties; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.DataTypeClobProperties; +import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogState; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; import net.sourceforge.squirrel_sql.fw.util.StringManager; @@ -52,23 +52,17 @@ public class ResultImageDisplayPanel extends JPanel implements CellDisplayPanelC private BufferedImage _image; - public ResultImageDisplayPanel(ColumnDisplayDefinition cdd, - Object valueToDisplay, - boolean tableEditable, - int selRow, - int selCol, - ImageContainerSizeProvider imageContainerSizeProvider, - DataSetViewerTable table) + public ResultImageDisplayPanel(CellDataDialogState cellDataDialogState, ImageContainerSizeProvider imageContainerSizeProvider) { _imageContainerSizeProvider = imageContainerSizeProvider; setLayout(new BorderLayout(3,3)); add(_scrImage, BorderLayout.CENTER); - updateImageDisplay(cdd, valueToDisplay); + updateImageDisplay(cellDataDialogState.getColDispDef(), cellDataDialogState.getValueToDisplay()); - if(tableEditable) + if(cellDataDialogState.isEditable()) { - add(createUpdatePanel(selRow, selCol, table, cdd), BorderLayout.SOUTH); + add(createUpdatePanel(cellDataDialogState), BorderLayout.SOUTH); } } @@ -77,7 +71,7 @@ private void updateImageDisplay(ColumnDisplayDefinition cdd, Object valueToDispl _scrImage.setViewportView(getDisplayComponent(cdd, valueToDisplay)); } - private JPanel createUpdatePanel(int selRow, int selCol, DataSetViewerTable table, ColumnDisplayDefinition cdd) + private JPanel createUpdatePanel(CellDataDialogState state) { JPanel ret = new JPanel(new BorderLayout(0,3)); @@ -89,7 +83,11 @@ private JPanel createUpdatePanel(int selRow, int selCol, DataSetViewerTable tabl @Override public void drop(DropTargetDropEvent dtde) { - onDrop(dtde, selRow, selCol, table, cdd); + onDrop(dtde, + state.getEditableState().getRowIx(), + state.getEditableState().getColIx(), + state.getEditableState().getDatasetViewerTable(), + state.getColDispDef()); } }); @@ -103,7 +101,12 @@ public void drop(DropTargetDropEvent dtde) JButton btnDel = new JButton(Main.getApplication().getResources().getIcon(SquirrelResources.IImageNames.DELETE)); btnDel.setToolTipText(s_stringMgr.getString("ResultImageDisplayPanel.delete.image.from.database.tooltip")); - btnDel.addActionListener(e -> onDelete(selRow, selCol, table, cdd)); + + btnDel.addActionListener(e -> onDelete(state.getEditableState().getRowIx(), + state.getEditableState().getColIx(), + state.getEditableState().getDatasetViewerTable(), + state.getColDispDef())); + ret.add(GUIUtils.styleAsToolbarButton(btnDel), BorderLayout.EAST); return ret; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ShowCellDetailCtrl.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ShowCellDetailCtrl.java index e1eb7cbd97..22a3409f9e 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ShowCellDetailCtrl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/datasetviewer/columndisplaychoice/ShowCellDetailCtrl.java @@ -1,15 +1,15 @@ package net.sourceforge.squirrel_sql.fw.datasetviewer.columndisplaychoice; +import javax.swing.JToggleButton; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; +import net.sourceforge.squirrel_sql.client.session.mainpanel.IResultTab; import net.sourceforge.squirrel_sql.client.session.mainpanel.ResultTab; import net.sourceforge.squirrel_sql.client.session.mainpanel.resulttabactions.ResultTabProvider; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.JToggleButton; - public class ShowCellDetailCtrl { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ShowCellDetailCtrl.class); @@ -60,11 +60,21 @@ else if(false == selectedTabsDisplayHandler.getCellDetailDisplayAvailableInfo(). public void finishedCreatingResultTab() { - ResultDataSetAndCellDetailDisplayHandler selectedTabsDisplayHandler = _resultTabProvider.getResultTab().getSelectedResultTabsDisplayHandler(); - if(null != selectedTabsDisplayHandler) + IResultTab resultTab = _resultTabProvider.getResultTab(); + + if(null == resultTab) { - selectedTabsDisplayHandler.setCloseListener(() -> onClosedByPanelButton()); + return; } + + ResultDataSetAndCellDetailDisplayHandler selectedResultTabsDisplayHandler = resultTab.getSelectedResultTabsDisplayHandler(); + + if(null == selectedResultTabsDisplayHandler) + { + return; + } + + selectedResultTabsDisplayHandler.setCloseListener(() -> onClosedByPanelButton()); } private void onClosedByPanelButton() diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/ColumnsMonospacedCommand.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/ColumnsMonospacedCommand.java new file mode 100644 index 0000000000..7fd278cd5e --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/ColumnsMonospacedCommand.java @@ -0,0 +1,21 @@ +package net.sourceforge.squirrel_sql.fw.gui; + +import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; + +public class ColumnsMonospacedCommand +{ + private final DataSetViewerTable _table; + + public ColumnsMonospacedCommand(DataSetViewerTable table) + { + _table = table; + } + + public void execute() + { + int[] selectedColumns = _table.getSelectedColumns(); + + _table.getFontService().toggleMonoSpaced(selectedColumns); + + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/GUIUtils.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/GUIUtils.java index 8e0df75adb..b0e8fd000c 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/GUIUtils.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/GUIUtils.java @@ -18,44 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget; -import net.sourceforge.squirrel_sql.fw.props.Props; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import net.sourceforge.squirrel_sql.fw.util.Utilities; -import net.sourceforge.squirrel_sql.fw.util.log.ILogger; -import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import org.apache.commons.lang3.StringUtils; - -import javax.swing.AbstractAction; -import javax.swing.AbstractButton; -import javax.swing.BorderFactory; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JInternalFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSeparator; -import javax.swing.JTabbedPane; -import javax.swing.JTable; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.JToggleButton; -import javax.swing.JTree; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.ToolTipManager; -import javax.swing.plaf.TextUI; -import javax.swing.text.BadLocationException; -import javax.swing.text.Position; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -96,6 +58,45 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSeparator; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.JTree; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.ToolTipManager; +import javax.swing.plaf.TextUI; +import javax.swing.text.BadLocationException; +import javax.swing.text.Position; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget; +import net.sourceforge.squirrel_sql.fw.props.Props; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; +import net.sourceforge.squirrel_sql.fw.util.Utilities; +import net.sourceforge.squirrel_sql.fw.util.log.ILogger; +import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; +import org.apache.commons.lang3.StringUtils; /** * Common GUI utilities accessed via static methods. @@ -1385,4 +1386,34 @@ public static BufferedImage scaleImage(BufferedImage originalImage, int newWidth return scaledImage; } + + public static void unconventionallyAddToParentWithRepaint(JPanel parent, JComponent child) + { + JFrame f = new JFrame(); + f.getContentPane().setLayout(new GridLayout(1,1)); + f.getContentPane().add(child); + f.setSize(5,5); + //f.setVisible(true); + + SwingUtilities.invokeLater(() -> + { + f.setVisible(false); + f.getContentPane().remove(child); + f.dispose(); + parent.add(child); + parent.doLayout(); + }); + } + + public static void copyAllActionProperties(Action from, Action to) + { + to.putValue(Action.NAME, from.getValue(Action.NAME)); + to.putValue(Action.ACTION_COMMAND_KEY, from.getValue(Action.ACTION_COMMAND_KEY)); + to.putValue(Action.SMALL_ICON, from.getValue(Action.SMALL_ICON)); + to.putValue(Action.LARGE_ICON_KEY, from.getValue(Action.LARGE_ICON_KEY)); + to.putValue(Action.MNEMONIC_KEY, from.getValue(Action.MNEMONIC_KEY)); + to.putValue(Action.ACCELERATOR_KEY, from.getValue(Action.ACCELERATOR_KEY)); + to.putValue(Action.SHORT_DESCRIPTION, from.getValue(Action.SHORT_DESCRIPTION)); + to.putValue(Action.LONG_DESCRIPTION, from.getValue(Action.LONG_DESCRIPTION)); + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/I18NStrings.properties index afebf00130..5e7bbaa6f3 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/I18NStrings.properties @@ -78,6 +78,7 @@ TablePopupMenu.ColorSelectedRows=Color selected rows TablePopupMenu.ColorSelectedCells=Color selected cells TablePopupMenu.GotoColor=Go to color TablePopupMenu.CopyColoredRowsToNewWindow=Copy colored rows to new window +TablePopupMenu.ToggleColumnsMonospaced=Toggle selected columns monospaced ChooserPreviewer.errorReadingFile=Error reading file {0}: {1} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/TablePopupMenu.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/TablePopupMenu.java index 8ae8233a8a..97f6256f0c 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/TablePopupMenu.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/TablePopupMenu.java @@ -18,10 +18,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Component; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.awt.print.PrinterJob; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.SQLExecutionInfo; import net.sourceforge.squirrel_sql.client.session.action.dbdiff.tableselectiondiff.TableSelectionDiff; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTablePanel; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSetUpdateableModel; @@ -60,18 +72,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import org.apache.commons.lang3.time.StopWatch; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JComponent; -import javax.swing.JFrame; -import javax.swing.JMenuItem; -import javax.swing.KeyStroke; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.MouseEvent; -import java.awt.print.PrinterJob; - public class TablePopupMenu extends BasePopupMenu { @@ -106,6 +106,8 @@ public class TablePopupMenu extends BasePopupMenu private GotoColorMenuController _gotoColorMenuController = new GotoColorMenuController(); private CopyColoredRowsToNewWindowAction _copyColoredRowsToNewWindow = new CopyColoredRowsToNewWindowAction(); + private ToggleColumnsMonospacedAction _toggleColumnsMonospaced = new ToggleColumnsMonospacedAction(); + private ExportAction _export; private AdjustAllColWidthsAction _adjustAllColWidthsAction = new AdjustAllColWidthsAction(); private AlwaysAdjustAllColWidthsAction _alwaysAdjustAllColWidthsAction = new AlwaysAdjustAllColWidthsAction(); @@ -190,6 +192,8 @@ public TablePopupMenu(boolean allowEditing, add(_copyColoredRowsToNewWindow); addSeparator(); + add(_toggleColumnsMonospaced); + addSeparator(); _export = new ExportAction(DataSetViewerTablePanel.getDataModelImplementationDetails().getSQLExecutionInfo()); addAction(_export); @@ -245,7 +249,7 @@ public TablePopupMenu(boolean allowEditing, private void addMenuItem(JMenuItem menuItem) { String actionName = menuItem.getText(); - KeyStroke validKeyStroke = Main.getApplication().getShortcutManager().setAccelerator(menuItem, null, actionName); + KeyStroke validKeyStroke = Main.getApplication().getShortcutManager().setAccelerator(menuItem, null, actionName, ShortCutDescriptionReader.of(menuItem)); add(menuItem); if (null != validKeyStroke) @@ -272,7 +276,7 @@ private void addAction(Action action) private void addAction(Action action, KeyStroke defaultKeyStroke) { JMenuItem mnuAdded = add(action); - KeyStroke validKeyStroke = Main.getApplication().getShortcutManager().setAccelerator(mnuAdded, defaultKeyStroke, action); + KeyStroke validKeyStroke = Main.getApplication().getShortcutManager().setAccelerator(mnuAdded, defaultKeyStroke, action, ShortCutDescriptionReader.of(action)); ResourceUtil.trySetToolTip(mnuAdded, action); if (null != validKeyStroke) @@ -611,6 +615,19 @@ public void actionPerformed(ActionEvent evt) } } + private class ToggleColumnsMonospacedAction extends BaseAction + { + ToggleColumnsMonospacedAction() + { + super(s_stringMgr.getString("TablePopupMenu.ToggleColumnsMonospaced")); + } + + public void actionPerformed(ActionEvent evt) + { + new ColumnsMonospacedCommand(_dataSetViewerTablePanel.getTable()).execute(); + } + } + private class AdjustAllColWidthsAction extends BaseAction { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByCtrl.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByCtrl.java index 5dbe57abdb..861758cb3c 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByCtrl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByCtrl.java @@ -1,126 +1,150 @@ package net.sourceforge.squirrel_sql.fw.gui.action.copyseparatedby; +import javax.swing.JOptionPane; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.props.Props; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - -import javax.swing.JOptionPane; +import org.apache.commons.lang3.StringUtils; public class CopySeparatedByCtrl { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(CopySeparatedByCtrl.class); + public static final String DEFAULT_CELL_SEPARATOR = ","; + private static final String PREF_KEY_COPYSEPARATEDBYCTRL_CELL_SEPARATOR = "Squirrel.copyseparatedbyctrl.cell.separator"; + private static final String PREF_KEY_JUST_CONCAT_CELLS = "Squirrel.copyseparatedbyctrl.just.concat.cells"; private static final String PREF_KEY_COPYSEPARATEDBYCTRL_CELL_DELIMITER = "Squirrel.copyseparatedbyctrl.cell.delimiter"; private static final String PREF_KEY_COPYSEPARATEDBYCTRL_INCLUDE_HEADERS = "Squirrel.copyseparatedbyctrl.include.headers"; private static final String PREF_KEY_COPYSEPARATEDBYCTRL_ROW_SEPARATOR = "Squirrel.copyseparatedbyctrl.row.separator"; private static final String PREF_KEY_COPYSEPARATEDBYCTRL_ROW_PREFERED_LINE_LEN = "Squirrel.copyseparatedbyctrl.prefered.line.len"; - private CopySeparatedByDlg _copySeparatedByDlg; + private CopySeparatedByDlg _dlg; private boolean _enableRowSeparator; private String _cellSeparator = ""; + private boolean _justConcatCells; private String _cellDelimiter = ""; private boolean _includeHeaders; private String _rowSeparator = ""; private int _preferredLineLength; private boolean _isOk; + private boolean _inCellDataPopup; public CopySeparatedByCtrl(DataSetViewerTable table, boolean enableRowSeparator) { - _copySeparatedByDlg = new CopySeparatedByDlg(GUIUtils.getOwningFrame(table)); + _dlg = new CopySeparatedByDlg(GUIUtils.getOwningFrame(table)); _enableRowSeparator = enableRowSeparator; - _copySeparatedByDlg.txtCellSeparator.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_SEPARATOR, ",")); - _copySeparatedByDlg.txtCellDelimiter.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_DELIMITER, "")); + _dlg.txtCellSeparator.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_SEPARATOR, DEFAULT_CELL_SEPARATOR)); + _dlg.txtCellDelimiter.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_DELIMITER, "")); + + _dlg.txtLineLength.setInt(Props.getInt(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_PREFERED_LINE_LEN, 100)); + _dlg.txtRowSeparator.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_SEPARATOR, "\\n")); - _copySeparatedByDlg.txtLineLength.setInt(Props.getInt(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_PREFERED_LINE_LEN, 100)); - _copySeparatedByDlg.txtRowSeparator.setText(Props.getString(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_SEPARATOR, "\\n")); + _dlg.chkIncludeHeaders.setSelected(Props.getBoolean(PREF_KEY_COPYSEPARATEDBYCTRL_INCLUDE_HEADERS, false)); + _dlg.chkIncludeHeaders.addActionListener(e -> updateEnabled()); - _copySeparatedByDlg.chkIncludeHeaders.setSelected(Props.getBoolean(PREF_KEY_COPYSEPARATEDBYCTRL_INCLUDE_HEADERS, false)); + _dlg.chkJustConcatCells.setSelected(Props.getBoolean(PREF_KEY_JUST_CONCAT_CELLS, false)); + _dlg.chkJustConcatCells.addActionListener(e -> updateEnabled()); - _copySeparatedByDlg.chkIncludeHeaders.addActionListener(e -> updateEnabled()); updateEnabled(); - _copySeparatedByDlg.btnOk.addActionListener(e -> onOk()); - _copySeparatedByDlg.btnCancel.addActionListener(e -> onCancel()); + _dlg.btnOk.addActionListener(e -> onOk()); + _dlg.btnCancel.addActionListener(e -> onCancel()); + _dlg.btnInCellDataPopup.addActionListener(e -> onInCellDataPopup()); - GUIUtils.forceFocus(_copySeparatedByDlg.txtCellSeparator); + GUIUtils.forceFocus(_dlg.txtCellSeparator); - _copySeparatedByDlg.setVisible(true); + _dlg.setVisible(true); } private void updateEnabled() { - _copySeparatedByDlg.txtRowSeparator.setEnabled(true); - _copySeparatedByDlg._lblRowSeparator.setEnabled(true); + _dlg.txtCellSeparator.setEnabled(!_dlg.chkJustConcatCells.isSelected()); + _dlg.lblCellSeparator.setEnabled(!_dlg.chkJustConcatCells.isSelected()); + + _dlg.txtRowSeparator.setEnabled(true); + _dlg.lblRowSeparator.setEnabled(true); - _copySeparatedByDlg.txtLineLength.setEnabled(true); - _copySeparatedByDlg.lblPreferredLineLength.setEnabled(true); + _dlg.txtLineLength.setEnabled(true); + _dlg.lblPreferredLineLength.setEnabled(true); - if(false == _enableRowSeparator || _copySeparatedByDlg.chkIncludeHeaders.isSelected()) + if(false == _enableRowSeparator || _dlg.chkIncludeHeaders.isSelected()) { - _copySeparatedByDlg.txtRowSeparator.setEnabled(false); - _copySeparatedByDlg._lblRowSeparator.setEnabled(false); + _dlg.txtRowSeparator.setEnabled(false); + _dlg.lblRowSeparator.setEnabled(false); //_copySeparatedByDlg.txtRowSeparator.setText(null); } - if(_copySeparatedByDlg.chkIncludeHeaders.isSelected()) + if( _dlg.chkIncludeHeaders.isSelected()) { - _copySeparatedByDlg.txtLineLength.setEnabled(false); - _copySeparatedByDlg.lblPreferredLineLength.setEnabled(false); + _dlg.txtLineLength.setEnabled(false); + _dlg.lblPreferredLineLength.setEnabled(false); } } private void onCancel() { - _copySeparatedByDlg.setVisible(false); - _copySeparatedByDlg.dispose(); + _dlg.setVisible(false); + _dlg.dispose(); } + private void onInCellDataPopup() + { + onOk(); + + if(_isOk) + { + _inCellDataPopup = true; + } + } + + + private void onOk() { - if(0 >= _copySeparatedByDlg.txtLineLength.getInt()) + if( 0 > _dlg.txtLineLength.getInt()) { - JOptionPane.showConfirmDialog(_copySeparatedByDlg, s_stringMgr.getString("CopySeparatedByCtrl.invalid.line.length")); + JOptionPane.showConfirmDialog(_dlg, s_stringMgr.getString("CopySeparatedByCtrl.invalid.line.length")); return; } - - String text = ""; - if (null != _copySeparatedByDlg.txtCellSeparator.getText()) + String text = DEFAULT_CELL_SEPARATOR; + if ( null != _dlg.txtCellSeparator.getText()) { - text = _copySeparatedByDlg.txtCellSeparator.getText(); + text = _dlg.txtCellSeparator.getText(); } Props.putString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_SEPARATOR, text); _cellSeparator = doReplacements(text); + Props.putBoolean(PREF_KEY_JUST_CONCAT_CELLS, _dlg.chkJustConcatCells.isSelected()); + _justConcatCells = _dlg.chkJustConcatCells.isSelected(); String cellDelim = ""; - if (null != _copySeparatedByDlg.txtCellDelimiter.getText()) + if(false == StringUtils.isBlank(_dlg.txtCellDelimiter.getText())) { - cellDelim = _copySeparatedByDlg.txtCellDelimiter.getText(); + cellDelim = _dlg.txtCellDelimiter.getText(); } Props.putString(PREF_KEY_COPYSEPARATEDBYCTRL_CELL_DELIMITER, cellDelim); _cellDelimiter = cellDelim; + Props.putBoolean(PREF_KEY_COPYSEPARATEDBYCTRL_INCLUDE_HEADERS, _dlg.chkIncludeHeaders.isSelected()); + _includeHeaders = _dlg.chkIncludeHeaders.isSelected(); - Props.putBoolean(PREF_KEY_COPYSEPARATEDBYCTRL_INCLUDE_HEADERS, _copySeparatedByDlg.chkIncludeHeaders.isSelected()); - _includeHeaders = _copySeparatedByDlg.chkIncludeHeaders.isSelected(); - - Props.putInt(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_PREFERED_LINE_LEN, _copySeparatedByDlg.txtLineLength.getInt()); - _preferredLineLength = _copySeparatedByDlg.txtLineLength.getInt(); + Props.putInt(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_PREFERED_LINE_LEN, _dlg.txtLineLength.getInt()); + _preferredLineLength = _dlg.txtLineLength.getInt(); - if(_enableRowSeparator && null != _copySeparatedByDlg.txtRowSeparator.getText()) + if(_enableRowSeparator && null != _dlg.txtRowSeparator.getText()) { text = "\\n"; - if (null != _copySeparatedByDlg.txtRowSeparator.getText()) + if ( null != _dlg.txtRowSeparator.getText()) { - text = _copySeparatedByDlg.txtRowSeparator.getText(); + text = _dlg.txtRowSeparator.getText(); } Props.putString(PREF_KEY_COPYSEPARATEDBYCTRL_ROW_SEPARATOR, text); @@ -130,8 +154,8 @@ private void onOk() _isOk = true; - _copySeparatedByDlg.setVisible(false); - _copySeparatedByDlg.dispose(); + _dlg.setVisible(false); + _dlg.dispose(); } private String doReplacements(String text) @@ -145,6 +169,10 @@ public String getCellSeparator() return _cellSeparator; } + public boolean isJustConcatCells() + { + return _justConcatCells; + } public String getRowSeparator() { @@ -170,4 +198,9 @@ public boolean isOk() { return _isOk; } + + public boolean isInCellDataPopup() + { + return _inCellDataPopup; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByDlg.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByDlg.java index 2b586fe1bb..57cea64e0a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByDlg.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/CopySeparatedByDlg.java @@ -1,42 +1,44 @@ package net.sourceforge.squirrel_sql.fw.gui.action.copyseparatedby; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; -import net.sourceforge.squirrel_sql.fw.gui.IntegerField; -import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; -import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.SmallToolTipInfoButton; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; -import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.gui.IntegerField; +import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; +import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.SmallToolTipInfoButton; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; public class CopySeparatedByDlg extends JDialog { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(CopySeparatedByDlg.class); + JLabel lblCellSeparator = new JLabel(s_stringMgr.getString("CopySeparatedByDlg.cell.separator")); JTextField txtCellSeparator = new JTextField(); + JCheckBox chkJustConcatCells = new JCheckBox(s_stringMgr.getString("CopySeparatedByDlg.justConcat.cells")); + JTextField txtCellDelimiter = new JTextField(); JCheckBox chkIncludeHeaders = new JCheckBox(s_stringMgr.getString("CopySeparatedByDlg.include.column.headers")); - JLabel _lblRowSeparator = new JLabel(s_stringMgr.getString("CopySeparatedByDlg.row.separator")); + JLabel lblRowSeparator = new JLabel(s_stringMgr.getString("CopySeparatedByDlg.row.separator")); JTextField txtRowSeparator = new JTextField(); JLabel lblPreferredLineLength = new JLabel(s_stringMgr.getString("CopySeparatedByDlg.prefered.line.length")); - IntegerField txtLineLength = new IntegerField(6); + IntegerField txtLineLength = new IntegerField(8); JButton btnOk = new JButton(s_stringMgr.getString("CopySeparatedByDlg.cell.ok")); JButton btnCancel = new JButton(s_stringMgr.getString("CopySeparatedByDlg.cell.cancel")); + JButton btnInCellDataPopup = new JButton(s_stringMgr.getString("CopySeparatedByDlg.cell.show.in.cell.data.popup")); public CopySeparatedByDlg(Frame owningFrame) @@ -53,8 +55,8 @@ public CopySeparatedByDlg(Frame owningFrame) gbc = new GridBagConstraints(0, 1 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0,5,5,5), 0,0); getContentPane().add(createControlsPanel(), gbc); - gbc = new GridBagConstraints(0, 2 , 1, 1, 0,1, GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(0,5,5,5), 0,0); - getContentPane().add(createButtoPanel(), gbc); + gbc = new GridBagConstraints(0, 2 , 1, 1, 0,1, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0,5,5,5), 0,0); + getContentPane().add(createButtonPanel(), gbc); setSize(350, 350); @@ -65,7 +67,7 @@ public CopySeparatedByDlg(Frame owningFrame) getRootPane().setDefaultButton(btnOk); } - private JPanel createButtoPanel() + private JPanel createButtonPanel() { JPanel ret = new JPanel(new GridBagLayout()); @@ -77,6 +79,11 @@ private JPanel createButtoPanel() gbc = new GridBagConstraints(1, 0 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); ret.add(btnCancel, gbc); + gbc = new GridBagConstraints(2, 0 , 1, 1, 1,0, GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(5,0,5,5), 0,0); + ret.add(new JPanel(), gbc); + + gbc = new GridBagConstraints(3, 0 , 1, 1, 0,0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5,0,5,5), 0,0); + ret.add(btnInCellDataPopup, gbc); return ret; } @@ -87,40 +94,45 @@ private JPanel createControlsPanel() GridBagConstraints gbc; - gbc = new GridBagConstraints(0, 0 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); - ret.add(new JLabel(s_stringMgr.getString("CopySeparatedByDlg.cell.separator")), gbc); + gbc = new GridBagConstraints(0, 0 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,0), 0,0); + ret.add(lblCellSeparator, gbc); - gbc = new GridBagConstraints(1, 0 , 1, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,5,5), 0,0); - //txtCellSeparator.setPreferredSize(new Dimension(70, txtCellSeparator.getPreferredSize().height)); + gbc = new GridBagConstraints(1, 0 , 1, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,0,5), 0,0); ret.add(txtCellSeparator, gbc); - gbc = new GridBagConstraints(0, 1 , 1, 1, 0,0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); + gbc = new GridBagConstraints(0, 1 , 2, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,20,0,0), 0,0); + ret.add(chkJustConcatCells, gbc); + + + gbc = new GridBagConstraints(0, 2 , 1, 1, 0,0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(15,5,0,5), 0,0); ret.add(createCellDelimiterLabelPanel(), gbc); - gbc = new GridBagConstraints(1, 1 , 1, 1, 1,0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,5,5), 0,0); + gbc = new GridBagConstraints(1, 2 , 1, 1, 1,0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15,5,0,5), 0,0); ret.add(txtCellDelimiter, gbc); - gbc = new GridBagConstraints(0, 2 , 2, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(15,5,0,5), 0,0); + + gbc = new GridBagConstraints(0, 3 , 2, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(15,5,0,5), 0,0); ret.add(GUIUtils.createHorizontalSeparatorPanel(), gbc); - gbc = new GridBagConstraints(0, 3 , 2, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,5,5), 0,0); + gbc = new GridBagConstraints(0, 4 , 2, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,0,5), 0,0); ret.add(chkIncludeHeaders, gbc); - gbc = new GridBagConstraints(0, 4 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); - ret.add(_lblRowSeparator, gbc); + gbc = new GridBagConstraints(0, 5 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,0), 0,0); + ret.add(lblRowSeparator, gbc); - gbc = new GridBagConstraints(1, 4 , 1, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,5,5), 0,0); + gbc = new GridBagConstraints(1, 5 , 1, 1, 1,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5,5,0,5), 0,0); //txtRowSeparator.setPreferredSize(new Dimension(70, txtRowSeparator.getPreferredSize().height)); ret.add(txtRowSeparator, gbc); - gbc = new GridBagConstraints(0, 5 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); - ret.add(lblPreferredLineLength, gbc); + gbc = new GridBagConstraints(0, 6 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,0), 0,0); + ret.add(createPreferredLineLengthLabelPanel(), gbc); - gbc = new GridBagConstraints(1, 5 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0,0); - txtLineLength.setPreferredSize(new Dimension(70, txtLineLength.getPreferredSize().height)); + gbc = new GridBagConstraints(1, 6 , 1, 1, 0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5,5,0,5), 0,0); + GUIUtils.setPreferredWidth(txtLineLength, 100); + GUIUtils.setMinimumWidth(txtLineLength, 100); ret.add(txtLineLength, gbc); @@ -141,4 +153,12 @@ private JPanel createCellDelimiterLabelPanel() return ret; } + + private JPanel createPreferredLineLengthLabelPanel() + { + JPanel ret = new JPanel(new BorderLayout()); + ret.add(lblPreferredLineLength, BorderLayout.CENTER); + ret.add(new SmallToolTipInfoButton(s_stringMgr.getString("CopySeparatedByDlg.preferred.line.length.info")).getButton(), BorderLayout.EAST); + return ret; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/I18NStrings.properties index ba75cdacb6..c1f96c7702 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/I18NStrings.properties @@ -18,4 +18,11 @@ CopySeparatedByDlg.description=Configure separators for cells and rows. If the s CopySeparatedByDlg.prefered.line.length=Preferred line length -CopySeparatedByCtrl.invalid.line.length=Please enter a valid line length. \ No newline at end of file +CopySeparatedByCtrl.invalid.line.length=Please enter a valid line length. +CopySeparatedByDlg.preferred.line.length.info=0 means no line length limit. + +CopySeparatedByDlg.justConcat.cells=Just concatenate cell values + +CopySeparatedByDlg.cell.show.in.cell.data.popup=To cell data popup + +TableCopySeparatedByCommand.cell.data.dialog.title="Copy result" \ No newline at end of file diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/TableCopySeparatedByCommand.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/TableCopySeparatedByCommand.java index 6ad71e117f..20abd9b532 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/TableCopySeparatedByCommand.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/copyseparatedby/TableCopySeparatedByCommand.java @@ -2,7 +2,10 @@ import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetViewerTable; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.BaseDataTypeComponent; +import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogHandler; +import net.sourceforge.squirrel_sql.fw.datasetviewer.celldatapopup.CellDataDialogState; import net.sourceforge.squirrel_sql.fw.gui.ClipboardUtil; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.StringUtilities; @@ -32,6 +35,11 @@ public void execute() String cellSeparator = copySeparatedByCtrl.getCellSeparator(); + if(copySeparatedByCtrl.isJustConcatCells()) + { + cellSeparator = ""; + } + String rowSeparator = "\n"; if(false == copySeparatedByCtrl.isIncludeHeaders()) @@ -47,8 +55,6 @@ public void execute() int preferredLineLength = copySeparatedByCtrl.getPreferredLineLength(); - - int nbrSelRows = _table.getSelectedRowCount(); int[] selRows = _table.getSelectedRows(); int[] selCols = _table.getSelectedColumns(); @@ -93,7 +99,9 @@ public void execute() { sb.append(cellSeparator); - if(false == copySeparatedByCtrl.isIncludeHeaders() && preferredLineLength < getDistToLastNewLine(sb)) + if( false == copySeparatedByCtrl.isIncludeHeaders() + && 0 < preferredLineLength + && preferredLineLength < getDistToLastNewLine(sb)) { sb.append("\n"); } @@ -107,10 +115,13 @@ public void execute() } } - if(cellObj instanceof String && -1 < ((String)cellObj).indexOf('\n')) + if( false == copySeparatedByCtrl.isJustConcatCells() + && cellObj instanceof String cellStr + && -1 < indexOfFirstLineBreakChar(cellStr) ) { - int lineBreakPos = ((String)cellObj).indexOf('\n'); - sb.append(wrapCellDelimiter(cellObj, copySeparatedByCtrl.getCellDelimiter()), 0, lineBreakPos); + int lineBreakPos = indexOfFirstLineBreakChar(cellStr); + cellStr = cellStr.substring(0, lineBreakPos); + sb.append(wrapCellDelimiter(cellStr, copySeparatedByCtrl.getCellDelimiter())); } else if(null == cellObj) { @@ -123,7 +134,38 @@ else if(null == cellObj) } } - ClipboardUtil.copyToClip(sb); + if(copySeparatedByCtrl.isInCellDataPopup()) + { + CellDataDialogState cellDataDialogState = + new CellDataDialogState(s_stringMgr.getString("TableCopySeparatedByCommand.cell.data.dialog.title"), sb.toString()); + + CellDataDialogHandler.createAndShowCellDataDialog(cellDataDialogState, GUIUtils.getOwningWindow(_table)); + } + else + { + ClipboardUtil.copyToClip(sb); + } + } + + private static int indexOfFirstLineBreakChar(String cellStr) + { + int indexOfNewLine = cellStr.indexOf('\n'); + int indexOfCarriageReturn = cellStr.indexOf('\r'); + + if(-1 == indexOfNewLine && -1 == indexOfCarriageReturn) + { + return -1; + } + else if(-1 == indexOfNewLine) + { + return indexOfCarriageReturn; + } + else if(-1 == indexOfCarriageReturn) + { + return indexOfNewLine; + } + + return Math.min(indexOfCarriageReturn, indexOfNewLine); } private String wrapCellDelimiter(Object cellContent, String cellDelimiter) diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/DataExportExcelWriter.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/DataExportExcelWriter.java index d09de721ab..0bfec0b37a 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/DataExportExcelWriter.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/DataExportExcelWriter.java @@ -18,6 +18,14 @@ */ package net.sourceforge.squirrel_sql.fw.gui.action.fileexport; +import java.io.File; +import java.io.FileOutputStream; +import java.sql.Types; +import java.text.NumberFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.CellComponentFactory; import net.sourceforge.squirrel_sql.fw.sql.ProgressAbortCallback; @@ -34,15 +42,6 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import java.io.File; -import java.io.FileOutputStream; -import java.sql.Types; -import java.text.NumberFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; - /** * Exports {@link IExportData} to a Excel file. * Note: This class is the result of a refactoring task. The code was @@ -80,7 +79,7 @@ public long write(ExportDataInfoList exportDataInfoList, TableExportPreferences for (ExportDataInfo exportDataInfo : exportDataInfoList.getExportDataInfos()) { - _sheet = _workbook.createSheet(exportDataInfo.getExcelSheetTabName()); + _sheet = ExcelSheetReplaceUtil.getOrCreateSheet(_workbook, exportDataInfo.getExcelSheetTabName(prefs), prefs); rowsCount += _writeExcelTab(exportDataInfo.getExportData()); @@ -96,7 +95,7 @@ public long write(ExportDataInfoList exportDataInfoList, TableExportPreferences if(prefs.isExcelExportSQLStatementInAdditionalSheet()) { - ExcelSQLStatementSheet.createSqlStatementSheet(exportDataInfo, _workbook); + ExcelSQLStatementSheet.createSqlStatementSheet(exportDataInfo, _workbook, prefs); } } _fileExportService.progress(s_stringMgr.getString("DataExportExcelWriter.finishedLoading", NumberFormat.getInstance().format(rowsCount))); @@ -280,20 +279,28 @@ private String getDataXLSAsString(Object cellObj) private void beforeWorking() { + _workbook = ExcelSheetReplaceUtil.getExistingWorkBookOrNull(_fileExportService); + + if(null != _workbook) + { + return; + } + + if (_fileExportService.getPrefs().isFormatXLSOld()) { - this._workbook = new HSSFWorkbook(); // See https://gist.github.com/madan712/3912272 + _workbook = new HSSFWorkbook(); // See https://gist.github.com/madan712/3912272 } else { if(_fileExportService.getPrefs().isUseColoring()) { // See class ExcelCellColorer on how this will take care the Excel gets colored. - this._workbook = new XSSFWorkbook(); + _workbook = new XSSFWorkbook(); } else { - this._workbook = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk + _workbook = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk } } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSQLStatementSheet.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSQLStatementSheet.java index d2a3c0b428..89d83c1c9d 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSQLStatementSheet.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSQLStatementSheet.java @@ -12,16 +12,14 @@ public class ExcelSQLStatementSheet { - public static void createSqlStatementSheet(ExportDataInfo exportDataInfo, Workbook workbook) + public static void createSqlStatementSheet(ExportDataInfo exportDataInfo, Workbook workbook, TableExportPreferences prefs) { if(StringUtilities.isEmpty(exportDataInfo.getSqlToWriteToFile(), true)) { return; } - String sqlStatementTabName = getUniqueSqlSheetName(workbook, exportDataInfo.getExcelSheetTabName(), 0); - - Sheet sheet = workbook.createSheet(sqlStatementTabName); + Sheet sheet = getOrCreateSqlStatementSheet(exportDataInfo, workbook, prefs); Row row = sheet.createRow(0); // Does not work @@ -40,9 +38,24 @@ public static void createSqlStatementSheet(ExportDataInfo exportDataInfo, Workbo cell.setCellStyle(cellStyle); } + private static Sheet getOrCreateSqlStatementSheet(ExportDataInfo exportDataInfo, Workbook workbook, TableExportPreferences prefs) + { + if(ExcelSheetReplaceUtil.isReplaceExcelSheets(prefs)) + { + String sqlStatementTabName = getInitialCandidateSqlSheetName(exportDataInfo.getExcelSheetTabName(prefs)); + return ExcelSheetReplaceUtil.getOrCreateSheet(workbook, sqlStatementTabName, prefs); + } + else + { + String sqlStatementTabName = getUniqueSqlSheetName(workbook, exportDataInfo.getExcelSheetTabName(prefs), 0); + Sheet sheet = workbook.createSheet(sqlStatementTabName); + return sheet; + } + } + private static String getUniqueSqlSheetName(Workbook workbook, String excelSheetTabName, int numberToCheck) { - String candidate = excelSheetTabName + "_SQL"; + String candidate = getInitialCandidateSqlSheetName(excelSheetTabName); if(numberToCheck > 0) { @@ -60,4 +73,9 @@ private static String getUniqueSqlSheetName(Workbook workbook, String excelSheet return candidate; } + + private static String getInitialCandidateSqlSheetName(String excelSheetTabName) + { + return excelSheetTabName + "_SQL"; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSheetReplaceUtil.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSheetReplaceUtil.java new file mode 100644 index 0000000000..7c121dc787 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExcelSheetReplaceUtil.java @@ -0,0 +1,83 @@ +package net.sourceforge.squirrel_sql.fw.gui.action.fileexport; + +import java.io.FileInputStream; +import java.io.IOException; +import net.sourceforge.squirrel_sql.fw.util.log.ILogger; +import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; + +public class ExcelSheetReplaceUtil +{ + private static final ILogger s_log = LoggerController.createLogger(ExcelSheetReplaceUtil.class); + + + public static Sheet getOrCreateSheet(Workbook workbook, String excelSheetTabName, TableExportPreferences prefs) + { + if(false == isReplaceExcelSheets(prefs)) + { + return workbook.createSheet(excelSheetTabName); + } + + Sheet sheet = workbook.getSheet(excelSheetTabName); + if(null == sheet) + { + return workbook.createSheet(excelSheetTabName); + } + + // AI: Clear existing contents + for(int rowIndex = sheet.getLastRowNum(); rowIndex >= 0; rowIndex--) + { + Row row = sheet.getRow(rowIndex); + if(row != null) + { + sheet.removeRow(row); + } + } + + return sheet; + + } + + + public static boolean isReplaceExcelSheets(TableExportPreferences prefs) + { + return prefs.isExcelReplaceSheets(); + } + + public static Workbook getExistingWorkBookOrNull(FileExportService fileExportService) + { + if(false == isReplaceExcelSheets(fileExportService.getPrefs())) + { + return null; + } + + + if(!hasExcelExtension(fileExportService.getFile().getAbsolutePath())) + { + return null; // Quick check by extension + } + + try(FileInputStream fis = new FileInputStream(fileExportService.getFile())) + { + Workbook workbook = WorkbookFactory.create(fis); // Will throw exception if not valid + return workbook; + } + catch(IOException e) + { + s_log.warn("File to replace sheet(s) in is not an MSExcelFile", e); + return null; + } + } + + /** + * AI: Method to check by extension + */ + public static boolean hasExcelExtension(String filePath) + { + return StringUtils.endsWithIgnoreCase(filePath,".xls") || StringUtils.endsWithIgnoreCase(filePath,".xlsx"); + } +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportController.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportController.java index 7a4601209e..eec4b0d89c 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportController.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportController.java @@ -1,5 +1,16 @@ package net.sourceforge.squirrel_sql.fw.gui.action.fileexport; +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import net.sourceforge.squirrel_sql.fw.gui.EditableComboBoxHandler; import net.sourceforge.squirrel_sql.fw.gui.FontChooser; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; @@ -8,18 +19,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringUtilities; import org.apache.commons.lang3.StringUtils; -import javax.swing.JFileChooser; -import javax.swing.JOptionPane; -import javax.swing.SwingUtilities; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.Font; -import java.awt.Toolkit; -import java.awt.Window; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.io.File; - public class ExportController { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ExportController.class); @@ -190,8 +189,11 @@ private void onFormat(boolean replaceEnding) _dlg.btnChooseExcelFont.setEnabled(false); _dlg.btnChooseExcelHeaderFont.setEnabled(false); _dlg.lblExcelFontName.setEnabled(false); + _dlg.lblExcelSheetName.setEnabled(false); + _dlg.txtExcelSheetName.setEnabled(false); _dlg.lblExcelHeaderFontName.setEnabled(false); _dlg.chkExcelExportSQLStatementInAdditionalSheet.setEnabled(false); + _dlg.chkExcelReplaceSheets.setEnabled(false); if(_dlg.chkSeparatorTab.isSelected()) @@ -231,7 +233,10 @@ else if (_dlg.radFormatXLSX.isSelected() || _dlg.radFormatXLS.isSelected()) _dlg.btnChooseExcelHeaderFont.setEnabled(true); _dlg.lblExcelFontName.setEnabled(true); _dlg.lblExcelHeaderFontName.setEnabled(true); + _dlg.lblExcelSheetName.setEnabled(true); + _dlg.txtExcelSheetName.setEnabled(true); _dlg.chkExcelExportSQLStatementInAdditionalSheet.setEnabled(true); + _dlg.chkExcelReplaceSheets.setEnabled(true); if(replaceEnding) { @@ -258,7 +263,10 @@ else if (_dlg.radFormatXML.isSelected() || _dlg.radFormatJSON.isSelected()) _dlg.btnChooseExcelHeaderFont.setEnabled(false); _dlg.lblExcelFontName.setEnabled(false); _dlg.lblExcelHeaderFontName.setEnabled(false); + _dlg.lblExcelSheetName.setEnabled(false); + _dlg.txtExcelSheetName.setEnabled(false); _dlg.chkExcelExportSQLStatementInAdditionalSheet.setEnabled(false); + _dlg.chkExcelReplaceSheets.setEnabled(false); if(replaceEnding) @@ -444,8 +452,12 @@ private void onOK() && false == isExportingMultipleFiles() // For now in case of multiple export files these files will be replaced silently. ) { - // i18n[TableExportCsvController.replaceFile=The export file already exisits. Would you like to replace it?] String msg = s_stringMgr.getString("TableExportCsvController.replaceFile"); + if(isExcelWithReplaceSheets()) + { + msg = s_stringMgr.getString("TableExportCsvController.add.or.replace.excel.sheet"); + } + if(JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(_dlg, msg)) { return; @@ -460,6 +472,11 @@ private void onOK() closeDlg(); } + private boolean isExcelWithReplaceSheets() + { + return (_dlg.radFormatXLSX.isSelected() || _dlg.radFormatXLS.isSelected()) && _dlg.chkExcelReplaceSheets.isSelected(); + } + private boolean isExportingMultipleFiles() { return _exportSelectionPanelController.isExportMultipleSQLResults() @@ -503,7 +520,9 @@ private void writeControlsToPrefs(TableExportPreferences prefs) prefs.setExcelFirstRowFrozen(_dlg.chkExcelFirstRowFrozen.isSelected()); prefs.setExcelFirstRowCentered(_dlg.chkExcelFirstRowCentered.isSelected()); prefs.setExcelFirstRowBold(_dlg.chkExcelFirstRowBold.isSelected()); + prefs.setExcelSheetNameFileNormalized(StringUtilities.fileNameNormalize(StringUtilities.emptyToNull(_dlg.txtExcelSheetName.getText()), true)); prefs.setExcelExportSQLStatementInAdditionalSheet(_dlg.chkExcelExportSQLStatementInAdditionalSheet.isSelected()); + prefs.setExcelReplaceSheets(_dlg.chkExcelReplaceSheets.isSelected()); _excelFontCtrl.writeToPrefs(prefs); @@ -545,7 +564,9 @@ private void initData() _dlg.chkExcelFirstRowFrozen.setSelected(prefs.isExcelFirstRowFrozen()); _dlg.chkExcelFirstRowCentered.setSelected(prefs.isExcelFirstRowCentered()); _dlg.chkExcelFirstRowBold.setSelected(prefs.isExcelFirstRowBold()); + _dlg.txtExcelSheetName.setText(prefs.getExcelSheetNameFileNormalized()); _dlg.chkExcelExportSQLStatementInAdditionalSheet.setSelected(prefs.isExcelExportSQLStatementInAdditionalSheet()); + _dlg.chkExcelReplaceSheets.setSelected(prefs.isExcelReplaceSheets()); _dlg.cboCharsets.setSelectedItem(prefs.getEncoding()); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDataInfo.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDataInfo.java index de39305773..34aa62e5cd 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDataInfo.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDataInfo.java @@ -1,8 +1,7 @@ package net.sourceforge.squirrel_sql.fw.gui.action.fileexport; -import net.sourceforge.squirrel_sql.fw.util.StringUtilities; - import java.io.File; +import net.sourceforge.squirrel_sql.fw.util.StringUtilities; public class ExportDataInfo { @@ -50,27 +49,20 @@ public File getFile(TableExportPreferences prefs) } } - public String getExcelSheetTabName() + public String getExcelSheetTabName(TableExportPreferences prefs) { - if(StringUtilities.isEmpty(_exportNameFileNormalized, true)) + if(false == StringUtilities.isEmpty(_exportNameFileNormalized, true)) { - return DataExportExcelWriter.DEFAULT_EXCEL_EXPORT_SHEET_NAME; + return _exportNameFileNormalized; } - else + else if(false == StringUtilities.isEmpty(prefs.getExcelSheetNameFileNormalized())) { - return _exportNameFileNormalized; + return prefs.getExcelSheetNameFileNormalized(); } - - } - - public ResultSetExportData getResultSetExportData() - { - if(_exportData instanceof ResultSetExportData ret) + else { - return ret; + return DataExportExcelWriter.DEFAULT_EXCEL_EXPORT_SHEET_NAME; } - - return null; } public String getSqlToWriteToFile() diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDlg.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDlg.java index dce04b336c..8561c28012 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDlg.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/ExportDlg.java @@ -1,14 +1,16 @@ package net.sourceforge.squirrel_sql.fw.gui.action.fileexport; -import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; -import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; -import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.SmallToolTipInfoButton; -import net.sourceforge.squirrel_sql.fw.resources.LibraryResources; -import net.sourceforge.squirrel_sql.fw.util.StringManager; -import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; - +import java.awt.Component; +import java.awt.Cursor; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.Window; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.nio.charset.Charset; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; @@ -21,17 +23,13 @@ import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ScrollPaneConstants; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.GridLayout; -import java.awt.Insets; -import java.awt.Window; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.nio.charset.Charset; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; +import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel; +import net.sourceforge.squirrel_sql.fw.gui.buttontabcomponent.SmallToolTipInfoButton; +import net.sourceforge.squirrel_sql.fw.resources.LibraryResources; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; public class ExportDlg extends JDialog { @@ -57,7 +55,11 @@ public class ExportDlg extends JDialog JButton btnChooseExcelHeaderFont; MultipleLineLabel lblExcelHeaderFontName; + JLabel lblExcelSheetName; + JTextField txtExcelSheetName; + JCheckBox chkExcelExportSQLStatementInAdditionalSheet; + JCheckBox chkExcelReplaceSheets; JRadioButton radFormatXML; JRadioButton radFormatJSON; @@ -245,21 +247,53 @@ private JPanel createExcelOptionsPanel() gbc = new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 3, 3, 0), 0, 0); ret.add(createFontPanel(), gbc); - gbc = new GridBagConstraints(0, 2, GridBagConstraints.REMAINDER, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 3, 3, 0), 0, 0); - ret.add(createSQLStatementInAdditionalSheetPanel(), gbc); + gbc = new GridBagConstraints(0, 2, GridBagConstraints.REMAINDER, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 3, 3, 0), 0, 0); + ret.add(createSheetNamePanel(), gbc); + + gbc = new GridBagConstraints(0, 3, GridBagConstraints.REMAINDER, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 3, 3, 0), 0, 0); + ret.add(createExcelSectionLowerCheckboxes(), gbc); + + return ret; + } + + private JPanel createSheetNamePanel() + { + JPanel ret = new JPanel(new GridBagLayout()); + + GridBagConstraints gbc; + + gbc = new GridBagConstraints(0,0,1,1,0,0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); + lblExcelSheetName = new JLabel(s_stringMgr.getString("TableExportCsvDlg.lbl.sheet.name")); + ret.add(lblExcelSheetName, gbc); + + gbc = new GridBagConstraints(1,0,1,1,1,0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,5,0,60), 0,0); + txtExcelSheetName = new JTextField(); + ret.add(txtExcelSheetName, gbc); return ret; } - private JPanel createSQLStatementInAdditionalSheetPanel() + private JPanel createExcelSectionLowerCheckboxes() { - JPanel ret = new JPanel(new BorderLayout()); + JPanel ret = new JPanel(new GridBagLayout()); + + GridBagConstraints gbc; + gbc = new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); chkExcelExportSQLStatementInAdditionalSheet = new JCheckBox(s_stringMgr.getString("TableExportCsvDlg.excel.SQL.in.extra.sheet")); - ret.add(chkExcelExportSQLStatementInAdditionalSheet, BorderLayout.CENTER); + ret.add(chkExcelExportSQLStatementInAdditionalSheet, gbc); + + gbc = new GridBagConstraints(1,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); + SmallToolTipInfoButton btnInfoSql = new SmallToolTipInfoButton(s_stringMgr.getString("TableExportCsvDlg.excel.SQL.in.extra.sheet.infoButton")); + ret.add(btnInfoSql.getButton(), gbc); + + gbc = new GridBagConstraints(2,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,20,0,0), 0,0); + chkExcelReplaceSheets = new JCheckBox(s_stringMgr.getString("TableExportCsvDlg.excel.replace.sheets")); + ret.add(chkExcelReplaceSheets, gbc); - SmallToolTipInfoButton btnInfo = new SmallToolTipInfoButton(s_stringMgr.getString("TableExportCsvDlg.excel.SQL.in.extra.sheet.infoButton")); - ret.add(btnInfo.getButton(), BorderLayout.EAST); + gbc = new GridBagConstraints(3,0,1,1,0,0,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0); + SmallToolTipInfoButton btnInfoReplace = new SmallToolTipInfoButton(s_stringMgr.getString("TableExportCsvDlg.excel.replace.sheets.infoButton")); + ret.add(btnInfoReplace.getButton(), gbc); return ret; } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/I18NStrings.properties b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/I18NStrings.properties index b62157613e..5bc116db08 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/I18NStrings.properties +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/I18NStrings.properties @@ -39,6 +39,7 @@ TableExportCsvController.noFile=You must provide an export file name. TableExportCsvController.noCommand=You must provide a command string or uncheck "Execute command". TableExportCsvController.invalidSeparator=You must provide a single separator character or check "Use tab" to use the tab character. TableExportCsvController.replaceFile=The export file already exists. Would you like to replace it? +TableExportCsvController.add.or.replace.excel.sheet=The Excel file to export to already exists. Would you like to add or replace sheets in the file? TableExportCsvController.fileChooserTilte=Choose export file TableExportCsvCommand.failedToWriteFile=Failed to write file\n{0}\nError message:\n{1}\nSee last log entry for details. TableExportCsvCommand.failedToExecuteCommand=Failed to execute\n{0}\nError message:\n{1}\nSee last log entry for details. @@ -202,4 +203,13 @@ TableExportCsvDlg.excel.SQL.in.extra.sheet.infoButton=Applies to MS Excel data may be incomplete or changed as compared to the SQL result.

\ On direct SQL exports: To do direct SQL exports you may right mouse click an SQL statement or hit Ctrl+T --> sql2file
\ or check the multiple sheet export explained in the "About Exporting" link at the bottom of the export dialog.\ - \ No newline at end of file + + + +TableExportCsvDlg.excel.replace.sheets=Update existing Excel file +TableExportCsvDlg.excel.replace.sheets.infoButton=When the Excel file to export to already exists then this option, instead of replacing the complete Excel file,
\ + will add or update sheet(s) in the existing file. + +TableExportCsvDlg.lbl.sheet.name=Sheet name + + diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferences.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferences.java index 8394ea2884..8410441222 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferences.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferences.java @@ -77,6 +77,8 @@ public class TableExportPreferences private boolean _excelHeaderFontBold; private boolean _excelHeaderFontItalic; private boolean _excelExportSQLStatementInAdditionalSheet; + private String _excelSheetNameFileNormalized; + private boolean _excelReplaceSheets; public boolean isFormatXLS() { @@ -426,4 +428,24 @@ public void setExcelExportSQLStatementInAdditionalSheet(boolean excelExportSQLSt { _excelExportSQLStatementInAdditionalSheet = excelExportSQLStatementInAdditionalSheet; } + + public void setExcelSheetNameFileNormalized(String excelSheetNameFileNormalized) + { + _excelSheetNameFileNormalized = excelSheetNameFileNormalized; + } + + public String getExcelSheetNameFileNormalized() + { + return _excelSheetNameFileNormalized; + } + + public void setExcelReplaceSheets(boolean excelReplaceSheets) + { + _excelReplaceSheets = excelReplaceSheets; + } + + public boolean isExcelReplaceSheets() + { + return _excelReplaceSheets; + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferencesDAO.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferencesDAO.java index 3f09788272..6de58f0f8f 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferencesDAO.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/action/fileexport/TableExportPreferencesDAO.java @@ -37,6 +37,8 @@ public class TableExportPreferencesDAO private static final String PREF_KEY_EXCEL_HEADER_FONT_BOLD = "SQuirrelSQL.csvexport.excelHeaderFontBold"; private static final String PREF_KEY_EXCEL_HEADER_FONT_ITALIC = "SQuirrelSQL.csvexport.excelHeaderFontItalic"; private static final String PREF_KEY_EXCEL_SQL_STATEMENT_IN_ADDITIONAL_SHEET = "SQuirrelSQL.csvexport.excelExportSQLStatementInAdditionalSheet"; + private static final String PREF_KEY_EXCEL_SHEET_NAME_FILE_NORMALIZED = "SQuirrelSQL.csvexport.excelSheetNameFileNormalized"; + private static final String PREF_KEY_EXCEL_REPLACE_SHEETS = "SQuirrelSQL.csvexport.excelReplaceSheets"; private static final String PREF_KEY_FORMAT_XML = "SquirrelSQL.csvexport.formatXML"; private static final String PREF_KEY_FORMAT_JSON = "SquirrelSQL.csvexport.formatJSON"; @@ -71,6 +73,8 @@ public static TableExportPreferences loadPreferences() ret.setExcelFirstRowBold(Props.getBoolean(PREF_KEY_EXCEL_FIRST_ROW_BOLD, ret.isExcelFirstRowBold())); ret.setExcelFirstRowCentered(Props.getBoolean(PREF_KEY_EXCEL_FIRST_ROW_CENTERED, ret.isExcelFirstRowCentered())); ret.setExcelExportSQLStatementInAdditionalSheet(Props.getBoolean(PREF_KEY_EXCEL_SQL_STATEMENT_IN_ADDITIONAL_SHEET, ret.isExcelExportSQLStatementInAdditionalSheet())); + ret.setExcelSheetNameFileNormalized(Props.getString(PREF_KEY_EXCEL_SHEET_NAME_FILE_NORMALIZED, ret.getExcelSheetNameFileNormalized())); + ret.setExcelReplaceSheets(Props.getBoolean(PREF_KEY_EXCEL_REPLACE_SHEETS, ret.isExcelReplaceSheets())); ret.setExcelFontNoSelection(Props.getBoolean(PREF_KEY_EXCEL_FONT_NO_SELECTION, ret.isExcelFontNoSelection())); ret.setExcelFontFamily(Props.getString(PREF_KEY_EXCEL_FONT_FAMILY, ret.getExcelFontFamily())); @@ -127,6 +131,8 @@ public static void savePreferences(TableExportPreferences prefs) Props.putBoolean(PREF_KEY_EXCEL_HEADER_FONT_BOLD, prefs.isExcelHeaderFontBold()); Props.putBoolean(PREF_KEY_EXCEL_HEADER_FONT_ITALIC, prefs.isExcelHeaderFontItalic()); Props.putBoolean(PREF_KEY_EXCEL_SQL_STATEMENT_IN_ADDITIONAL_SHEET, prefs.isExcelExportSQLStatementInAdditionalSheet()); + Props.putString(PREF_KEY_EXCEL_SHEET_NAME_FILE_NORMALIZED, prefs.getExcelSheetNameFileNormalized()); + Props.putBoolean(PREF_KEY_EXCEL_REPLACE_SHEETS, prefs.isExcelReplaceSheets()); Props.putBoolean(PREF_KEY_FORMAT_XML, prefs.isFormatXML()); Props.putBoolean(PREF_KEY_FORMAT_JSON, prefs.isFormatJSON()); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/buttonchooser/ButtonChooser.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/buttonchooser/ButtonChooser.java index 5ce03c8b8c..14b5cf1b14 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/buttonchooser/ButtonChooser.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/buttonchooser/ButtonChooser.java @@ -1,9 +1,12 @@ package net.sourceforge.squirrel_sql.fw.gui.buttonchooser; -import net.sourceforge.squirrel_sql.client.Main; -import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; - +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.ImageIcon; @@ -13,13 +16,9 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JToolBar; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.stream.Collectors; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.client.resources.SquirrelResources; +import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; /** * Behaves like a ComboBox with buttons in it. @@ -277,4 +276,16 @@ public void setPreferredHeight(int height) { GUIUtils.setPreferredHeight(_container, height); } + + public void replaceButtonsBy(List newButtons) + { + if(newButtons.isEmpty()) + { + throw new IllegalStateException("newButtons cannot be empty"); + } + + _buttons.clear(); + newButtons.forEach(b -> addButton(b)); + setSelectedButton(newButtons.get(newButtons.size() - 1)); + } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/stdtextpopup/TextActionHelper.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/stdtextpopup/TextActionHelper.java index 64837fc8be..3b83fb73e2 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/stdtextpopup/TextActionHelper.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/stdtextpopup/TextActionHelper.java @@ -1,10 +1,10 @@ package net.sourceforge.squirrel_sql.fw.gui.stdtextpopup; -import net.sourceforge.squirrel_sql.client.Main; - import javax.swing.Action; import javax.swing.KeyStroke; import javax.swing.text.JTextComponent; +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; public class TextActionHelper { @@ -36,6 +36,6 @@ public void initKeyStroke(JTextComponent comp) public static KeyStroke getKeyStroke(String defaultEditorKitActionName, KeyStroke defaultKeyStroke) { - return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(defaultEditorKitActionName, defaultKeyStroke)); + return KeyStroke.getKeyStroke(Main.getApplication().getShortcutManager().registerAccelerator(defaultEditorKitActionName, defaultKeyStroke, ShortCutDescriptionReader.of())); } } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeader.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeader.java index 509d2c1a2f..d988cefca1 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeader.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeader.java @@ -18,6 +18,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Component; +import java.awt.Cursor; +import java.awt.FontMetrics; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.event.TableModelListener; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.fw.datasetviewer.RowNumberTableColumn; import net.sourceforge.squirrel_sql.fw.datasetviewer.cellcomponent.SquirrelTableCellRenderer; @@ -26,18 +42,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.*; -import javax.swing.event.TableModelListener; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; -import javax.swing.table.TableModel; -import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseMotionListener; -import java.awt.geom.Rectangle2D; - public class ButtonTableHeader extends JTableHeader { private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ButtonTableHeader.class); @@ -54,7 +58,7 @@ public class ButtonTableHeader extends JTableHeader private TableAccessForHeader _tableAccess; - private ButtonTableHeaderDraggedColumnListener _buttonTableHeaderDraggedColumnListener; + private java.util.List _buttonTableHeaderDragListeners = new ArrayList<>(); /** * Constructor for ButtonTableHeader. @@ -284,9 +288,15 @@ private void adjustColWidth(int colIx, boolean includeColHeaders) } - public void setDraggedColumnListener(ButtonTableHeaderDraggedColumnListener buttonTableHeaderDraggedColumnListener) + public void addColumnDragListener(ButtonTableHeaderColumnDragListener buttonTableHeaderColumnDragListener) + { + _buttonTableHeaderDragListeners.remove(buttonTableHeaderColumnDragListener); + _buttonTableHeaderDragListeners.add(buttonTableHeaderColumnDragListener); + } + + public void removeColumnDragListener(ButtonTableHeaderColumnDragListener buttonTableHeaderColumnDragListener) { - _buttonTableHeaderDraggedColumnListener = buttonTableHeaderDraggedColumnListener; + _buttonTableHeaderDragListeners.remove(buttonTableHeaderColumnDragListener); } class HeaderListener extends MouseAdapter implements MouseMotionListener @@ -376,9 +386,9 @@ public void mouseReleased(MouseEvent e) } else { - if(null != _buttonTableHeaderDraggedColumnListener) + for(ButtonTableHeaderColumnDragListener l : _buttonTableHeaderDragListeners.toArray(new ButtonTableHeaderColumnDragListener[0])) { - _buttonTableHeaderDraggedColumnListener.columnDragged(); + l.columnDragged(); } } _mouseState.setDragged(false); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderColumnDragListener.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderColumnDragListener.java new file mode 100644 index 0000000000..b1a9c4f025 --- /dev/null +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderColumnDragListener.java @@ -0,0 +1,7 @@ +package net.sourceforge.squirrel_sql.fw.gui.table; + +@FunctionalInterface +public interface ButtonTableHeaderColumnDragListener +{ + void columnDragged(); +} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderDraggedColumnListener.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderDraggedColumnListener.java deleted file mode 100644 index 88183060c6..0000000000 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/gui/table/ButtonTableHeaderDraggedColumnListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sourceforge.squirrel_sql.fw.gui.table; - -@FunctionalInterface -public interface ButtonTableHeaderDraggedColumnListener -{ - public void columnDragged(); -} diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/resources/Resources.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/resources/Resources.java index ba4f9f5d5e..405ee3811c 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/resources/Resources.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/resources/Resources.java @@ -19,6 +19,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.net.URL; +import java.util.MissingResourceException; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.KeyStroke; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.shortcut.ShortCutReader; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; @@ -28,10 +38,7 @@ import net.sourceforge.squirrel_sql.fw.util.Utilities; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; - -import javax.swing.*; -import java.net.URL; -import java.util.MissingResourceException; +import org.apache.commons.lang3.StringUtils; public abstract class Resources implements IResources { @@ -304,6 +311,30 @@ public String getActionName(Class actionClass) return getResourceString(getActionKey(actionClass), ActionProperties.NAME); } + public String getTooltipFromResource(Class actionClass) + { + String ret = getResourceString(getActionKey(actionClass), ActionProperties.TOOLTIP); + if(false == StringUtils.isBlank(ret)) + { + return ret; + } + + return null; + } + + public String getTooltipFromResource(String fullResourceString) + { + String ret = getResourceString(fullResourceString, ActionProperties.TOOLTIP); + + if(false == StringUtils.isBlank(ret)) + { + return ret; + } + + return null; + } + + private String getActionKey(Class actionClass) { final String actionClassName = actionClass.getName(); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/ProcedureAndFunctionMetaData.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/ProcedureAndFunctionMetaData.java index c9b1ff76f4..7a94d37db6 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/ProcedureAndFunctionMetaData.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/ProcedureAndFunctionMetaData.java @@ -1,18 +1,21 @@ package net.sourceforge.squirrel_sql.fw.sql.databasemetadata; -import net.sourceforge.squirrel_sql.fw.datasetviewer.BlockMode; -import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory; -import net.sourceforge.squirrel_sql.fw.dialects.DialectType; -import net.sourceforge.squirrel_sql.fw.sql.*; -import net.sourceforge.squirrel_sql.fw.util.log.ILogger; -import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; - import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import net.sourceforge.squirrel_sql.fw.datasetviewer.BlockMode; +import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory; +import net.sourceforge.squirrel_sql.fw.dialects.DialectType; +import net.sourceforge.squirrel_sql.fw.sql.IProcedureInfo; +import net.sourceforge.squirrel_sql.fw.sql.ProcedureInfo; +import net.sourceforge.squirrel_sql.fw.sql.ProgressCallBack; +import net.sourceforge.squirrel_sql.fw.sql.ResultSetReader; +import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities; +import net.sourceforge.squirrel_sql.fw.util.log.ILogger; +import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; public class ProcedureAndFunctionMetaData { @@ -30,7 +33,7 @@ static List getProcedureInfos(String catalog, String schemaPatte int count = 0; try { - final int[] cols = new int[] + final int[] columnsToReadFomMetaDataResult = new int[] { 1, // PROCEDURE_CAT 2, // PROCEDURE_SCHEM @@ -40,7 +43,7 @@ static List getProcedureInfos(String catalog, String schemaPatte }; DialectType dialectType = DialectFactory.getDialectType(md); - final ResultSetReader rdr = new ResultSetReader(rs, cols, dialectType); + final ResultSetReader rdr = new ResultSetReader(rs, columnsToReadFomMetaDataResult, dialectType); Object[] row; while ((row = rdr.readRow(BlockMode.INDIFFERENT)) != null) { diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/SQLDatabaseMetaData.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/SQLDatabaseMetaData.java index f07ede36e1..bb14a96705 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/SQLDatabaseMetaData.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/databasemetadata/SQLDatabaseMetaData.java @@ -33,6 +33,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; + import net.sourceforge.squirrel_sql.client.session.schemainfo.synonym.SynonymHandler; import net.sourceforge.squirrel_sql.fw.datasetviewer.BlockMode; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; @@ -1232,7 +1233,7 @@ public synchronized IDataSet getColumnPrivilegesDataSet(ITableInfo ti, int[] col rs = md.getColumnPrivileges(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName(), columns); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1267,7 +1268,7 @@ public synchronized IDataSet getExportedKeysDataSet(ITableInfo ti) throws DataSe privateGetJDBCMetaData().getExportedKeys(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName()); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, null, true, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, null, true, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1326,7 +1327,7 @@ public synchronized IDataSet getImportedKeysDataSet(ITableInfo ti) throws DataSe { rs = privateGetJDBCMetaData().getImportedKeys(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName()); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, null, true, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, null, true, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1438,7 +1439,7 @@ public synchronized ResultSetDataSet getIndexInfo(ITableInfo ti, int[] columnInd { rs = _getIndexInfo(ti); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1518,7 +1519,7 @@ public synchronized IDataSet getPrimaryKey(ITableInfo ti, int[] columnIndices, b privateGetJDBCMetaData().getPrimaryKeys(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName()); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1584,7 +1585,7 @@ public synchronized IDataSet getProcedureColumnsDataSet(IProcedureInfo ti) throw DatabaseMetaData md = privateGetJDBCMetaData(); rs = md.getProcedureColumns(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName(), "%"); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1623,7 +1624,7 @@ public synchronized IDataSet getTablePrivilegesDataSet(ITableInfo ti, int[] colu DatabaseMetaData md = privateGetJDBCMetaData(); rs = md.getTablePrivileges(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName()); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1660,7 +1661,7 @@ public synchronized IDataSet getVersionColumnsDataSet(ITableInfo ti) throws Data DatabaseMetaData md = privateGetJDBCMetaData(); rs = md.getVersionColumns(ti.getCatalogName(), ti.getSchemaName(), ti.getSimpleName()); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectFactory.getDialectType(this)); return rsds; } catch (SQLException e) @@ -1704,7 +1705,7 @@ public synchronized IDataSet getColumns(ITableInfo ti, int[] columnIndices, bool { rs = getColumns(ti); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); + rsds.readDataFromJdbcResultSetForDatabaseMetaData(rs, columnIndices, computeWidths, DialectFactory.getDialectType(this)); // Workaround for DB2/AIX64 driver: COLUMN_SIZE is not CHAR_OCTET_LENGTH for double-bytes datatypes GRAPHIC/VARGRAPHIC result = rsds; diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/querytokenizer/QueryTokenizer.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/querytokenizer/QueryTokenizer.java index 65bee0c864..57be6f61bd 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/querytokenizer/QueryTokenizer.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/sql/querytokenizer/QueryTokenizer.java @@ -18,6 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.session.action.sqlscript.SQLScriptServices; import net.sourceforge.squirrel_sql.fw.preferences.IQueryTokenizerPreferenceBean; @@ -29,13 +35,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - public class QueryTokenizer implements IQueryTokenizer { private final static ILogger s_log = LoggerController.createLogger(QueryTokenizer.class); @@ -166,8 +165,8 @@ public void setScriptToTokenize(String script, QueryTokenizePurpose queryTokeniz script = script.replace('\r', ' '); - StringBuffer curQuery = new StringBuffer(); - StringBuffer curOriginalQuery = new StringBuffer(); + StringBuilder curQuery = new StringBuilder(); + StringBuilder curOriginalQuery = new StringBuilder(); SQLCommentAndLiteralHandler commentAndLiteralHandler = new SQLCommentAndLiteralHandler(script, _lineCommentBegin, _removeMultiLineComment, _removeLineComment); ChangeStatementSeparatorSupport changeStatementSeparatorSupport = new ChangeStatementSeparatorSupport(queryTokenizePurpose, script, _lineCommentBegin); diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilities.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilities.java index e19147af1c..0b38a7a928 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilities.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilities.java @@ -18,26 +18,14 @@ */ package net.sourceforge.squirrel_sql.fw.util; -import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; public interface IOUtilities { - - public static String NEW_LINE = System.getProperty("line.separator"); - - String HTTP_PROTOCOL_PREFIX = "http"; - - void closeInputStream(InputStream is); - void closeOutputStream(OutputStream os); /** @@ -63,43 +51,6 @@ public interface IOUtilities * the Writer to flush. */ void flushWriter(Writer writer); - - /** - * Reads from the specified InputStream and copies bytes read to the specified OuputStream. - * - * @param is - * the InputStream to read from - * @param os - * the OutputStream to write to - * @throws IOException - * in an exception occurs while reading/writing - */ - void copyBytes(InputStream is, OutputStream os) throws IOException; - - /** - * Reads from the specified FileWrapper(from) and copies bytes read to the specified FileWrapper(to). - * - * @param from - * @param to - * @throws IOException - */ - void copyFile(FileWrapper from, FileWrapper to) throws IOException; - - /** - * Computes the CRC32 checksum for the specified file. This doesn't appear to be compatible with cksum. - * - * @param f - * the file to compute a checksum for. - * @return the checksum value for the file specified - */ - long getCheckSum(File f) throws IOException; - - /** - * @param f - * @return - * @throws IOException - */ - long getCheckSum(FileWrapper f) throws IOException; /** * Copies bytes from the specified InputStream to the specified output file. This will create the file if @@ -112,49 +63,7 @@ public interface IOUtilities * @return the number of bytes that were read and written to the file. * @throws IOException */ - public int copyBytesToFile(InputStream is, FileWrapper outputFile) throws IOException; - - /** - * Downloads a file using HTTP. - * - * @param url - * the URL of the file to be retrieved - * @param destFile - * the file to download the URL file into - * @param proxySettings - * the ProxySettings to use - * @return the number of bytes that were read and written to the file. - * @throws Exception - */ - int downloadHttpFile(final URL url, FileWrapper destFile, IProxySettings proxySettings) throws IOException; - - URL constructHttpUrl(final String host, final int port, final String fileToGet) - throws MalformedURLException; - - /** - * Reads the file specified by filename and builds a list of lines, applying the line fixers specified. - * - * @param filename - * the name of the file to read lines from. - * @param lineFixers - * a list of fixers to apply to each line. This can be null if no line manipulation is required. - * @return a list of lines - * @throws IOException - * if an I/O error occurs. - */ - List getLinesFromFile(String filename, List lineFixers) throws IOException; - - /** - * Writes the specified list of line to the specified filename. This will overrite the current contents of - * the file. - * - * @param filename - * the file to overwrite - * @param lines - * the lines to write to the file. - * @throws FileNotFoundException - */ - void writeLinesToFile(String filename, List lines) throws FileNotFoundException; + int copyBytesToFile(InputStream is, FileWrapper outputFile) throws IOException; } \ No newline at end of file diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilitiesImpl.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilitiesImpl.java index 0716d0ecea..5ccc35fd47 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilitiesImpl.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/IOUtilitiesImpl.java @@ -18,34 +18,15 @@ */ package net.sourceforge.squirrel_sql.fw.util; -import net.sourceforge.squirrel_sql.fw.util.log.ILogger; -import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.methods.GetMethod; - -import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.PrintWriter; import java.io.Reader; import java.io.Writer; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.zip.CRC32; +import net.sourceforge.squirrel_sql.fw.util.log.ILogger; +import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; public class IOUtilitiesImpl implements IOUtilities { @@ -56,24 +37,6 @@ public class IOUtilitiesImpl implements IOUtilities /** Logger for this class. */ private final ILogger s_log = LoggerController.createLogger(IOUtilitiesImpl.class); - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities#closeInputStream(java.io.InputStream) - */ - public void closeInputStream(InputStream is) - { - if (is != null) - { - try - { - is.close(); - } - catch (Exception e) - { - s_log.error("closeInputStream: Unable to close InputStream - " + e.getMessage(), e); - } - } - } - /** * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities#closeOutputStream(java.io.OutputStream) */ @@ -146,21 +109,7 @@ public void flushWriter(Writer writer) } } } - - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# copyBytes(java.io.InputStream, - * java.io.OutputStream) - */ - public void copyBytes(InputStream is, OutputStream os) throws IOException - { - byte[] buffer = new byte[DISK_DATA_BUFFER_SIZE]; - int length; - while ((length = is.read(buffer)) > 0) - { - os.write(buffer, 0, length); - } - } + /** * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# copyBytesToFile(java.io.InputStream, @@ -192,220 +141,4 @@ public int copyBytesToFile(InputStream is, FileWrapper outputFile) throws IOExce } return totalLength; } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities#getCheckSum(java.io.File) - */ - public long getCheckSum(File f) throws IOException - { - CRC32 result = new CRC32(); - FileInputStream fis = null; - try - { - fis = new FileInputStream(f); - int len = 0; - byte[] buffer = new byte[DISK_DATA_BUFFER_SIZE]; - while ((len = fis.read(buffer)) != -1) - { - result.update(buffer, 0, len); - } - } - finally - { - closeInputStream(fis); - } - return result.getValue(); - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# - * getCheckSum(net.sourceforge.squirrel_sql.fw.util.FileWrapper) - */ - public long getCheckSum(FileWrapper f) throws IOException - { - return getCheckSum(new File(f.getAbsolutePath())); - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# - * copyFile(net.sourceforge.squirrel_sql.fw.util.FileWrapper, - * net.sourceforge.squirrel_sql.fw.util.FileWrapper) - */ - public void copyFile(FileWrapper from, FileWrapper to) throws IOException - { - FileInputStream in = null; - FileOutputStream out = null; - try - { - in = new FileInputStream(from.getAbsolutePath()); - out = new FileOutputStream(to.getAbsolutePath()); - byte[] buffer = new byte[8192]; - int len; - while ((len = in.read(buffer)) != -1) - { - out.write(buffer, 0, len); - } - } - finally - { - closeInputStream(in); - closeOutputStream(out); - } - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# constructHttpUrl(java.lang.String, int, - * java.lang.String) - */ - public URL constructHttpUrl(final String host, final int port, final String fileToGet) - throws MalformedURLException - { - URL url = null; - String server = host; - if (server.startsWith(HTTP_PROTOCOL_PREFIX)) - { - int beginIdx = server.indexOf("://") + 3; - server = server.substring(beginIdx, host.length()); - } - if (port == 80) - { - url = new URL(HTTP_PROTOCOL_PREFIX, server, fileToGet); - } - else - { - url = new URL(HTTP_PROTOCOL_PREFIX, server, port, fileToGet); - } - return url; - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities# downloadHttpFile(java.lang.String, int, - * java.lang.String, net.sourceforge.squirrel_sql.fw.util.FileWrapper) - */ - public int downloadHttpFile(URL url, FileWrapper destFile, IProxySettings proxySettings) - throws IOException - { - BufferedInputStream is = null; - HttpMethod method = null; - int resultCode = -1; - int result = -1; - try - { - if (s_log.isDebugEnabled()) - { - s_log.debug("downloadHttpFile: downloading file (" + destFile.getName() + ") from url: " + url); - } - HttpClient client = new HttpClient(); - setupProxy(proxySettings, client, url); - - method = new GetMethod(url.toString()); - method.setFollowRedirects(true); - - resultCode = client.executeMethod(method); - if (s_log.isDebugEnabled()) - { - s_log.debug("downloadHttpFile: response code was: " + resultCode); - } - - if (resultCode != 200) { throw new FileNotFoundException("Failed to download file from url (" + url - + "): HTTP Response Code=" + resultCode); } - InputStream mis = method.getResponseBodyAsStream(); - - is = new BufferedInputStream(mis); - - if (s_log.isDebugEnabled()) - { - s_log.debug("downloadHttpFile: writing http response body to file: " + destFile.getAbsolutePath()); - } - - result = copyBytesToFile(mis, destFile); - } - catch (IOException e) - { - s_log.error("downloadHttpFile: Unexpected exception while " - + "attempting to open an HTTP connection to url (" + url + ") to download a file (" - + destFile.getAbsolutePath() + "): " + e.getMessage(), e); - throw e; - } - finally - { - closeInputStream(is); - method.releaseConnection(); - } - return result; - } - - /** - * Setup proxy configuration specified in proxySettings. This setup is skipped if: 1) proxySettings is - * null. 2) proxySettings.getHttpUseProxy() is false (HttpClient doesn't support SOCKS proxy) 3) The url's - * host component is in the "non-proxy" host list - * - * @param proxySettings - * the ProxySettings to use - * @param client - * the instance of HttpClient to configure - * @param url - * the URL of the file to be retrieved - */ - private void setupProxy(IProxySettings proxySettings, HttpClient client, URL url) - { - if (proxySettings == null) { return; } - if (!proxySettings.getHttpUseProxy()) { return; } - if (proxySettings.getHttpNonProxyHosts() != null - && proxySettings.getHttpNonProxyHosts().contains(url.getHost())) { return; } - - String proxyHost = proxySettings.getHttpProxyServer(); - int proxyPort = Integer.parseInt(proxySettings.getHttpProxyPort()); - String proxyUsername = proxySettings.getHttpProxyUser(); - String proxyPassword = proxySettings.getHttpProxyPassword(); - - client.getHostConfiguration().setProxy(proxyHost, proxyPort); - if (proxyUsername != null && !"".equals(proxyUsername)) - { - Credentials credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword); - client.getState().setProxyCredentials(AuthScope.ANY, credentials); - } - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities#getLinesFromFile(java.lang.String, java.util.List) - */ - @Override - public List getLinesFromFile(String filename, List lineFixers) throws IOException - { - ArrayList lines = new ArrayList(); - - BufferedReader reader = new BufferedReader(new FileReader(filename)); - String line = null; - - while ((line = reader.readLine()) != null) - { - if (lineFixers != null) - { - for (ScriptLineFixer fixer : lineFixers) - { - line = fixer.fixLine(filename, line); - } - } - lines.add(line); - } - reader.close(); - return lines; - } - - /** - * @see net.sourceforge.squirrel_sql.fw.util.IOUtilities#writeLinesToFile(java.lang.String, java.util.List) - */ - @Override - public void writeLinesToFile(String filename, List lines) throws FileNotFoundException - { - PrintWriter out = new PrintWriter(new File(filename)); - for (String outline : lines) - { - out.write(outline); - out.write(NEW_LINE); - } - out.close(); - } - } diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/ProxyHandler.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/ProxyHandler.java index 9cf96f1fc2..eac0ec1af6 100755 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/ProxyHandler.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/ProxyHandler.java @@ -17,10 +17,10 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + import java.net.Authenticator; import java.net.PasswordAuthentication; import java.util.Properties; - import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; /** @@ -42,15 +42,7 @@ public ProxyHandler() public void apply(IProxySettings proxy) { - apply(proxy, System.getProperties()); - } - - public void apply(IProxySettings proxy, Properties props) - { - if (proxy == null) - { - throw new IllegalArgumentException("ProxySettings == null"); - } + Properties props = System.getProperties(); final boolean http = proxy.getHttpUseProxy(); if (http) diff --git a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/StringUtilities.java b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/StringUtilities.java index babe4c2b24..af7fdd61b8 100644 --- a/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/StringUtilities.java +++ b/sql12/core/src/net/sourceforge/squirrel_sql/fw/util/StringUtilities.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; - import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; import org.apache.commons.lang3.StringUtils; @@ -326,6 +325,16 @@ else if(false == ensureJavaStart && Character.isLetterOrDigit(text.charAt(0)) ) public static String fileNameNormalize(String text) { + return fileNameNormalize(text, false); + } + + public static String fileNameNormalize(String text, boolean respectNull) + { + if(respectNull && null == text) + { + return null; + } + StringBuilder buf = new StringBuilder(text.length()); for(int i=0; i < text.length(); ++i) diff --git a/sql12/installer/mac/installer-readme.html b/sql12/installer/mac/installer-readme.html index bfd0ce8a91..0199378b1a 100644 --- a/sql12/installer/mac/installer-readme.html +++ b/sql12/installer/mac/installer-readme.html @@ -28,7 +28,7 @@ SQuirreL SQL Client Version JRE Minimum Version - 5.0.0 and higher + 5.1.0 and higher 17 diff --git a/sql12/installer/other/installer-readme.html b/sql12/installer/other/installer-readme.html index fe18305896..afdd99d992 100644 --- a/sql12/installer/other/installer-readme.html +++ b/sql12/installer/other/installer-readme.html @@ -28,7 +28,7 @@ SQuirreL SQL Client Version JRE Minimum Version - 5.0.0 and higher + 5.1.0 and higher 17 diff --git a/sql12/plugins/hibernate/src/net/sourceforge/squirrel_sql/plugins/hibernate/HibernatePlugin.java b/sql12/plugins/hibernate/src/net/sourceforge/squirrel_sql/plugins/hibernate/HibernatePlugin.java index fdfbd6a3ff..6e0176aff1 100644 --- a/sql12/plugins/hibernate/src/net/sourceforge/squirrel_sql/plugins/hibernate/HibernatePlugin.java +++ b/sql12/plugins/hibernate/src/net/sourceforge/squirrel_sql/plugins/hibernate/HibernatePlugin.java @@ -1,8 +1,6 @@ package net.sourceforge.squirrel_sql.plugins.hibernate; import java.util.HashMap; - -import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.plugin.DefaultSessionPlugin; import net.sourceforge.squirrel_sql.client.plugin.PluginException; @@ -10,6 +8,7 @@ import net.sourceforge.squirrel_sql.client.plugin.PluginSessionCallbackAdaptor; import net.sourceforge.squirrel_sql.client.preferences.IGlobalPreferencesPanel; import net.sourceforge.squirrel_sql.client.session.ISession; +import net.sourceforge.squirrel_sql.client.shortcut.ShortCutDescriptionReader; import net.sourceforge.squirrel_sql.fw.id.IIdentifier; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; @@ -78,9 +77,9 @@ public synchronized void initialize() throws PluginException { _resources = new HibernatePluginResources(this); - Main.getApplication().getShortcutManager().registerAccelerator(HQLCompleteCodeAction.class, _resources); - Main.getApplication().getShortcutManager().registerAccelerator(HQLBookmarksAction.class, _resources); - Main.getApplication().getShortcutManager().registerAccelerator(HQLToolsPopUpAction.class, _resources); + Main.getApplication().getShortcutManager().registerAccelerator(HQLCompleteCodeAction.class, _resources, ShortCutDescriptionReader.of(_resources, HQLCompleteCodeAction.class)); + Main.getApplication().getShortcutManager().registerAccelerator(HQLBookmarksAction.class, _resources, ShortCutDescriptionReader.of(_resources, HQLBookmarksAction.class)); + Main.getApplication().getShortcutManager().registerAccelerator(HQLToolsPopUpAction.class, _resources, ShortCutDescriptionReader.of(_resources, HQLToolsPopUpAction.class)); } diff --git a/sql12/plugins/mssql/src/net/sourceforge/squirrel_sql/plugins/mssql/gui/MonitorPanel.java b/sql12/plugins/mssql/src/net/sourceforge/squirrel_sql/plugins/mssql/gui/MonitorPanel.java index 51006a29d8..962c15161a 100644 --- a/sql12/plugins/mssql/src/net/sourceforge/squirrel_sql/plugins/mssql/gui/MonitorPanel.java +++ b/sql12/plugins/mssql/src/net/sourceforge/squirrel_sql/plugins/mssql/gui/MonitorPanel.java @@ -27,7 +27,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Date; - import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JPanel; @@ -168,11 +167,11 @@ private void refreshData() { _refreshDate = new Date(); rs = _whoStmt.executeQuery(); - _whoDataSet.setResultSet(rs, DialectType.MSSQL); + _whoDataSet.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectType.MSSQL); _whoViewer.show(_whoDataSet); rs = _perfStmt.executeQuery(); - _perfDataSet.setResultSet(rs, DialectType.MSSQL); + _perfDataSet.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectType.MSSQL); _perfViewer.show(_perfDataSet); } catch (java.sql.SQLException ex) diff --git a/sql12/plugins/mysql/src/net/sourceforge/squirrel_sql/plugins/mysql/tab/BaseSQLTab.java b/sql12/plugins/mysql/src/net/sourceforge/squirrel_sql/plugins/mysql/tab/BaseSQLTab.java index 946662edae..e29077eef8 100644 --- a/sql12/plugins/mysql/src/net/sourceforge/squirrel_sql/plugins/mysql/tab/BaseSQLTab.java +++ b/sql12/plugins/mysql/src/net/sourceforge/squirrel_sql/plugins/mysql/tab/BaseSQLTab.java @@ -18,6 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.Component; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashMap; +import java.util.Map; + import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs.BaseObjectTab; import net.sourceforge.squirrel_sql.client.session.properties.SessionProperties; @@ -31,13 +38,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import java.awt.Component; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Map; - abstract class BaseSQLTab extends BaseObjectTab { /** Title to display for tab. */ @@ -159,7 +159,7 @@ protected IDataSet createDataSetFromResultSet(ResultSet rs) throws DataSetException { final ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, DialectType.MYSQL); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectType.MYSQL); if (!_firstRowOnly) { return rsds; diff --git a/sql12/plugins/oracle/src/net/sourceforge/squirrel_sql/plugins/oracle/oracle.properties b/sql12/plugins/oracle/src/net/sourceforge/squirrel_sql/plugins/oracle/oracle.properties index 84aef54762..14f21ad4a2 100755 --- a/sql12/plugins/oracle/src/net/sourceforge/squirrel_sql/plugins/oracle/oracle.properties +++ b/sql12/plugins/oracle/src/net/sourceforge/squirrel_sql/plugins/oracle/oracle.properties @@ -52,7 +52,7 @@ net.sourceforge.squirrel_sql.plugins.oracle.SGAtrace.SGATraceInternalFrame.frame # Configuration information for Actions. ######## action.net.sourceforge.squirrel_sql.plugins.oracle.dboutput.NewDBOutputWorksheetAction.image=dboutput.gif -action.net.sourceforge.squirrel_sql.plugins.oracle.dboutput.NewDBOutputWorksheetAction.name=DB Ouptut +action.net.sourceforge.squirrel_sql.plugins.oracle.dboutput.NewDBOutputWorksheetAction.name=DB Output action.net.sourceforge.squirrel_sql.plugins.oracle.dboutput.NewDBOutputWorksheetAction.tooltip=View Oracle Database Output action.net.sourceforge.squirrel_sql.plugins.oracle.dboutput.ClearDBOutputAction.image=Delete16.gif diff --git a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/explain/ExplainExecutorPanel.java b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/explain/ExplainExecutorPanel.java index adae275fb5..e99730e5d1 100644 --- a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/explain/ExplainExecutorPanel.java +++ b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/explain/ExplainExecutorPanel.java @@ -19,6 +19,22 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +import java.awt.BorderLayout; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.gui.builders.UIFactory; import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanel; import net.sourceforge.squirrel_sql.client.session.ISQLExecuterHandler; @@ -44,23 +60,6 @@ import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; -import javax.swing.Icon; -import javax.swing.JComponent; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JTabbedPane; -import javax.swing.SwingUtilities; -import java.awt.BorderLayout; -import java.awt.Component; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.text.NumberFormat; -import java.util.ArrayList; -import java.util.List; - public class ExplainExecutorPanel extends JPanel implements ISQLResultExecutor { static final String EXPLAIN_PREFIX = "EXPLAIN ANALYZE "; @@ -287,7 +286,7 @@ public void sqlResultSetAvailable(ResultSetWrapper rs, final SQLExecutionInfo in { final ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs.getResultSet(), _dialectType); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs.getResultSet(), _dialectType); GUIUtils.processOnSwingEventThread( new Runnable() diff --git a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/ActiveConnections.java b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/ActiveConnections.java index a38b9ef6b8..8c6fe2e773 100644 --- a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/ActiveConnections.java +++ b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/ActiveConnections.java @@ -3,7 +3,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; - import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs.BaseDataSetTab; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; @@ -54,7 +53,7 @@ protected IDataSet createDataSet() throws DataSetException { Statement stmt = con.createStatement(); ResultSet rs = isPostgres92(con) ? stmt.executeQuery(QUERY_92) : stmt.executeQuery(QUERY); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, DialectType.POSTGRES); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectType.POSTGRES); return rsds; } catch (SQLException ex) { diff --git a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/LockTab.java b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/LockTab.java index d549267da7..622e7e3010 100644 --- a/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/LockTab.java +++ b/sql12/plugins/postgres/src/net/sourceforge/squirrel_sql/plugins/postgres/tab/LockTab.java @@ -3,7 +3,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; - import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs.BaseDataSetTab; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; @@ -62,7 +61,7 @@ protected IDataSet createDataSet() throws DataSetException { Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(QUERY); ResultSetDataSet rsds = new ResultSetDataSet(); - rsds.setResultSet(rs, DialectType.POSTGRES); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectType.POSTGRES); return rsds; } catch (SQLException ex) diff --git a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SQLALiasesCombo.java b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SQLALiasesCombo.java index 06b70a3006..eba8d9561d 100644 --- a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SQLALiasesCombo.java +++ b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SQLALiasesCombo.java @@ -18,11 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.client.IApplication; +import java.util.ArrayList; +import java.util.List; +import javax.swing.JComboBox; +import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias; +import org.apache.commons.lang3.StringUtils; -import javax.swing.*; -import java.util.Iterator; /** * This JComboBox will display all aliases. * @@ -46,22 +48,30 @@ public SQLAlias getSelectedSQLAlias() /** * Load control with all the aliases in the system. - * - * @param conn app Application API. - * - * @throws IllegalArgumentException - * Thrown if a null IApplication passed. - * - * @throws BaseSQLException - * Thrown if an SQL exception occurs. */ - public void load(IApplication app) + public void load(AliasScriptCache scriptsCache) { removeAllItems(); - for (Iterator it = app.getAliasesAndDriversManager().aliases(); it.hasNext();) + + List aliasListClone= new ArrayList<>(Main.getApplication().getAliasesAndDriversManager().getAliasList()); + + aliasListClone.sort((a1, a2) -> compareAliases(scriptsCache, a1, a2)); + + aliasListClone.forEach(a -> addItem(a)); + } + + private int compareAliases(AliasScriptCache scriptsCache, SQLAlias a1, SQLAlias a2) + { + if(false == StringUtils.isBlank(scriptsCache.get(a1).getSQL()) && StringUtils.isBlank(scriptsCache.get(a2).getSQL())) { - SQLAlias alias = it.next(); - addItem(alias); + return -1; } - } + else if(StringUtils.isBlank(scriptsCache.get(a1).getSQL()) && false == StringUtils.isBlank(scriptsCache.get(a2).getSQL())) + { + return 1; + } + + return StringUtils.compareIgnoreCase(a1.getName(), a2.getName()); + + } } diff --git a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ScriptsSheet.java b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ScriptsSheet.java index 1b82ad442a..002e6bf917 100644 --- a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ScriptsSheet.java +++ b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ScriptsSheet.java @@ -18,44 +18,34 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import javax.swing.WindowConstants; import net.sourceforge.squirrel_sql.client.IApplication; +import net.sourceforge.squirrel_sql.client.Main; import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.DialogWidget; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import net.sourceforge.squirrel_sql.fw.util.log.ILogger; -import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; - -import javax.swing.*; -import java.awt.*; class ScriptsSheet extends DialogWidget { - private static final StringManager s_stringMgr = - StringManagerFactory.getStringManager(ScriptsSheet.class); + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(ScriptsSheet.class); - - /** Logger for this class. */ - private static ILogger s_log = - LoggerController.createLogger(ScriptsSheet.class); - /** Singleton instance of this class. */ private static ScriptsSheet s_instance; - /** Plugin. */ private SessionScriptPlugin _plugin; - /** Application API. */ - private IApplication _app; /** Main panel. */ private ViewSessionScriptsPanel _mainPnl; - private ScriptsSheet(SessionScriptPlugin plugin, IApplication app) + private ScriptsSheet(SessionScriptPlugin plugin) { // i18n[sessionscript.startupScripts=Startup Scripts] - super(s_stringMgr.getString("sessionscript.startupScripts"), true, true, true, true); + super(s_stringMgr.getString("sessionscript.startupScripts"), true, true, true, true, Main.getApplication().getMainFrame()); _plugin = plugin; - _app = app; createUserInterface(); } @@ -74,9 +64,10 @@ public static synchronized void showSheet(SessionScriptPlugin plugin, { if (s_instance == null) { - s_instance = new ScriptsSheet(plugin, app); + s_instance = new ScriptsSheet(plugin); app.getMainFrame().addWidget(s_instance); } + DialogWidget.centerWithinDesktop(s_instance); s_instance.setVisible(true); } @@ -94,7 +85,7 @@ private void createUserInterface() makeToolWindow(true); - _mainPnl = new ViewSessionScriptsPanel(_plugin, _app); + _mainPnl = new ViewSessionScriptsPanel(_plugin); Container content = getContentPane(); content.setLayout(new BorderLayout()); diff --git a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SessionScriptPlugin.java b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SessionScriptPlugin.java index dac5fa698b..6ec7267ea1 100755 --- a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SessionScriptPlugin.java +++ b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/SessionScriptPlugin.java @@ -18,8 +18,9 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import java.io.IOException; +import java.io.IOException; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.IApplication; import net.sourceforge.squirrel_sql.client.action.ActionCollection; import net.sourceforge.squirrel_sql.client.plugin.DefaultSessionPlugin; @@ -32,8 +33,7 @@ import net.sourceforge.squirrel_sql.fw.util.FileWrapper; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; - -import javax.swing.*; +import org.apache.commons.lang3.StringUtils; /** * The plugin class. @@ -169,7 +169,8 @@ public synchronized void initialize() throws PluginException try { _cache = new AliasScriptCache(this); - } catch (IOException ex) + } + catch(IOException ex) { throw new PluginException(ex); } @@ -189,17 +190,22 @@ public void unload() super.unload(); } - public PluginSessionCallback sessionStarted(final ISession session) + @Override + public int getSessionStartedCallRank() { - boolean rc = false; + // Call this Plugin's sessionStarted method last. + return Integer.MAX_VALUE; + } + @Override + public PluginSessionCallback sessionStarted(final ISession session) + { AliasScript script = _cache.get(session.getAlias()); if (script != null) { final String sql = script.getSQL(); - if (sql != null && sql.length() > 0) + if (false == StringUtils.isBlank(sql)) { - rc = true; final ISQLPanelAPI api = session.getSessionInternalFrame().getMainSQLPanelAPI(); SwingUtilities.invokeLater(new Runnable() @@ -212,11 +218,6 @@ public void run() }); } } - - if (false == rc) - { - return null; - } return new PluginSessionCallbackAdaptor(); } diff --git a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ViewSessionScriptsPanel.java b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ViewSessionScriptsPanel.java index 7d7cacb525..2a3ff4950c 100644 --- a/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ViewSessionScriptsPanel.java +++ b/sql12/plugins/sessionscript/src/net/sourceforge/squirrel_sql/plugins/sessionscript/ViewSessionScriptsPanel.java @@ -18,18 +18,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -import net.sourceforge.squirrel_sql.client.IApplication; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import net.sourceforge.squirrel_sql.client.gui.db.SQLAlias; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - public class ViewSessionScriptsPanel extends JPanel { private static final StringManager s_stringMgr = @@ -37,25 +41,18 @@ public class ViewSessionScriptsPanel extends JPanel private SessionScriptPlugin _plugin; - private IApplication _app; private SQLALiasesCombo _aliasesCmb = new SQLALiasesCombo(); private JTextArea _sqlEntry = new JTextArea(); private JButton _saveBtn; - ViewSessionScriptsPanel(SessionScriptPlugin plugin, IApplication app) + ViewSessionScriptsPanel(SessionScriptPlugin plugin) { - super(); if (plugin == null) { throw new IllegalArgumentException("SessionScriptPlugin == null"); } - if (app == null) - { - throw new IllegalArgumentException("IApplication == null"); - } _plugin = plugin; - _app = app; createUserInterface(); refreshScript(); @@ -86,7 +83,7 @@ private void createUserInterface() { setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); - _aliasesCmb.load(_app); + _aliasesCmb.load(_plugin.getScriptsCache()); _aliasesCmb.addActionListener(new AliasesComboListener(this)); _sqlEntry.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); diff --git a/sql12/plugins/sqlbookmark/doc/readme.html b/sql12/plugins/sqlbookmark/doc/readme.html index 23625ab81d..cb0bce8174 100644 --- a/sql12/plugins/sqlbookmark/doc/readme.html +++ b/sql12/plugins/sqlbookmark/doc/readme.html @@ -9,7 +9,7 @@ -

SQLBookmark 1.0 - Joe Mocker, Gerd Wagner

+

SQLBookmark 2.0.1 - Joe Mocker, Gerd Wagner

SQLBookmark allows you to "bookmark" commonly used SQL code for easy point and click reuse. Whatever you type in the SQL editor can be easily bookmarked by opening SQuirreL's tools popup via @@ -99,5 +99,16 @@

The Global Preferences window can be opened using the “Edit Bookmarks” toolbar button of a Session window.

+

+



+

+

Executing Bookmarks scriptlike:

+Bookmarks can be called from within the SQL editor using the following syntax: + + + @runbookmark <bookmarkNameInSingleQuotes> + + + \ No newline at end of file diff --git a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/I18NStrings.properties b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/I18NStrings.properties index 82178fb6bd..680264f893 100644 --- a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/I18NStrings.properties +++ b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/I18NStrings.properties @@ -48,3 +48,10 @@ BookmarkEditController.duplicate.bookmark.name=A bookmark named "{0}" already ex SQLBookmarkPreferencesPanel.show.as.tree=Show user bookmarks in tree using SQLBookmarkPreferencesPanel.show.as.tree.as.path.separator=as path separator char + +RunBookmarkTagHandler.noBookmarkBeginMarker=@runbookmark tag found without bookmark to run. Bookmark name must be given after the tag in single quotes. +RunBookmarkTagHandler.noBookmarkEndMarker=@runbookmark tag found without bookmark to run. Bookmark name must be given after the tag in single quotes. +RunBookmarkTagHandler.bookmarkDoesNotExist=Bookmark named {0} does not exits. + +sqlbookmark.note.runbookmark=Note: To directly execute a bookmark's statement use @runbookmark +sqlbookmark.note.runbookmark.tooltipp=Note: To directly execute a bookmark's statement from within the SQL editor use @runbookmark \ No newline at end of file diff --git a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/RunBookmarkTagHandler.java b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/RunBookmarkTagHandler.java new file mode 100644 index 0000000000..9b70f20d09 --- /dev/null +++ b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/RunBookmarkTagHandler.java @@ -0,0 +1,53 @@ +package net.sourceforge.squirrel_sql.plugins.sqlbookmark; + +import net.sourceforge.squirrel_sql.client.Main; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; +import org.apache.commons.lang3.StringUtils; + +public class RunBookmarkTagHandler +{ + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(RunBookmarkTagHandler.class); + + private static final String RUN_BOOKMARK_TAG = "@runbookmark"; + + public static boolean requiresToRunBookmark(String sql) + { + return StringUtils.startsWith(StringUtils.trim(sql), RUN_BOOKMARK_TAG); + } + + public static String toBookmarkSql(String sql, BookmarkManager bookmarkManager) + { + String sqlWithBookmarkPrefix = sql; + + int bookmarkBeginMarkerPos = sqlWithBookmarkPrefix.indexOf('\''); + if(-1 == bookmarkBeginMarkerPos) + { + Main.getApplication().getMessageHandler().showErrorMessage(s_stringMgr.getString("RunBookmarkTagHandler.noBookmarkBeginMarker")); + throw new IllegalStateException("@runbookmark tag found without bookmark to run. Bookmark name must be given after the tag in single quotes."); + } + + int fileEndMarkerPos = sqlWithBookmarkPrefix.indexOf('\'', bookmarkBeginMarkerPos + 1); + if(-1 == fileEndMarkerPos) + { + Main.getApplication().getMessageHandler().showErrorMessage(s_stringMgr.getString("RunBookmarkTagHandler.noBookmarkEndMarker")); + throw new IllegalStateException("@runbookmark tag found without bookmark to run. Bookmark name must be given after the tag in single quotes."); + } + + String bookmarkName = sqlWithBookmarkPrefix.substring(bookmarkBeginMarkerPos + 1, fileEndMarkerPos).trim(); + Bookmark bookmark = bookmarkManager.get(bookmarkName); + + if(null == bookmark) + { + Main.getApplication().getMessageHandler().showErrorMessage(s_stringMgr.getString("RunBookmarkTagHandler.bookmarkDoesNotExist", bookmarkName)); + throw new IllegalStateException("Bookmark named %s does not exist".formatted(bookmarkName)); + } + + return bookmark.getSql(); + } + + public static boolean scriptContainsRunBookmarkTag(String script) + { + return StringUtils.contains(script, RUN_BOOKMARK_TAG); + } +} diff --git a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPlugin.java b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPlugin.java index a63edc7d8c..106aa61195 100644 --- a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPlugin.java +++ b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPlugin.java @@ -43,13 +43,19 @@ import net.sourceforge.squirrel_sql.client.preferences.IGlobalPreferencesPanel; import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.ISession; +import net.sourceforge.squirrel_sql.client.session.event.SQLExecutionAdapter; import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.ObjectTreePanel; import net.sourceforge.squirrel_sql.client.session.mainpanel.sqltab.AdditionalSQLTab; import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.resources.IResources; +import net.sourceforge.squirrel_sql.fw.sql.querytokenizer.IQueryTokenizer; +import net.sourceforge.squirrel_sql.fw.sql.querytokenizer.QueryHolder; import net.sourceforge.squirrel_sql.fw.util.FileWrapper; +import net.sourceforge.squirrel_sql.fw.util.StringManager; +import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; +import org.apache.commons.lang3.StringUtils; /** * Main entry into the SQL Bookmark plugin. @@ -63,64 +69,40 @@ public class SQLBookmarkPlugin extends DefaultSessionPlugin { private final static ILogger s_log = LoggerController.createLogger(SQLBookmarkPlugin.class); + private static final StringManager s_stringMgr = StringManagerFactory.getStringManager(SQLBookmarkPlugin.class); - private ArrayList _sqlPanelAPIsListeningForBookmarks = new ArrayList<>(); private static final String BOOKMARKS_PROPS_FILE = "bookmarks.properties"; static final String BOOKMARK_PROP_DEFAULT_MARKS_IN_POPUP = "squirrelMarksInPopup"; static final String BOOKMARK_PROP_USE_CONTAINS_TO_FILTER_BOOKMARKS = "useContainsToFilterBookmarks"; - private Properties _boomarkProps; - private interface IMenuResourceKeys { String BOOKMARKS = "bookmarks"; } - public static final String RESOURCE_PATH = - "net.sourceforge.squirrel_sql.plugins.sqlbookmark.sqlbookmark"; + public static final String RESOURCE_PATH = "net.sourceforge.squirrel_sql.plugins.sqlbookmark.sqlbookmark"; - private static ILogger logger = - LoggerController.createLogger(SQLBookmarkPlugin.class); + private Properties _bookmarkProps; private IResources _resources; - private IPluginResourcesFactory _resourcesFactory = new PluginResourcesFactory(); - /** - * @param resourcesFactory the resourcesFactory to set - */ - public void setResourcesFactory(IPluginResourcesFactory resourcesFactory) - { - _resourcesFactory = resourcesFactory; - } + private ArrayList _sqlPanelAPIsListeningForBookmarks = new ArrayList<>(); - /** - * The bookmark menu - */ - private JMenu menu; + private IPluginResourcesFactory _resourcesFactory = new PluginResourcesFactory(); + + private JMenu _menu; + + private BookmarkManager _bookmarkManager; - /** - * All the current bookmarkManager - */ - private BookmarkManager bookmarkManager; - /** - * Returns the plugin version. - * - * @return the plugin version. - */ public String getVersion() { return "2.0.1"; } - /** - * Returns the authors name. - * - * @return the authors name. - */ public String getAuthor() { return "Joseph Mocker"; @@ -131,99 +113,44 @@ public String getContributors() return "Gerd Wagner"; } - - /** - * Return the internal name of this plugin. - * - * @return the internal name of this plugin. - */ public String getInternalName() { return "sqlbookmark"; } - /** - * Return the descriptive name of this plugin. - * - * @return the descriptive name of this plugin. - */ public String getDescriptiveName() { return "SQL Bookmark Plugin"; } - /** - * Returns the name of the Help file for the plugin. - * - * @return the help file name. - */ public String getHelpFileName() { return "doc/readme.html"; } - /** - * Returns the name of the Help file for the plugin. - * - * @return the license file name. - */ public String getLicenceFileName() { return "licence.txt"; } - /** - * Returns the name of the change log for the plugin. This should - * be a text or HTML file residing in the getPluginAppSettingsFolder - * directory. - * - * @return the changelog file name or null if plugin doesn't have - * a change log. - */ public String getChangeLogFileName() { return "changes.txt"; } - /** - * Return the plugin resources. Used by other classes. - * - * @return plugin resources. - */ - protected IResources getResources() + IResources getResources() { return _resources; } - /** - * Get and return a string from the plugin resources. - * - * @param name name of the resource string to return. - * @return resource string. - */ - protected String getResourceString(String name) + String getResourceString(String name) { return _resources.getString(name); } - /** - * Returns a handle to the current bookmark manager. - * - * @return the bookmark manager. - */ BookmarkManager getBookmarkManager() { - return bookmarkManager; - } - - /** - * Set the bookmark manager. - * - * @param bookmarks new manager to register. - */ - protected void setBookmarkManager(BookmarkManager bookmarks) - { - this.bookmarkManager = bookmarks; + return _bookmarkManager; } @@ -232,9 +159,6 @@ public Object getExternalService() return new BookmarksExternalServiceImpl(this); } - /** - * Initialize this plugin. - */ public synchronized void initialize() throws PluginException { super.initialize(); @@ -244,17 +168,17 @@ public synchronized void initialize() throws PluginException // Load resources such as menu items, etc... _resources = _resourcesFactory.createResource(RESOURCE_PATH, this); - bookmarkManager = new BookmarkManager(this); + _bookmarkManager = new BookmarkManager(this); // Load plugin preferences. try { - bookmarkManager.load(); + _bookmarkManager.load(); } catch (IOException e) { if (!(e instanceof FileNotFoundException)) { - logger.error("Problem loading bookmarkManager", e); + s_log.error("Problem loading bookmarkManager", e); } } @@ -269,7 +193,7 @@ public synchronized void initialize() throws PluginException public boolean allowsSessionStartedInBackground() { - return true; + return false; } public PluginSessionCallback sessionStarted(final ISession session) @@ -330,6 +254,55 @@ private void initSqlPanel(ISQLPanelAPI sqlPanelAPI) sqlPanelAPI.addToToolsPopUp("bookmarkadd", coll.get(AddBookmarkAction.class)); sqlPanelAPI.addToToolsPopUp("bookmarkedit", coll.get(EditBookmarksAction.class)); sqlPanelAPI.addToToolsPopUp("bookmarkselect", registerBookmarkSelectKeyStroke(sqlPanelAPI)); + + sqlPanelAPI.addSQLExecutionListener(new SQLExecutionAdapter(){ + @Override + public String statementExecuting(String sql) + { + return onStatementExecuting(sql, sqlPanelAPI.getSession()); + } + }); + } + + private String onStatementExecuting(String sql, ISession session) + { + if(false == RunBookmarkTagHandler.scriptContainsRunBookmarkTag(sql)) + { + return sql; + } + + IQueryTokenizer tokenizer = session.getNewQueryTokenizer(); + + tokenizer.setScriptToTokenize(sql); + + StringBuilder sb = new StringBuilder(); + + boolean changed = false; + while(tokenizer.hasQuery()) + { + QueryHolder query = tokenizer.nextQuery(); + String trimmedSql = StringUtils.trim(query.getQuery()); + + if(RunBookmarkTagHandler.requiresToRunBookmark(trimmedSql)) + { + sb.append(RunBookmarkTagHandler.toBookmarkSql(trimmedSql, _bookmarkManager)).append(tokenizer.getSQLStatementSeparator()); + changed = true; + } + else + { + sb.append(query.getOriginalQuery()).append(tokenizer.getSQLStatementSeparator()); + } + } + + + if(changed) + { + return sb.toString(); + } + else + { + return sql; + } } private CompleteBookmarkAction registerBookmarkSelectKeyStroke(ISQLPanelAPI sqlPaneAPI) @@ -350,12 +323,12 @@ protected void rebuildMenu() { ActionCollection coll = getApplication().getActionCollection(); - menu.removeAll(); - _resources.addToMenu(coll.get(AddBookmarkAction.class), menu); - _resources.addToMenu(coll.get(EditBookmarksAction.class), menu); - menu.add(new JSeparator()); + _menu.removeAll(); + _resources.addToMenu(coll.get(AddBookmarkAction.class), _menu); + _resources.addToMenu(coll.get(EditBookmarksAction.class), _menu); + _menu.add(new JSeparator()); - for (Iterator i = bookmarkManager.iterator(); i.hasNext();) + for (Iterator i = _bookmarkManager.iterator(); i.hasNext();) { Object o = i.next(); Bookmark bookmark = (Bookmark) o; @@ -388,9 +361,9 @@ private void createMenu() { IApplication app = getApplication(); - menu = _resources.createMenu(IMenuResourceKeys.BOOKMARKS); + _menu = _resources.createMenu(IMenuResourceKeys.BOOKMARKS); - app.addToMenu(IApplication.IMenuIDs.SESSION_MENU, menu); + app.addToMenu(IApplication.IMenuIDs.SESSION_MENU, _menu); } /** @@ -406,7 +379,7 @@ protected void addBookmarkItem(Bookmark bookmark) JMenuItem item = new JMenuItem(coll.get(RunBookmarkAction.class)); item.setText(bookmark.getName()); - menu.add(item); + _menu.add(item); } /** @@ -450,23 +423,23 @@ Properties getBookmarkProperties() FileInputStream fis = null; try { - if(null == _boomarkProps) + if(null == _bookmarkProps) { FileWrapper usf = getPluginUserSettingsFolder(); FileWrapper bookmarkPropsFile = fileWrapperFactory.create(usf, BOOKMARKS_PROPS_FILE); if(false == bookmarkPropsFile.exists()) { - _boomarkProps = new Properties(); + _bookmarkProps = new Properties(); } else { fis = bookmarkPropsFile.getFileInputStream(); - _boomarkProps = new Properties(); - _boomarkProps.load(fis); + _bookmarkProps = new Properties(); + _bookmarkProps.load(fis); } } - return _boomarkProps; + return _bookmarkProps; } catch (IOException e) { @@ -488,7 +461,7 @@ void saveBookmarkProperties() FileOutputStream fos = null; try { - if(null == _boomarkProps) + if(null == _bookmarkProps) { return; } @@ -496,7 +469,7 @@ void saveBookmarkProperties() FileWrapper usf = getPluginUserSettingsFolder(); FileWrapper boomarkPropsFile = fileWrapperFactory.create(usf, BOOKMARKS_PROPS_FILE); fos = boomarkPropsFile.getFileOutputStream(); - _boomarkProps.store(fos, "Bookmark properties"); + _bookmarkProps.store(fos, "Bookmark properties"); } catch (IOException e) { throw new RuntimeException(e); } finally { diff --git a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPreferencesPanel.java b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPreferencesPanel.java index 3759d42704..294b99daef 100644 --- a/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPreferencesPanel.java +++ b/sql12/plugins/sqlbookmark/src/net/sourceforge/squirrel_sql/plugins/sqlbookmark/SQLBookmarkPreferencesPanel.java @@ -80,9 +80,10 @@ private JPanel createSouthPane(SQLBookmarkPlugin plugin) gbc = new GridBagConstraints(0,3,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,5,5,5), 0,0); pnlSouth.add(createViewAsTreePanel(), gbc); - gbc = new GridBagConstraints(1,0,1,3,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0,0); - pnlSouth.add(new JPanel(), gbc); - + gbc = new GridBagConstraints(0,4,1,1,0,0,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,5,5,5), 0,0); + JLabel lblRunBookmark = new JLabel(s_stringMgr.getString("sqlbookmark.note.runbookmark")); + lblRunBookmark.setToolTipText(s_stringMgr.getString("sqlbookmark.note.runbookmark.tooltipp")); + pnlSouth.add(lblRunBookmark, gbc); return pnlSouth; } diff --git a/sql12/plugins/sqlparam/src/net/sourceforge/squirrel_sql/plugins/sqlparam/SQLParamExecutionListener.java b/sql12/plugins/sqlparam/src/net/sourceforge/squirrel_sql/plugins/sqlparam/SQLParamExecutionListener.java index f32b7b2c44..b3f371f62d 100644 --- a/sql12/plugins/sqlparam/src/net/sourceforge/squirrel_sql/plugins/sqlparam/SQLParamExecutionListener.java +++ b/sql12/plugins/sqlparam/src/net/sourceforge/squirrel_sql/plugins/sqlparam/SQLParamExecutionListener.java @@ -17,22 +17,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.SelectWidgetCommand; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.SwingUtilities; import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI; import net.sourceforge.squirrel_sql.client.session.event.SQLExecutionAdapter; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.sql.commentandliteral.SQLCommentRemover; import net.sourceforge.squirrel_sql.fw.sql.querytokenizer.QueryHolder; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; import net.sourceforge.squirrel_sql.plugins.sqlparam.gui.AskParamValueDialog; -import javax.swing.SwingUtilities; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * This listener listens for SQL execution. * @@ -136,7 +133,9 @@ public String statementExecuting(String sql) m.reset(); } - GUIUtils.processOnSwingEventThread(() -> new SelectWidgetCommand(_sqlPanelAPI.getSession().getActiveSessionWindow()).execute()); + + // Was removed because it messed with the feature https://github.com/squirrel-sql-client/squirrel-sql-code/issues/75 + //GUIUtils.processOnSwingEventThread(() -> new SelectWidgetCommand(_sqlPanelAPI.getSession().getActiveSessionWindow()).execute()); // log.info("SQL passing to execute: " + buffer.toString()); ////////////////////////////////////////////////////////////////// diff --git a/sql12/plugins/sqlreplace/src/net/sourceforge/squirrel_sql/plugins/sqlreplace/SQLReplaceExecutionListener.java b/sql12/plugins/sqlreplace/src/net/sourceforge/squirrel_sql/plugins/sqlreplace/SQLReplaceExecutionListener.java index b99d4fa8bf..9f1fcd1018 100644 --- a/sql12/plugins/sqlreplace/src/net/sourceforge/squirrel_sql/plugins/sqlreplace/SQLReplaceExecutionListener.java +++ b/sql12/plugins/sqlreplace/src/net/sourceforge/squirrel_sql/plugins/sqlreplace/SQLReplaceExecutionListener.java @@ -18,10 +18,8 @@ */ package net.sourceforge.squirrel_sql.plugins.sqlreplace; -import net.sourceforge.squirrel_sql.client.gui.desktopcontainer.SelectWidgetCommand; import net.sourceforge.squirrel_sql.client.session.ISession; import net.sourceforge.squirrel_sql.client.session.event.SQLExecutionAdapter; -import net.sourceforge.squirrel_sql.fw.gui.GUIUtils; import net.sourceforge.squirrel_sql.fw.sql.querytokenizer.QueryHolder; import net.sourceforge.squirrel_sql.fw.util.log.ILogger; import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; @@ -79,12 +77,13 @@ public String statementExecuting(String sql) { if (log.isDebugEnabled()) { log.debug("statementExecuting: replacedStmnt = "+replacedStmnt); } - - GUIUtils.processOnSwingEventThread(new Runnable() { - public void run() { - new SelectWidgetCommand(session.getActiveSessionWindow()).execute(); - } - }); + + // Was removed because it messed with the feature https://github.com/squirrel-sql-client/squirrel-sql-code/issues/75 + //GUIUtils.processOnSwingEventThread(new Runnable() { + // public void run() { + // new SelectWidgetCommand(session.getActiveSessionWindow()).execute(); + // } + //}); return replacedStmnt; } diff --git a/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ContentPlusTab.java b/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ContentPlusTab.java index 8ed426d41f..c3a3801724 100644 --- a/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ContentPlusTab.java +++ b/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ContentPlusTab.java @@ -29,7 +29,6 @@ import net.sourceforge.squirrel_sql.client.session.sqlfilter.OrderByClausePanel; import net.sourceforge.squirrel_sql.client.session.sqlfilter.SQLFilterClauses; import net.sourceforge.squirrel_sql.client.session.sqlfilter.WhereClausePanel; -import net.sourceforge.squirrel_sql.fw.datasetviewer.ColumnDisplayDefinition; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSet; import net.sourceforge.squirrel_sql.fw.datasetviewer.ResultSetDataSet; @@ -38,12 +37,11 @@ import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData; import net.sourceforge.squirrel_sql.fw.sql.ITableInfo; import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities; -import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo; import net.sourceforge.squirrel_sql.fw.sql.dbobj.BestRowIdentifier; -import net.sourceforge.squirrel_sql.fw.util.log.ILogger; -import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; +import net.sourceforge.squirrel_sql.fw.util.log.ILogger; +import net.sourceforge.squirrel_sql.fw.util.log.LoggerController; public class ContentPlusTab extends ContentsTab { @@ -237,9 +235,9 @@ protected IDataSet createDataSet() throws DataSetException // distinguish this table from other tables in the DB. // We also include the URL used to connect to the DB so that // the same table/DB on different machines is treated differently. - rsds.setContentsTabResultSet(rs, - _dataSetUpdateableTableModel.getFullTableName(), - DialectFactory.getDialectType(md)); + rsds.readDataFromJdbcResultSetForObjectTreeContentTabs(rs, + _dataSetUpdateableTableModel.getFullTableName(), + DialectFactory.getDialectType(md)); if (rs != null) { try { rs.close(); } catch (SQLException e) {} } diff --git a/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ProjectionTab.java b/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ProjectionTab.java index c929f60ede..e1fc3888cb 100644 --- a/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ProjectionTab.java +++ b/sql12/plugins/vertica/src/net/sourceforge/squirrel_sql/plugins/vertica/tab/ProjectionTab.java @@ -16,6 +16,10 @@ package net.sourceforge.squirrel_sql.plugins.vertica.tab; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + import net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs.table.BaseTableTab; import net.sourceforge.squirrel_sql.fw.datasetviewer.DataSetException; import net.sourceforge.squirrel_sql.fw.datasetviewer.IDataSet; @@ -28,10 +32,6 @@ import net.sourceforge.squirrel_sql.fw.util.StringManager; import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - /** * This tab shows the primary key info for the currently selected table. */ @@ -99,7 +99,7 @@ protected IDataSet createDataSet() throws DataSetException pstmt.setString(2, ti.getSimpleName()); rs = pstmt.executeQuery(); ResultSetDataSet rsds = new ResultSetDataSet(md.getColumnInfo(ti)); - rsds.setResultSet(rs, DialectFactory.getDialectType(md)); + rsds.readDataFromJdbcResultSetForGeneralPurpose(rs, DialectFactory.getDialectType(md)); return rsds; } diff --git a/sql12/web-site/faq.html b/sql12/web-site/faq.html index cd6d7f89a6..477698c34e 100755 --- a/sql12/web-site/faq.html +++ b/sql12/web-site/faq.html @@ -409,7 +409,7 @@

Which version of the JVM - 5.0.0 and higher + 5.1.0 and higher 17 diff --git a/sql12/web-site/header.html b/sql12/web-site/header.html index 53ab51c75a..98951bba99 100644 --- a/sql12/web-site/header.html +++ b/sql12/web-site/header.html @@ -18,7 +18,7 @@ Universal SQL Client - Version 5.0.0 + Version 5.1.0
diff --git a/sql12/web-site/home.html b/sql12/web-site/home.html index 66dcfe81ee..c682aae962 100755 --- a/sql12/web-site/home.html +++ b/sql12/web-site/home.html @@ -41,32 +41,20 @@

  -

Feature highlights of 5.0.0:

+

Feature highlights of 5.1.0:

    -
  • The Object tree's root node has a new detail tab named "Client Properties"
  • -
  • The Object tree didn't show tables when the JDBC driver didn't provide table types
  • -
  • Support for Java 25
  • -
  • SQL result table search now highlights results in cell detail display, too
  • -
  • Cell data image display offers to scale images to fit the display size
  • -
  • MS Excel exports offer to create tabs containing the exports' SQL statements
  • -
  • Improved memory footprint
  • -
  • Enhanced 'Copy separated by ...' function
  • -
  • Searching all open SQL results and cell data dialogs
  • -
  • Code completion for JOIN ON clauses
  • -
  • Cell data display highlights JSON and XML after reformatting
  • -
  • Choosing fonts for MS-Excel export
  • -
  • Aliases can be made read-only
  • -
  • SQL result tabs that match the current SQL in the editor are marked
  • -
  • SQL result's find function now offers to narrow the columns to search
  • -
  • SQL result's detail data display now allows to automatically reformat XML or Json
  • -
  • Numeric values can be right aligned
  • -
  • Export to MS-Excel allows to configure auto filtering
  • -
  • Header rows of MS-Excel exports can be made bold/centered/frozen
  • -
  • Option to change the statement separator during SQL execution using --#SET TERMINATOR <separator>
  • -
  • Besides sums, means and deviations can now be displayed for selections in numerical columns
  • -
  • New Alias tree icons which for FlatLaf Look and Feels show if top level folders are expanded or collapsed
  • +
  • Table columns can be toggled between a monospaced font and default font
  • +
  • Table cell contents can be concatenated without separator
  • +
  • SQL results can be rerun automatically after a configurable number of seconds
  • +
  • The SQL editor allows to run bookmarks by the syntax @runbookmark <bookmarkNameInSingleQuotes>
  • +
  • MS Excel file export allows to add or replace sheet-tabs in an MS Excel file
  • +
  • Option to execute SQL in multiple Sessions
  • +
  • Single click connect to multiple Aliases
  • +
  • Enhanced security for encrypting Alias passwords
  • +
  • "Copy as WIKI Table" - function of tables now supports copying the Jira/Cloud table format
  • +
  • User Bookmarks can be displayed as tree
- All new features and bug fixes of the 5.0.0 release can be found in our change log at + All new features and bug fixes of the 5.1.0 release can be found in our change log at SourceForge or GitHub. @@ -118,49 +106,56 @@

Feature highlights of 5.0.0:

Latest News

-

- SQuirreL 5.0.0 is released (09/18/2025).
- The list of feature highlights is rather long and can be found above.
- For all new features and bug fixes see our change log at SourceForge - or GitHub.
- Note that SQuirreL 5.0.0 requires at least Java 17.
-
- 5.0.0 releases on SourceForge:
- Download installer for Windows/Linux/others
- Download installer for Mac OS

- 5.0.0 releases on GitHub:
- Download installer for Windows/Linux/others
- Download installer for Mac OS

-

-
-

- The latest snapshot-20250824_2124 is one more candidate for the 5.0.0 release.
- Latest changes are
+

+ SQuirreL 5.1.0 is released (03/26/2026).
+ The list of feature highlights is rather long and can be found above.
+ For all new features and bug fixes see our change log at SourceForge + or GitHub.
+ Note that SQuirreL 5.1.0 requires at least Java 17.
+
+ 5.1.0 releases on SourceForge:
+ Download installer for Windows/Linux/others
+ Download installer for Mac OS

+ 5.1.0 releases on GitHub:
+ Download installer for Windows/Linux/others
+ Download installer for Mac OS
+

+
+

+ The latest snapshot-20260215_1841 is a release candidate for the 5.1.0 release.
+ Changes since the 5.0.0 release are

- - - + + + + + + + + + +
⇒ the Object tree's root node has new detail tab named "Client Properties"
⇒ the Object tree didn't show tables when the JDBC driver didn't provide table types
⇒ support for the upcoming Java 25 release
⇒ Table columns can be toggled between a monospaced font and default font
⇒ Table cell contents can be concatenated without separator
⇒ SQL results can be rerun automatically after a configurable number of seconds
⇒ The SQL editor allows to run bookmarks by the syntax @runbookmark <bookmarkNameInSingleQuotes>
⇒ MS Excel file export allows to add or replace sheet-tabs in an MS Excel file
⇒ Option to execute SQL in multiple Sessions
⇒ Single click connect to multiple Aliases
⇒ Enhanced security for encrypting Alias passwords
⇒ "Copy as WIKI Table" - function of tables now supports copying the Jira/Cloud table format
⇒ User Bookmarks can be displayed as tree
Please give it a try.

- The minimum required Java version for this snapshot is 17.x.

For all new features and bug fixes see our change log at SourceForge or GitHub.

- snapshot-20250824_2124 releases on SourceForge are:
- Download installer for Windows/Linux/others
- Download installer for Mac OS
- snapshot-20250824_2124 releases on GitHub are:
- Download installer for Windows/Linux/others
- Download installer for Mac OS

+ snapshot-20260215_1841 releases on SourceForge are:
+ Download installer for Windows/Linux/others
+ Download installer for Mac OS
+ snapshot-20260215_1841 releases on GitHub are:
+ Download installer for Windows/Linux/others
+ Download installer for Mac OS

-

+

Note: We don't announce every snapshot release here. If you are interested please check
https://github.com/squirrel-sql-client/squirrel-sql-snapshot-releases/releases
or
https://sourceforge.net/projects/squirrel-sql/files/3-snapshots
for the latest snapshots regularly.

+
  @@ -234,19 +229,19 @@

Available downloads are: