001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
013: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
014: //
015: //All Rights Reserved.
016:
017: package org.columba.core.gui.config;
018:
019: import java.awt.BorderLayout;
020: import java.awt.Font;
021: import java.awt.GridLayout;
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.awt.event.KeyEvent;
025: import java.util.Locale;
026: import java.util.Properties;
027:
028: import javax.swing.BorderFactory;
029: import javax.swing.DefaultComboBoxModel;
030: import javax.swing.JButton;
031: import javax.swing.JCheckBox;
032: import javax.swing.JComboBox;
033: import javax.swing.JComponent;
034: import javax.swing.JDialog;
035: import javax.swing.JFrame;
036: import javax.swing.JLabel;
037: import javax.swing.JOptionPane;
038: import javax.swing.JPanel;
039: import javax.swing.KeyStroke;
040: import javax.swing.SwingConstants;
041:
042: import org.columba.api.gui.frame.IContainer;
043: import org.columba.api.plugin.IExtension;
044: import org.columba.api.plugin.IExtensionHandler;
045: import org.columba.api.plugin.IExtensionHandlerKeys;
046: import org.columba.api.plugin.PluginHandlerNotFoundException;
047: import org.columba.api.plugin.PluginLoadingFailedException;
048: import org.columba.core.config.Config;
049: import org.columba.core.config.GuiItem;
050: import org.columba.core.gui.base.ButtonWithMnemonic;
051: import org.columba.core.gui.base.CheckBoxWithMnemonic;
052: import org.columba.core.gui.base.LabelWithMnemonic;
053: import org.columba.core.gui.base.SingleSideEtchedBorder;
054: import org.columba.core.gui.dialog.FontSelectionDialog;
055: import org.columba.core.gui.frame.FrameManager;
056: import org.columba.core.gui.plugin.ConfigurationDialog;
057: import org.columba.core.gui.themes.ThemeSwitcher;
058: import org.columba.core.gui.util.DialogHeaderPanel;
059: import org.columba.core.gui.util.FontProperties;
060: import org.columba.core.help.HelpManager;
061: import org.columba.core.plugin.PluginManager;
062: import org.columba.core.resourceloader.GlobalResourceLoader;
063: import org.columba.core.xml.XmlElement;
064:
065: import com.jgoodies.forms.builder.DefaultFormBuilder;
066: import com.jgoodies.forms.layout.FormLayout;
067:
068: /**
069: * Shows a dialog for managing general options such as font settings.
070: */
071:
072: public class GeneralOptionsDialog extends JDialog implements
073: ActionListener {
074: private static final String RESOURCE_PATH = "org.columba.core.i18n.dialog";
075:
076: // button panel
077: protected JButton okButton;
078:
079: protected JButton cancelButton;
080:
081: protected JButton helpButton;
082:
083: // look and feel
084: protected JLabel lfLabel;
085:
086: protected JComboBox lfComboBox;
087:
088: protected JButton lfButton;
089:
090: private String theme = null;
091:
092: private IExtensionHandler handler;
093:
094: // fonts
095: protected JCheckBox overwriteCheckBox;
096:
097: protected JLabel mainFontLabel;
098:
099: protected JLabel textFontLabel;
100:
101: protected JButton mainFontButton;
102:
103: protected JButton textFontButton;
104:
105: private Font mainFont;
106:
107: private Font textFont;
108:
109: // toolbar
110: protected JLabel toolbarLabel;
111:
112: protected JComboBox toolbarComboBox;
113:
114: // language
115: protected JLabel languageLabel;
116:
117: protected JComboBox languageComboBox;
118:
119: protected JFrame frame;
120:
121: protected IExtensionHandler configHandler;
122:
123: // HTTP proxy
124: protected JLabel proxyLabel;
125:
126: protected JButton proxyButton;
127:
128: protected String proxyHost;
129:
130: protected int proxyPort;
131:
132: // ID of configuration plugin of this theme plugin
133: protected String configID;
134:
135: private boolean restartRequired = false;
136:
137: private String oldLookAndFeelName;
138:
139: public GeneralOptionsDialog(JFrame frame) {
140: super (frame, GlobalResourceLoader.getString(RESOURCE_PATH,
141: "general", "dialog_title"), true);
142:
143: this .frame = frame;
144:
145: try {
146: // get theme plugin-handler
147: handler = PluginManager.getInstance().getExtensionHandler(
148: IExtensionHandlerKeys.ORG_COLUMBA_CORE_THEME);
149: } catch (PluginHandlerNotFoundException ex) {
150: ex.printStackTrace();
151: }
152:
153: try {
154: // get config plugin-handler
155: configHandler = PluginManager
156: .getInstance()
157: .getExtensionHandler(
158: IExtensionHandlerKeys.ORG_COLUMBA_CORE_CONFIG);
159: } catch (PluginHandlerNotFoundException ex) {
160: ex.printStackTrace();
161: }
162:
163: initComponents();
164: layoutComponents();
165: updateComponents(true);
166:
167: pack();
168: setLocationRelativeTo(null);
169: setVisible(true);
170: }
171:
172: public void updateComponents(boolean b) {
173:
174: GuiItem item = ((Config) Config.getInstance())
175: .getOptionsConfig().getGuiItem();
176:
177: if (b) {
178: // look and feel
179: theme = item.getString(GuiItem.THEME, GuiItem.NAME);
180: oldLookAndFeelName = theme;
181:
182: lfComboBox.setSelectedItem(theme);
183:
184: // fonts
185: String mainName = item.getStringWithDefault(
186: GuiItem.FONT_MAIN, GuiItem.NAME, "default");
187: int mainSize = item.getIntegerWithDefault(
188: GuiItem.FONT_MAIN, GuiItem.SIZE_INT, 12);
189: mainFont = new Font(mainName, Font.PLAIN, mainSize);
190:
191: String textName = item.getStringWithDefault(
192: GuiItem.FONT_TEXT, GuiItem.NAME, "default");
193: int textSize = item.getIntegerWithDefault(
194: GuiItem.FONT_TEXT, GuiItem.SIZE_INT, 12);
195: textFont = new Font(textName, Font.PLAIN, textSize);
196:
197: mainFontButton.setText(mainName);
198: mainFontButton.setFont(mainFont);
199: textFontButton.setText(textName);
200: textFontButton.setFont(textFont);
201:
202: boolean overwrite = item.getBooleanWithDefault(
203: GuiItem.FONT, GuiItem.OVERWRITE_BOOL, false);
204:
205: overwriteCheckBox.setSelected(overwrite);
206:
207: // enable/disable button, too
208: textFontButton.setEnabled(overwrite);
209: textFontLabel.setEnabled(overwrite);
210: mainFontButton.setEnabled(overwrite);
211: mainFontLabel.setEnabled(overwrite);
212:
213: // language
214: Locale[] available = GlobalResourceLoader
215: .getAvailableLocales();
216: languageComboBox.setModel(new DefaultComboBoxModel(
217: available));
218:
219: // select Locale in ComboBox
220: for (int i = 0; i < available.length; i++) {
221: if (available[i].equals(Locale.getDefault())) {
222: languageComboBox.setSelectedIndex(i);
223: break;
224: }
225: }
226:
227: boolean enableText = item.getBooleanWithDefault(
228: GuiItem.TOOLBAR, GuiItem.ENABLE_TEXT_BOOL, true);
229:
230: boolean alignment = item.getBooleanWithDefault(
231: GuiItem.TOOLBAR, GuiItem.TEXT_POSITION_BOOL, true);
232:
233: if (enableText) {
234: toolbarComboBox.setSelectedIndex(alignment ? 1 : 2);
235: }
236:
237: proxyHost = System.getProperty("http.proxyHost");
238: String proxyPortString = System.getProperty(
239: "http.proxyPort", "-1");
240: proxyPort = Integer.parseInt(proxyPortString);
241: updateProxyButtonText();
242: } else {
243: // fonts
244: item.setString(GuiItem.FONT_MAIN, GuiItem.NAME,
245: getMainFont().getName());
246: item.setInteger(GuiItem.FONT_MAIN, GuiItem.SIZE_INT,
247: getMainFont().getSize());
248:
249: item.setString(GuiItem.FONT_TEXT, GuiItem.NAME,
250: getTextFont().getName());
251: item.setInteger(GuiItem.FONT_TEXT, GuiItem.SIZE_INT,
252: getTextFont().getSize());
253:
254: item.setBoolean(GuiItem.FONT, GuiItem.OVERWRITE_BOOL,
255: overwriteCheckBox.isSelected());
256:
257: // notify all listeners
258: // @see org.columba.core.gui.util.FontProperties
259: // @see org.columba.mail.gui.message.TextViewer
260: // @see org.columba.mail.gui.composer.text.TextEditorController
261: item.getElement("fonts").notifyObservers();
262:
263: // look and feel
264: item.setString(GuiItem.THEME, GuiItem.NAME,
265: (String) lfComboBox.getSelectedItem());
266:
267: // remember if Look And Feel has been changed
268: if (!oldLookAndFeelName.equals((String) lfComboBox
269: .getSelectedItem()))
270: restartRequired = true;
271:
272: // get language configuration
273: XmlElement locale = Config.getInstance().get("options")
274: .getElement("/options/locale");
275:
276: // set language config based on selected item
277: Locale l = (Locale) languageComboBox.getSelectedItem();
278: locale.addAttribute("language", l.getLanguage());
279: locale.addAttribute("country", l.getCountry());
280: locale.addAttribute("variant", l.getVariant());
281:
282: int state = toolbarComboBox.getSelectedIndex();
283: if (state == 0) {
284: item.setBoolean(GuiItem.TOOLBAR,
285: GuiItem.ENABLE_TEXT_BOOL, false);
286:
287: } else {
288: item.setBoolean(GuiItem.TOOLBAR,
289: GuiItem.ENABLE_TEXT_BOOL, true);
290:
291: item.setBoolean(GuiItem.TOOLBAR,
292: GuiItem.TEXT_POSITION_BOOL, state == 1 ? true
293: : false);
294:
295: }
296:
297: XmlElement options = Config.getInstance().get("options")
298: .getElement("/options");
299:
300: XmlElement proxy = options.getElement("proxy");
301: if (proxyHost != null && proxyPort > 0) {
302: System.setProperty("http.proxyHost", proxyHost);
303: System.setProperty("http.proxyPort", Integer
304: .toString(proxyPort));
305: if (proxy == null) {
306: proxy = options.addSubElement("proxy");
307: }
308: proxy.addAttribute("host", proxyHost);
309: proxy.addAttribute("port", Integer.toString(proxyPort));
310: } else {
311: Properties properties = System.getProperties();
312: properties.remove("http.proxyHost");
313: properties.remove("http.proxyPort");
314: if (proxy != null) {
315: options.removeElement(proxy);
316: }
317: }
318: }
319: }
320:
321: protected void layoutComponents() {
322: JPanel contentPane = new JPanel(new BorderLayout());
323: setContentPane(contentPane);
324:
325: // Create a FormLayout instance.
326: FormLayout layout = new FormLayout(
327: "12dlu, pref, 3dlu, max(40dlu;pref), 3dlu, pref",
328:
329: // 3 columns
330: "");
331:
332: // create a form builder
333: DefaultFormBuilder builder = new DefaultFormBuilder(layout);
334:
335: // create EmptyBorder between components and dialog-frame
336: builder.setDefaultDialogBorder();
337:
338: // skip the first column
339: builder.setLeadingColumnOffset(1);
340:
341: // Add components to the panel:
342: builder.appendSeparator(GlobalResourceLoader.getString(
343: RESOURCE_PATH, "general", "general"));
344: builder.nextLine();
345:
346: builder.append(languageLabel);
347: builder.append(languageComboBox, 3);
348: builder.nextLine();
349:
350: builder.append(lfLabel, lfComboBox, lfButton);
351: builder.nextLine();
352:
353: builder.append(toolbarLabel);
354: builder.append(toolbarComboBox, 3);
355: builder.nextLine();
356:
357: builder.append(proxyLabel);
358: builder.append(proxyButton, 3);
359: builder.nextLine();
360:
361: builder.appendSeparator(GlobalResourceLoader.getString(
362: RESOURCE_PATH, "general", "fonts"));
363: builder.nextLine();
364:
365: builder.append(overwriteCheckBox, 5);
366: builder.nextLine();
367:
368: builder.append(mainFontLabel);
369: builder.append(mainFontButton, 3);
370: builder.nextLine();
371:
372: builder.append(textFontLabel);
373: builder.append(textFontButton, 3);
374: builder.nextLine();
375:
376: contentPane.add(builder.getPanel(), BorderLayout.CENTER);
377:
378: // init bottom panel with OK, Cancel buttons
379: JPanel bottomPanel = new JPanel(new BorderLayout(0, 0));
380: bottomPanel.setBorder(new SingleSideEtchedBorder(
381: SwingConstants.TOP));
382:
383: JPanel buttonPanel = new JPanel(new GridLayout(1, 3, 6, 0));
384: buttonPanel.setBorder(BorderFactory.createEmptyBorder(12, 12,
385: 12, 12));
386:
387: buttonPanel.add(okButton);
388: buttonPanel.add(cancelButton);
389: buttonPanel.add(helpButton);
390:
391: bottomPanel.add(buttonPanel, BorderLayout.EAST);
392: contentPane.add(bottomPanel, BorderLayout.SOUTH);
393:
394: getRootPane().setDefaultButton(okButton);
395: getRootPane().registerKeyboardAction(this , "CANCEL",
396: KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
397: JComponent.WHEN_IN_FOCUSED_WINDOW);
398:
399: contentPane.add(new DialogHeaderPanel(GlobalResourceLoader
400: .getString(RESOURCE_PATH, "general", "title_header"),
401: GlobalResourceLoader.getString(RESOURCE_PATH,
402: "general", "title_description")),
403: BorderLayout.NORTH);
404: }
405:
406: protected void initComponents() {
407: lfLabel = new LabelWithMnemonic(GlobalResourceLoader.getString(
408: RESOURCE_PATH, "general", "look_feel"));
409:
410: String[] plugins = handler.getPluginIdList();
411: lfComboBox = new JComboBox(plugins);
412: lfComboBox.setRenderer(new ThemeComboBoxRenderer());
413: lfComboBox.setActionCommand("THEME");
414: lfComboBox.addActionListener(this );
415: lfLabel.setLabelFor(lfComboBox);
416:
417: lfButton = new ButtonWithMnemonic(GlobalResourceLoader
418: .getString(RESOURCE_PATH, "general",
419: "look_feel_options"));
420: lfButton.setActionCommand("THEME_OPTIONS");
421: lfButton.addActionListener(this );
422:
423: overwriteCheckBox = new CheckBoxWithMnemonic(
424: GlobalResourceLoader.getString(RESOURCE_PATH,
425: "general", "override_fonts"));
426: overwriteCheckBox.addActionListener(this );
427:
428: mainFontLabel = new LabelWithMnemonic(GlobalResourceLoader
429: .getString(RESOURCE_PATH, "general", "main_font"));
430: mainFontButton = new JButton("main font");
431: mainFontButton.addActionListener(this );
432: mainFontLabel.setLabelFor(mainFontButton);
433:
434: textFontLabel = new LabelWithMnemonic(GlobalResourceLoader
435: .getString(RESOURCE_PATH, "general", "text_font"));
436: textFontButton = new JButton("text font");
437: textFontButton.addActionListener(this );
438: textFontLabel.setLabelFor(textFontButton);
439:
440: toolbarLabel = new LabelWithMnemonic(GlobalResourceLoader
441: .getString(RESOURCE_PATH, "general", "toolbar"));
442: toolbarComboBox = new JComboBox(new String[] {
443: GlobalResourceLoader.getString(RESOURCE_PATH,
444: "general", "toolbar_icons"),
445: GlobalResourceLoader.getString(RESOURCE_PATH,
446: "general", "toolbar_below"),
447: GlobalResourceLoader.getString(RESOURCE_PATH,
448: "general", "toolbar_beside") });
449: toolbarLabel.setLabelFor(toolbarComboBox);
450:
451: languageLabel = new LabelWithMnemonic(GlobalResourceLoader
452: .getString(RESOURCE_PATH, "general", "locale"));
453: languageComboBox = new JComboBox();
454: languageLabel.setLabelFor(languageComboBox);
455: languageComboBox.setRenderer(new LocaleComboBoxRenderer());
456:
457: proxyLabel = new LabelWithMnemonic(GlobalResourceLoader
458: .getString(RESOURCE_PATH, "general", "proxy"));
459: proxyButton = new JButton();
460: proxyButton.addActionListener(this );
461: proxyLabel.setLabelFor(proxyButton);
462:
463: // button panel
464: okButton = new ButtonWithMnemonic(GlobalResourceLoader
465: .getString("", "global", "ok"));
466: okButton.setActionCommand("OK");
467: okButton.addActionListener(this );
468:
469: cancelButton = new ButtonWithMnemonic(GlobalResourceLoader
470: .getString("", "global", "cancel"));
471: cancelButton.setActionCommand("CANCEL");
472: cancelButton.addActionListener(this );
473:
474: helpButton = new ButtonWithMnemonic(GlobalResourceLoader
475: .getString("", "global", "help"));
476:
477: // associate with JavaHelp
478: HelpManager.getInstance().enableHelpOnButton(helpButton,
479: "configuring_columba_8");
480: HelpManager.getInstance().enableHelpKey(getRootPane(),
481: "configuring_columba_8");
482: }
483:
484: public void actionPerformed(ActionEvent event) {
485: String action = event.getActionCommand();
486:
487: if (action.equals("OK")) {
488:
489: updateComponents(false);
490:
491: // TODO (@author fdietz): until we can get all the settings update
492: // immediately
493: // we just open a message box, telling the user to restart
494:
495: if (restartRequired) {
496: JOptionPane
497: .showMessageDialog(this ,
498: "You have to restart Columba for the changes to take effect!");
499:
500: // switch to new theme
501: ThemeSwitcher.setTheme();
502:
503: }
504:
505: setVisible(false);
506:
507: // notify frame to update
508: IContainer[] m = FrameManager.getInstance().getOpenFrames();
509: for (int i = 0; i < m.length; i++) {
510: JFrame frame = m[i].getFrame();
511: ThemeSwitcher.updateFrame(frame);
512: }
513:
514: // set fonts
515: FontProperties.setFont();
516:
517: } else if (action.equals("CANCEL")) {
518: setVisible(false);
519: } else if (action.equals("THEME")) {
520: // theme selection changed
521: String theme = (String) lfComboBox.getSelectedItem();
522:
523: IExtension extension = handler.getExtension(theme);
524:
525: configID = extension.getMetadata().getAttribute("config");
526:
527: lfButton.setEnabled(configID != null);
528: } else if (action.equals("THEME_OPTIONS")) {
529: try {
530: ConfigurationDialog dialog = new ConfigurationDialog(
531: configID);
532: dialog.setVisible(true);
533: } catch (PluginHandlerNotFoundException phnfe) {
534: } catch (PluginLoadingFailedException plfe) {
535: }
536: }
537:
538: Object source = event.getSource();
539: if (source == mainFontButton) {
540: FontSelectionDialog fontDialog = new FontSelectionDialog(
541: this , null);
542:
543: if (fontDialog.showDialog() == FontSelectionDialog.APPROVE_OPTION) {
544: mainFont = fontDialog.getSelectedFont();
545: mainFontButton.setFont(mainFont);
546: mainFontButton.setText(mainFont.getFontName());
547: }
548: } else if (source == textFontButton) {
549: FontSelectionDialog fontDialog = new FontSelectionDialog(
550: this , null);
551:
552: if (fontDialog.showDialog() == FontSelectionDialog.APPROVE_OPTION) {
553: textFont = fontDialog.getSelectedFont();
554: textFontButton.setFont(textFont);
555: textFontButton.setText(textFont.getFontName());
556: }
557: } else if (source == overwriteCheckBox) {
558: boolean enabled = overwriteCheckBox.isSelected();
559: mainFontLabel.setEnabled(enabled);
560: mainFontButton.setEnabled(enabled);
561: textFontLabel.setEnabled(enabled);
562: textFontButton.setEnabled(enabled);
563: } else if (source == proxyButton) {
564: ProxyConfigurationDialog dialog = new ProxyConfigurationDialog(
565: this );
566: dialog.setProxyHost(proxyHost);
567: dialog.setProxyPort(proxyPort);
568: if (dialog.showDialog() == ProxyConfigurationDialog.APPROVE_OPTION) {
569: proxyHost = dialog.getProxyHost();
570: proxyPort = dialog.getProxyPort();
571: updateProxyButtonText();
572: }
573: }
574: }
575:
576: protected void updateProxyButtonText() {
577: if (proxyHost != null) {
578: proxyButton.setText(proxyHost + ":"
579: + Integer.toString(proxyPort));
580: } else {
581: proxyButton.setText(GlobalResourceLoader.getString(
582: RESOURCE_PATH, "proxy", "no_proxy"));
583: }
584: }
585:
586: private Font getMainFont() {
587: return mainFont;
588: }
589:
590: private Font getTextFont() {
591: return textFont;
592: }
593: }
|