001: package net.sourceforge.squirrel_sql.plugins.syntax;
002:
003: /*
004: * Copyright (C) 2003 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021: import java.awt.*;
022: import java.awt.event.ActionListener;
023: import java.awt.event.ActionEvent;
024:
025: import javax.swing.*;
026: import javax.swing.event.ChangeEvent;
027: import javax.swing.event.ChangeListener;
028: import javax.swing.event.ListSelectionEvent;
029: import javax.swing.event.ListSelectionListener;
030:
031: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
032: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
033: import net.sourceforge.squirrel_sql.fw.util.StringManager;
034: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
035: import net.sourceforge.squirrel_sql.fw.gui.MultipleLineLabel;
036:
037: import net.sourceforge.squirrel_sql.client.IApplication;
038: import net.sourceforge.squirrel_sql.client.preferences.INewSessionPropertiesPanel;
039: import net.sourceforge.squirrel_sql.client.session.ISession;
040: import net.sourceforge.squirrel_sql.client.session.properties.ISessionPropertiesPanel;
041:
042: import net.sourceforge.squirrel_sql.plugins.syntax.prefspanel.StyleMaintenancePanel;
043: import net.sourceforge.squirrel_sql.plugins.syntax.prefspanel.StylesList;
044:
045: /**
046: * New Session and Current Session preferences panel for this plugin.
047: *
048: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
049: */
050: public class SyntaxPreferencesPanel implements
051: INewSessionPropertiesPanel, ISessionPropertiesPanel {
052: private static final StringManager s_stringMgr = StringManagerFactory
053: .getStringManager(SyntaxPreferencesPanel.class);
054:
055: /** Logger for this class. */
056: private static final ILogger s_log = LoggerController
057: .createLogger(SyntaxPreferencesPanel.class);
058:
059: /** Plugin preferences object. */
060: private final SyntaxPreferences _prefs;
061:
062: /** Component to display in the preferences dialog. */
063: private final MyPanel _myPanel;
064:
065: /**
066: * Ctor.
067: *
068: * @param prefs The preferences to be maintained.
069: *
070: * @throws IllegalArgumentException
071: * if <TT>prefs</TT> is <TT>null</TT>.
072: */
073: public SyntaxPreferencesPanel(SyntaxPreferences prefs,
074: SyntaxPluginResources rsrc) {
075: super ();
076: if (prefs == null) {
077: throw new IllegalArgumentException(
078: "Null SyntaxPreferences passed");
079: }
080: _prefs = prefs;
081:
082: // Create the actual panel that will be displayed in dialog.
083: _myPanel = new MyPanel(prefs, rsrc);
084: }
085:
086: /**
087: * Panel is being loaded for the Application Preferences. This means that
088: * the settings are for newly created sessions.
089: *
090: * @param app Application API.
091: */
092: public void initialize(IApplication app) {
093: _myPanel.loadData(_prefs);
094: }
095:
096: /**
097: * Panel is being loaded for the Session Properties. This means that
098: * the settings are for the current session only.
099: *
100: * @param app Application API.
101: *
102: * @throws IllegalArgumentException
103: * if <TT>IApplication</TT> is <TT>null</TT>.
104: */
105: public void initialize(IApplication app, ISession session) {
106: if (app == null) {
107: throw new IllegalArgumentException(
108: "Null IApplication passed");
109: }
110: if (session == null) {
111: throw new IllegalArgumentException("Null ISession passed");
112: }
113:
114: _myPanel.loadData(_prefs);
115: }
116:
117: /**
118: * Return the component to be displayed in the Preferences dialog.
119: *
120: * @return the component to be displayed in the Preferences dialog.
121: */
122: public Component getPanelComponent() {
123: return _myPanel;
124: }
125:
126: /**
127: * User has pressed OK or Apply in the dialog so save data from
128: * panel.
129: */
130: public void applyChanges() {
131: _myPanel.applyChanges(_prefs);
132: }
133:
134: /**
135: * Return the title for this panel.
136: *
137: * @return the title for this panel.
138: */
139: public String getTitle() {
140: return MyPanel.i18n.TAB_TITLE;
141: }
142:
143: /**
144: * Return the hint for this panel.
145: *
146: * @return the hint for this panel.
147: */
148: public String getHint() {
149: return MyPanel.i18n.TAB_HINT;
150: }
151:
152: /**
153: * Component to be displayed in the preferences dialog.
154: */
155: private final static class MyPanel extends JPanel {
156: /**
157: * This interface defines locale specific strings. This should be
158: * replaced with a property file.
159: */
160: interface i18n {
161: // i18n[syntax.prefSyntax=Syntax]
162: String TAB_TITLE = s_stringMgr
163: .getString("syntax.prefSyntax");
164: // i18n[syntax.prefSyntaxHint=Syntax Highlighting]
165: String TAB_HINT = s_stringMgr
166: .getString("syntax.prefSyntaxHint");
167: // i18n[syntax.prefUseNetbeans=Use Netbeans editor (recommended)]
168: String NETBEANS = s_stringMgr
169: .getString("syntax.prefUseNetbeans");
170: // i18n[syntax.prefUseOster=Use Ostermiller editor]
171: String OSTER = s_stringMgr.getString("syntax.prefUseOster");
172: // i18n[syntax.prefUsePlain=Use plain editor]
173: String PLAIN = s_stringMgr.getString("syntax.prefUsePlain");
174:
175: // i18n[syntax.textLimitLineVisible=Show text limit line]
176: String TEXT_LIMIT_LINE_VISIBLE = s_stringMgr
177: .getString("syntax.textLimitLineVisible");
178: // i18n[syntax.textLimitLineWidth=Text limit line width]
179: String TEXT_LIMIT_LINE_WIDTH = s_stringMgr
180: .getString("syntax.textLimitLineWidth");
181:
182: }
183:
184: private final JRadioButton _netbeansActiveOpt = new JRadioButton(
185: i18n.NETBEANS);
186: private final JRadioButton _osterActiveOpt = new JRadioButton(
187: i18n.OSTER);
188: private final JRadioButton _plainActiveOpt = new JRadioButton(
189: i18n.PLAIN);
190:
191: private final JCheckBox _chkTextLimitLineVisible = new JCheckBox(
192: i18n.TEXT_LIMIT_LINE_VISIBLE);
193: private final JTextField _txtTextLimitLineWidth = new JTextField();
194:
195: private StylesListSelectionListener _listLis;
196:
197: private final StylesList _stylesList = new StylesList();
198:
199: private StyleMaintenancePanel _styleMaintPnl;
200:
201: MyPanel(SyntaxPreferences prefs, SyntaxPluginResources rsrc) {
202: super ();
203: createUserInterface(prefs, rsrc);
204: }
205:
206: /**
207: * Component has been added to its parent so setup listeners etc.
208: */
209: public void addNotify() {
210: super .addNotify();
211:
212: if (_listLis == null) {
213: _listLis = new StylesListSelectionListener();
214: _stylesList.addListSelectionListener(_listLis);
215: }
216: }
217:
218: /**
219: * Component has been removed from its parent so remove listeners etc.
220: */
221: public void removeNotify() {
222: super .removeNotify();
223: if (_listLis != null) {
224: _stylesList.removeListSelectionListener(_listLis);
225: _listLis = null;
226: }
227: }
228:
229: void loadData(SyntaxPreferences prefs) {
230: _osterActiveOpt.setSelected(prefs.getUseOsterTextControl());
231: _netbeansActiveOpt.setSelected(prefs
232: .getUseNetbeansTextControl());
233: _plainActiveOpt.setSelected(prefs.getUsePlainTextControl());
234:
235: _chkTextLimitLineVisible.setSelected(prefs
236: .isTextLimitLineVisible());
237:
238: _txtTextLimitLineWidth.setText(""
239: + prefs.getTextLimitLineWidth());
240:
241: _stylesList.loadData(prefs);
242: _styleMaintPnl.setStyle(_stylesList
243: .getSelectedSyntaxStyle());
244:
245: updateControlStatus();
246: }
247:
248: void applyChanges(SyntaxPreferences prefs) {
249: boolean oldUseNetbeansTextControl = prefs
250: .getUseNetbeansTextControl();
251: boolean oldUseOsterTextControl = prefs
252: .getUseOsterTextControl();
253: boolean oldUsePlainTextControl = prefs
254: .getUsePlainTextControl();
255:
256: try {
257: prefs.setUseNetbeansTextControl(_netbeansActiveOpt
258: .isSelected());
259: prefs.setUseOsterTextControl(_osterActiveOpt
260: .isSelected());
261: prefs.setUsePlainTextControl(_plainActiveOpt
262: .isSelected());
263: } catch (SyntaxPrefChangeNotSupportedException e) {
264: prefs
265: .setUseNetbeansTextControl(oldUseNetbeansTextControl);
266: prefs.setUseOsterTextControl(oldUseOsterTextControl);
267: prefs.setUsePlainTextControl(oldUsePlainTextControl);
268: }
269:
270: prefs.setTextLimitLineVisible(_chkTextLimitLineVisible
271: .isSelected());
272:
273: int limit = 80;
274:
275: try {
276: int buf = Integer.parseInt(_txtTextLimitLineWidth
277: .getText());
278:
279: if (0 < buf && buf < 1000) {
280: limit = buf;
281: } else {
282: s_log.error("Invalid text limit widht: "
283: + _txtTextLimitLineWidth.getText());
284: }
285: } catch (NumberFormatException e) {
286: s_log.error("Invalid text limit widht: "
287: + _txtTextLimitLineWidth.getText(), e);
288: }
289:
290: prefs.setTextLimitLineWidth(limit);
291:
292: prefs
293: .setColumnStyle(_stylesList
294: .getSyntaxStyleAt(StylesList.IStylesListIndices.COLUMNS));
295: prefs
296: .setCommentStyle(_stylesList
297: .getSyntaxStyleAt(StylesList.IStylesListIndices.COMMENTS));
298: prefs
299: .setErrorStyle(_stylesList
300: .getSyntaxStyleAt(StylesList.IStylesListIndices.ERRORS));
301: prefs
302: .setFunctionStyle(_stylesList
303: .getSyntaxStyleAt(StylesList.IStylesListIndices.FUNCTIONS));
304: prefs
305: .setIdentifierStyle(_stylesList
306: .getSyntaxStyleAt(StylesList.IStylesListIndices.IDENTIFIERS));
307: prefs
308: .setLiteralStyle(_stylesList
309: .getSyntaxStyleAt(StylesList.IStylesListIndices.LITERALS));
310: prefs
311: .setOperatorStyle(_stylesList
312: .getSyntaxStyleAt(StylesList.IStylesListIndices.OPERATORS));
313: prefs
314: .setReservedWordStyle(_stylesList
315: .getSyntaxStyleAt(StylesList.IStylesListIndices.RESERVED_WORDS));
316: prefs
317: .setSeparatorStyle(_stylesList
318: .getSyntaxStyleAt(StylesList.IStylesListIndices.SEPARATORS));
319: prefs
320: .setTableStyle(_stylesList
321: .getSyntaxStyleAt(StylesList.IStylesListIndices.TABLES));
322: prefs
323: .setWhiteSpaceStyle(_stylesList
324: .getSyntaxStyleAt(StylesList.IStylesListIndices.WHITE_SPACE));
325: prefs
326: .setDataTypeStyle(_stylesList
327: .getSyntaxStyleAt(StylesList.IStylesListIndices.DATA_TYPES));
328: }
329:
330: private void updateControlStatus() {
331: final boolean useOsterControl = _osterActiveOpt
332: .isSelected();
333: final boolean useNetbeansControl = _netbeansActiveOpt
334: .isSelected();
335: final boolean usePlainControl = _plainActiveOpt
336: .isSelected();
337:
338: _stylesList.setEnabled(useOsterControl
339: || useNetbeansControl);
340: _styleMaintPnl.setEnabled(useOsterControl
341: || useNetbeansControl);
342:
343: _chkTextLimitLineVisible.setEnabled(useNetbeansControl);
344: _txtTextLimitLineWidth.setEnabled(useNetbeansControl);
345:
346: if (useNetbeansControl) {
347: _txtTextLimitLineWidth
348: .setEnabled(_chkTextLimitLineVisible
349: .isSelected());
350: }
351: }
352:
353: private void createUserInterface(SyntaxPreferences prefs,
354: SyntaxPluginResources rsrc) {
355: setLayout(new GridBagLayout());
356: GridBagConstraints gbc;
357:
358: ButtonGroup bg = new ButtonGroup();
359: bg.add(_netbeansActiveOpt);
360: bg.add(_osterActiveOpt);
361: bg.add(_plainActiveOpt);
362:
363: _osterActiveOpt.addChangeListener(new ChangeListener() {
364: public void stateChanged(ChangeEvent evt) {
365: updateControlStatus();
366: }
367: });
368:
369: _netbeansActiveOpt.addChangeListener(new ChangeListener() {
370: public void stateChanged(ChangeEvent evt) {
371: updateControlStatus();
372: }
373: });
374:
375: _plainActiveOpt.addChangeListener(new ChangeListener() {
376: public void stateChanged(ChangeEvent evt) {
377: updateControlStatus();
378: }
379: });
380:
381: _chkTextLimitLineVisible
382: .addActionListener(new ActionListener() {
383: public void actionPerformed(ActionEvent e) {
384: updateControlStatus();
385: }
386: });
387:
388: // i18n[syntax.osterExplain=Note: The preferable editor is the Netbeans editor. The Netbeans editor\n
389: //- is less memory consuming,\n
390: //- its highlightning is more exact,\n
391: //- can handle many lines well.\n
392: // The Oster editor is still there
393: // because it can handle
394: // very long lines better than the
395: // Netbeans editor.
396: // This is due to a known bug in
397: // the Netbeans editor (Issue #41241).
398: // As soon as this bug is fixed
399: // the Oster editor will be removed.]
400: String text = s_stringMgr.getString("syntax.osterExplain");
401: gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0,
402: GridBagConstraints.NORTHWEST,
403: GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0,
404: 0);
405: add(new MultipleLineLabel(text), gbc);
406:
407: gbc = new GridBagConstraints(0, 1, 1, 1, 0, 0,
408: GridBagConstraints.NORTHWEST,
409: GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0,
410: 0);
411: add(createOptionsPanel(), gbc);
412:
413: gbc = new GridBagConstraints(1, 0, 1, 2, 0, 0,
414: GridBagConstraints.NORTHWEST,
415: GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,
416: 0);
417: add(createStylePanel(rsrc), gbc);
418:
419: gbc = new GridBagConstraints(0, 2, 2, 1, 1, 1,
420: GridBagConstraints.NORTHWEST,
421: GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0,
422: 0);
423: add(new JPanel(), gbc);
424:
425: }
426:
427: private JPanel createOptionsPanel() {
428: JPanel pnlRet = new JPanel(new GridBagLayout());
429:
430: GridBagConstraints gbc;
431:
432: gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0,
433: GridBagConstraints.NORTHWEST,
434: GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,
435: 0);
436: pnlRet.add(_netbeansActiveOpt, gbc);
437:
438: gbc = new GridBagConstraints(0, 1, 1, 1, 0, 0,
439: GridBagConstraints.NORTHWEST,
440: GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0,
441: 0);
442: pnlRet.add(_osterActiveOpt, gbc);
443:
444: gbc = new GridBagConstraints(0, 2, 1, 1, 0, 0,
445: GridBagConstraints.NORTHWEST,
446: GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0,
447: 0);
448: pnlRet.add(_plainActiveOpt, gbc);
449:
450: JPanel pnlLineLimit = new JPanel(new GridBagLayout());
451: gbc = new GridBagConstraints(0, 3, 1, 1, 0, 0,
452: GridBagConstraints.NORTHWEST,
453: GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,
454: 0);
455: pnlRet.add(pnlLineLimit, gbc);
456:
457: gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0,
458: GridBagConstraints.WEST, GridBagConstraints.NONE,
459: new Insets(0, 0, 5, 5), 0, 0);
460: pnlLineLimit.add(_chkTextLimitLineVisible, gbc);
461:
462: gbc = new GridBagConstraints(1, 0, 1, 1, 0, 0,
463: GridBagConstraints.WEST, GridBagConstraints.NONE,
464: new Insets(0, 5, 5, 5), 0, 0);
465: pnlLineLimit.add(new JLabel(i18n.TEXT_LIMIT_LINE_WIDTH),
466: gbc);
467:
468: _txtTextLimitLineWidth.setColumns(3);
469: gbc = new GridBagConstraints(2, 0, 1, 1, 0, 0,
470: GridBagConstraints.WEST, GridBagConstraints.NONE,
471: new Insets(0, 0, 5, 5), 0, 0);
472: pnlLineLimit.add(_txtTextLimitLineWidth, gbc);
473:
474: return pnlRet;
475: }
476:
477: private JPanel createStylePanel(SyntaxPluginResources rsrc) {
478: JPanel pnl = new JPanel(new BorderLayout());
479: // i18n[syntax.styles=Syntax Styles]
480: pnl.setBorder(BorderFactory.createTitledBorder(s_stringMgr
481: .getString("syntax.styles")));
482:
483: _styleMaintPnl = new StyleMaintenancePanel(_stylesList,
484: rsrc);
485:
486: pnl.add(_styleMaintPnl, BorderLayout.NORTH);
487: pnl.add(_stylesList, BorderLayout.CENTER);
488:
489: return pnl;
490: }
491:
492: /**
493: * Selection listener for the Styles List. As selection changes in the
494: * list then update the maintenance panel to reflect the current
495: * selected style.
496: */
497: private class StylesListSelectionListener implements
498: ListSelectionListener {
499: public void valueChanged(ListSelectionEvent evt) {
500: _styleMaintPnl.setStyle(((StylesList) evt.getSource())
501: .getSelectedSyntaxStyle());
502: }
503: }
504: }
505: }
|