001: package net.sourceforge.squirrel_sql.client.session.mainpanel;
002:
003: import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI;
004: import net.sourceforge.squirrel_sql.client.session.ISession;
005: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
006: import net.sourceforge.squirrel_sql.fw.gui.SortableTableModel;
007: import net.sourceforge.squirrel_sql.fw.util.StringManager;
008: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
009:
010: import javax.swing.table.*;
011: import javax.swing.event.ListSelectionListener;
012: import javax.swing.event.ListSelectionEvent;
013: import javax.swing.*;
014: import java.util.ArrayList;
015: import java.util.prefs.Preferences;
016: import static java.lang.Math.*;
017: import java.awt.event.*;
018: import java.awt.*;
019:
020: public class SQLHistoryController {
021: private static final String PREF_KEY_SQL_HISTORY_COL_NAME_PREFIX_ = "Squirrel.sqlHistoryColIxPrefix_";
022:
023: @SuppressWarnings("unused")
024: private static final StringManager s_stringMgr = StringManagerFactory
025: .getStringManager(SQLHistoryController.class);
026:
027: private SQLHistoryDlg _dlg;
028: private ArrayList<SQLHistoryItemWrapper> _sqlHistoryItemWrappers;
029: private boolean _dontReactToChkFiltered;
030: private ISQLPanelAPI _sqlPanelAPI;
031:
032: private JPopupMenu _popUp = new JPopupMenu();
033:
034: @SuppressWarnings("serial")
035: public SQLHistoryController(ISession session,
036: ISQLPanelAPI sqlPanelAPI, ArrayList<SQLHistoryItem> items) {
037: _sqlPanelAPI = sqlPanelAPI;
038: _sqlHistoryItemWrappers = SQLHistoryItemWrapper.wrap(items);
039: _dlg = new SQLHistoryDlg(session.getApplication()
040: .getMainFrame(), session.getActiveSessionWindow()
041: .getTitle());
042:
043: GUIUtils.centerWithinParent(_dlg);
044:
045: _dlg.setVisible(true);
046:
047: _sqlPanelAPI.addSqlPanelListener(new SqlPanelListener() {
048: public void panelParentWindowClosing() {
049: _dlg.close();
050: }
051: });
052:
053: _dlg.addWindowListener(new WindowAdapter() {
054: boolean onWindowClosedCalled = false;
055:
056: public void windowClosed(WindowEvent e) {
057: if (false == onWindowClosedCalled) {
058: onWindowClosed();
059: }
060: }
061:
062: public void windowClosing(WindowEvent e) {
063: onWindowClosed();
064: onWindowClosedCalled = true;
065: }
066: });
067:
068: SortableTableModel stm = (SortableTableModel) _dlg.tblHistoryItems
069: .getModel();
070: ArrayList<SQLHistoryItemWrapper> copy = new ArrayList<SQLHistoryItemWrapper>(
071: _sqlHistoryItemWrappers);
072: SqlHistoryTableModel dtm = new SqlHistoryTableModel(copy, stm);
073: stm.setActualModel(dtm);
074:
075: final TableColumnModel tcm = new DefaultTableColumnModel();
076: _dlg.tblHistoryItems.setColumnModel(tcm);
077: for (int i = 0; i < SQLHistoryItemWrapper.getColumns().length; ++i) {
078: final TableColumn col = new TableColumn(i);
079: tcm.addColumn(col);
080: String header = SQLHistoryItemWrapper.getColumns()[i];
081: col.setHeaderValue(header);
082: col
083: .setPreferredWidth(Preferences.userRoot().getInt(
084: PREF_KEY_SQL_HISTORY_COL_NAME_PREFIX_
085: + header, 50));
086: }
087:
088: // i18n[SQLHistoryController.mnuAppendSelectionToEditor=Append selected statements to SQL editor]
089: JMenuItem mnuAppendSelectionToEditor = new JMenuItem(
090: "Append selected statements to SQL editor");
091: mnuAppendSelectionToEditor
092: .addActionListener(new ActionListener() {
093: public void actionPerformed(ActionEvent e) {
094: onAppendSelectionToEditor();
095: }
096: });
097: _popUp.add(mnuAppendSelectionToEditor);
098:
099: _dlg.tblHistoryItems.getSelectionModel()
100: .addListSelectionListener(new ListSelectionListener() {
101: public void valueChanged(ListSelectionEvent e) {
102: onTblSelectionChanged(e);
103: }
104: });
105:
106: _dlg.tblHistoryItems.addMouseListener(new MouseAdapter() {
107: public void mousePressed(MouseEvent evt) {
108: if (evt.getClickCount() == 2) {
109: onSQLSelected();
110: }
111: }
112: });
113:
114: _dlg.tblHistoryItems.addMouseListener(new MouseAdapter() {
115: public void mousePressed(MouseEvent evt) {
116: maybeShowPopup(evt);
117: }
118:
119: public void mouseReleased(MouseEvent e) {
120: maybeShowPopup(e);
121: }
122:
123: });
124:
125: _dlg.btnApplyFilter.addActionListener(new ActionListener() {
126: public void actionPerformed(ActionEvent e) {
127: onApplyFilter();
128: }
129: });
130:
131: _dlg.chkFiltered.addActionListener(new ActionListener() {
132: public void actionPerformed(ActionEvent e) {
133: onChckFiltered();
134: }
135: });
136:
137: _dlg.btnClose.addActionListener(new ActionListener() {
138: public void actionPerformed(ActionEvent e) {
139: closeAndSetFocus();
140: }
141: });
142:
143: AbstractAction closeAction = new AbstractAction() {
144: public void actionPerformed(ActionEvent actionEvent) {
145: closeAndSetFocus();
146: }
147: };
148:
149: KeyStroke escapeStroke = KeyStroke.getKeyStroke(
150: KeyEvent.VK_ESCAPE, 0);
151: _dlg.getRootPane().getInputMap(
152: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
153: escapeStroke, "CloseAction");
154: _dlg.getRootPane().getInputMap(
155: JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeStroke,
156: "CloseAction");
157: _dlg.getRootPane().getInputMap(JComponent.WHEN_FOCUSED).put(
158: escapeStroke, "CloseAction");
159: _dlg.getRootPane().getActionMap().put("CloseAction",
160: closeAction);
161:
162: }
163:
164: private void maybeShowPopup(MouseEvent evt) {
165: if (evt.isPopupTrigger()) {
166: _popUp.show(evt.getComponent(), evt.getX(), evt.getY());
167: }
168: }
169:
170: private void closeAndSetFocus() {
171: _dlg.close();
172: _sqlPanelAPI.getSQLEntryPanel().requestFocus();
173: }
174:
175: private void onAppendSelectionToEditor() {
176: int[] selRows = _dlg.tblHistoryItems.getSelectedRows();
177:
178: if (0 < selRows.length) {
179: for (int i = 0; i < selRows.length; i++) {
180: _sqlPanelAPI.getSQLEntryPanel().appendText(
181: "\n" + getSQLFromRow(selRows[i]) + "\n");
182: }
183: }
184: }
185:
186: private void onSQLSelected() {
187: int[] selRows = _dlg.tblHistoryItems.getSelectedRows();
188:
189: if (1 == selRows.length) {
190: _sqlPanelAPI.getSQLEntryPanel().appendText(
191: "\n" + getSQLFromRow(selRows[0]));
192: closeAndSetFocus();
193: }
194: }
195:
196: private void onChckFiltered() {
197: if (_dontReactToChkFiltered) {
198: return;
199: }
200:
201: if (_dlg.chkFiltered.isSelected()) {
202: onApplyFilter();
203: } else {
204: SortableTableModel stm = (SortableTableModel) _dlg.tblHistoryItems
205: .getModel();
206: SqlHistoryTableModel tm = (SqlHistoryTableModel) stm
207: .getActualModel();
208:
209: ArrayList<SQLHistoryItemWrapper> clone = new ArrayList<SQLHistoryItemWrapper>(
210: _sqlHistoryItemWrappers);
211: tm.setData(clone);
212: }
213: }
214:
215: private void onApplyFilter() {
216: SortableTableModel stm = (SortableTableModel) _dlg.tblHistoryItems
217: .getModel();
218: SqlHistoryTableModel tm = (SqlHistoryTableModel) stm
219: .getActualModel();
220:
221: if (_dlg.chkFiltered.isSelected()) {
222: ArrayList<SQLHistoryItemWrapper> clone = new ArrayList<SQLHistoryItemWrapper>(
223: _sqlHistoryItemWrappers);
224: tm.setData(clone);
225: }
226:
227: ArrayList<SQLHistoryItemWrapper> toRemove = new ArrayList<SQLHistoryItemWrapper>();
228: for (SQLHistoryItemWrapper itemWrapper : tm.getData()) {
229: if (false == matchesFilter(itemWrapper)) {
230: toRemove.add(itemWrapper);
231: }
232: }
233:
234: boolean filtered;
235: if (0 < toRemove.size()) {
236: tm.removeData(toRemove);
237: filtered = true;
238: } else {
239: filtered = false;
240: }
241:
242: try {
243: _dontReactToChkFiltered = true;
244: _dlg.chkFiltered.setSelected(filtered);
245: } finally {
246: _dontReactToChkFiltered = false;
247: }
248: }
249:
250: private boolean matchesFilter(SQLHistoryItemWrapper itemWrapper) {
251: String filter = _dlg.txtFilter.getText();
252:
253: if (null == filter || 0 == filter.length()) {
254: return true;
255: }
256:
257: String ucfilter;
258:
259: SQLHistoryDlg.FilterCboItems sel = (SQLHistoryDlg.FilterCboItems) _dlg.cboFilterItems
260: .getSelectedItem();
261: switch (sel) {
262: case CONTAINS:
263: ucfilter = filter.toUpperCase();
264: return -1 < itemWrapper.getUpperCaseSQL().indexOf(ucfilter);
265: case STARTS_WITH:
266: ucfilter = filter.toUpperCase();
267: return itemWrapper.getUpperCaseSQL().startsWith(ucfilter);
268: case ENDS_WITH:
269: ucfilter = filter.toUpperCase();
270: return itemWrapper.getUpperCaseSQL().endsWith(ucfilter);
271: case REG_EX:
272: return itemWrapper.getUpperCaseSQL().matches(filter);
273: }
274:
275: throw new IllegalArgumentException(
276: "How can I ever get here?????");
277: }
278:
279: private void onTblSelectionChanged(ListSelectionEvent e) {
280: if (e.getValueIsAdjusting()) {
281: return;
282: }
283:
284: int[] selRows = _dlg.tblHistoryItems.getSelectedRows();
285:
286: if (1 == selRows.length) {
287: _dlg.txtSQL.setText(getSQLFromRow(selRows[0]));
288:
289: SwingUtilities.invokeLater(new Runnable() {
290: public void run() {
291: _dlg.txtSQL.scrollRectToVisible(new Rectangle(0, 0,
292: 1, 1));
293: }
294: });
295:
296: } else {
297: _dlg.txtSQL.setText(null);
298: }
299: }
300:
301: private String getSQLFromRow(int row) {
302: TableModel tm = _dlg.tblHistoryItems.getModel();
303:
304: return (String) tm.getValueAt(row, SQLHistoryItemWrapper
305: .getSQLColIx());
306:
307: }
308:
309: private void onWindowClosed() {
310: TableColumnModel tcm = _dlg.tblHistoryItems.getColumnModel();
311: for (int i = 0; i < tcm.getColumnCount(); i++) {
312: TableColumn col = tcm.getColumn(i);
313: Preferences.userRoot().putInt(
314: PREF_KEY_SQL_HISTORY_COL_NAME_PREFIX_
315: + col.getHeaderValue(),
316: max(col.getWidth(), 10));
317: }
318: }
319:
320: @SuppressWarnings("serial")
321: private static class SqlHistoryTableModel extends DefaultTableModel {
322: private ArrayList<SQLHistoryItemWrapper> _tempSqlHistoryItemWrappers;
323: private SortableTableModel _parent;
324:
325: public SqlHistoryTableModel(
326: ArrayList<SQLHistoryItemWrapper> tempsqlHistoryItemWrappers,
327: SortableTableModel parent) {
328: _tempSqlHistoryItemWrappers = tempsqlHistoryItemWrappers;
329: _parent = parent;
330: }
331:
332: public boolean isCellEditable(int row, int column) {
333: return false;
334: }
335:
336: public Object getValueAt(int row, int column) {
337: return _tempSqlHistoryItemWrappers.get(row)
338: .getColum(column);
339: }
340:
341: public String getColumnName(int column) {
342: return SQLHistoryItemWrapper.getColumns()[column];
343: }
344:
345: public int getRowCount() {
346: if (null == _tempSqlHistoryItemWrappers) {
347: // I have seen the reference to the outer class being null
348: // when this method is called.
349: // I have seen it only with the runtime jars
350: // and on Linux.
351: // I could not reproduce in my IDE.
352: return 0;
353: } else {
354: return _tempSqlHistoryItemWrappers.size();
355: }
356: }
357:
358: public int getColumnCount() {
359: return SQLHistoryItemWrapper.getColumns().length;
360: }
361:
362: ArrayList<SQLHistoryItemWrapper> getData() {
363: return _tempSqlHistoryItemWrappers;
364: }
365:
366: public void setData(
367: ArrayList<SQLHistoryItemWrapper> sqlHistoryItemWrappers) {
368: _tempSqlHistoryItemWrappers = sqlHistoryItemWrappers;
369: _parent.tableChanged();
370: }
371:
372: public void removeData(ArrayList<SQLHistoryItemWrapper> toRemove) {
373: _tempSqlHistoryItemWrappers.removeAll(toRemove);
374: _parent.tableChanged();
375: }
376: }
377: }
|