Source Code Cross Referenced for ComposerController.java in  » Mail-Clients » columba-1.4 » org » columba » mail » gui » composer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Mail Clients » columba 1.4 » org.columba.mail.gui.composer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // The contents of this file are subject to the Mozilla Public License Version
0002:        // 1.1
0003:        //(the "License"); you may not use this file except in compliance with the
0004:        //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
0005:        //
0006:        //Software distributed under the License is distributed on an "AS IS" basis,
0007:        //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0008:        //for the specific language governing rights and
0009:        //limitations under the License.
0010:        //
0011:        //The Original Code is "The Columba Project"
0012:        //
0013:        //The Initial Developers of the Original Code are Frederik Dietz and Timo
0014:        // Stich.
0015:        //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
0016:        //
0017:        //All Rights Reserved.
0018:
0019:        package org.columba.mail.gui.composer;
0020:
0021:        import java.awt.BorderLayout;
0022:        import java.awt.Color;
0023:        import java.awt.Component;
0024:        import java.awt.Container;
0025:        import java.awt.FocusTraversalPolicy;
0026:        import java.awt.event.ItemEvent;
0027:        import java.awt.event.ItemListener;
0028:        import java.awt.event.MouseEvent;
0029:        import java.awt.event.MouseListener;
0030:        import java.io.File;
0031:        import java.io.FileInputStream;
0032:        import java.io.IOException;
0033:        import java.io.InputStream;
0034:        import java.nio.charset.Charset;
0035:        import java.nio.charset.UnsupportedCharsetException;
0036:        import java.util.List;
0037:        import java.util.Observable;
0038:        import java.util.Observer;
0039:        import java.util.logging.Logger;
0040:
0041:        import javax.swing.BorderFactory;
0042:        import javax.swing.JComponent;
0043:        import javax.swing.JEditorPane;
0044:        import javax.swing.JOptionPane;
0045:        import javax.swing.JPanel;
0046:        import javax.swing.JScrollPane;
0047:        import javax.swing.JSplitPane;
0048:        import javax.swing.SwingUtilities;
0049:        import javax.swing.UIManager;
0050:        import javax.swing.border.Border;
0051:        import javax.swing.border.LineBorder;
0052:        import javax.swing.event.DocumentEvent;
0053:        import javax.swing.event.DocumentListener;
0054:        import javax.swing.event.EventListenerList;
0055:        import javax.swing.text.BadLocationException;
0056:        import javax.swing.text.Document;
0057:
0058:        import org.columba.api.gui.frame.IContainer;
0059:        import org.columba.core.charset.CharsetEvent;
0060:        import org.columba.core.charset.CharsetListener;
0061:        import org.columba.core.charset.CharsetOwnerInterface;
0062:        import org.columba.core.config.ViewItem;
0063:        import org.columba.core.gui.base.LabelWithMnemonic;
0064:        import org.columba.core.gui.frame.DefaultFrameController;
0065:        import org.columba.core.gui.frame.FrameManager;
0066:        import org.columba.core.io.DiskIO;
0067:        import org.columba.core.xml.XmlElement;
0068:        import org.columba.mail.config.AccountItem;
0069:        import org.columba.mail.config.MailConfig;
0070:        import org.columba.mail.gui.composer.action.SaveAsDraftAction;
0071:        import org.columba.mail.gui.composer.html.HtmlEditorController2;
0072:        import org.columba.mail.gui.composer.html.HtmlToolbar;
0073:        import org.columba.mail.gui.composer.text.TextEditorController;
0074:        import org.columba.mail.gui.message.viewer.MessageBorder;
0075:        import org.columba.mail.parser.text.HtmlParser;
0076:        import org.columba.mail.util.MailResourceLoader;
0077:        import org.frapuccino.swing.MultipleTransferHandler;
0078:
0079:        import com.jgoodies.forms.debug.FormDebugPanel;
0080:        import com.jgoodies.forms.factories.FormFactory;
0081:        import com.jgoodies.forms.layout.CellConstraints;
0082:        import com.jgoodies.forms.layout.ColumnSpec;
0083:        import com.jgoodies.forms.layout.FormLayout;
0084:        import com.jgoodies.forms.layout.FormSpec;
0085:        import com.jgoodies.forms.layout.RowSpec;
0086:        import com.jgoodies.forms.layout.Sizes;
0087:
0088:        /**
0089:         *
0090:         * controller for message composer dialog
0091:         *
0092:         * @author fdietz
0093:         */
0094:        public class ComposerController extends DefaultFrameController
0095:                implements  CharsetOwnerInterface, ItemListener, Observer {
0096:
0097:            /** JDK 1.4+ logging framework logger, used for logging. */
0098:            private static final Logger LOG = Logger
0099:                    .getLogger("org.columba.mail.gui.composer");
0100:
0101:            private AttachmentController attachmentController;
0102:
0103:            private SubjectController subjectController;
0104:
0105:            private PriorityController priorityController;
0106:
0107:            private AccountController accountController;
0108:
0109:            private AbstractEditorController currentEditorController;
0110:
0111:            private HeaderController headerController;
0112:
0113:            private ComposerSpellCheck composerSpellCheck;
0114:
0115:            private ComposerModel composerModel;
0116:
0117:            private Charset charset;
0118:
0119:            private EventListenerList listenerList = new EventListenerList();
0120:
0121:            /** Buffer for listeners used by addContainerListenerForEditor and createView */
0122:            private List containerListenerBuffer;
0123:
0124:            private JSplitPane attachmentSplitPane;
0125:
0126:            /** Editor viewer resides in this panel */
0127:            private TextEditorPanel editorScrollPane;
0128:
0129:            private LabelWithMnemonic subjectLabel;
0130:
0131:            private LabelWithMnemonic smtpLabel;
0132:
0133:            private LabelWithMnemonic priorityLabel;
0134:
0135:            private JPanel centerPanel = new FormDebugPanel();
0136:
0137:            private JPanel topPanel;
0138:
0139:            private HtmlToolbar htmlToolbar;
0140:
0141:            private boolean promptOnDialogClosing = true;
0142:
0143:            private SignatureView signatureView;
0144:
0145:            private boolean attachmentPanelShown;
0146:
0147:            private JPanel editorPanel = new JPanel();
0148:
0149:            JPanel toolbarPanel = new JPanel();
0150:
0151:            private TextEditorController textEditor;
0152:
0153:            private HtmlEditorController2 htmlEditor;
0154:
0155:            public ComposerController() {
0156:                this (new ComposerModel(), FrameManager.getInstance()
0157:                        .createCustomViewItem("Composer"));
0158:
0159:            }
0160:
0161:            public ComposerController(ComposerModel model, ViewItem viewItem) {
0162:                super (viewItem);
0163:
0164:                // init model (defaults to empty plain text message)
0165:                composerModel = model;
0166:
0167:                // init controllers for different parts of the composer
0168:                attachmentController = new AttachmentController(this );
0169:                headerController = new HeaderController(this );
0170:                subjectController = new SubjectController(this );
0171:
0172:                // listen to changes in the Subject to update the title bar
0173:                // of the message composer window
0174:                getSubjectController().getView().getDocument()
0175:                        .addDocumentListener(new MyDocumentListener());
0176:
0177:                priorityController = new PriorityController(this );
0178:                accountController = new AccountController(this );
0179:                accountController.getView().addItemListener(this );
0180:                composerSpellCheck = new ComposerSpellCheck();
0181:
0182:                signatureView = new SignatureView(this );
0183:
0184:                // set default html or text based on stored option
0185:                // ... can be overridden by setting the composer model
0186:                XmlElement optionsElement = MailConfig.getInstance().get(
0187:                        "composer_options").getElement("/options");
0188:
0189:                // composer can either edit in html or plain text mode
0190:                // listen for configuration changes
0191:                initHtmlConfiguration(optionsElement);
0192:
0193:                htmlEditor = new HtmlEditorController2(this );
0194:
0195:                textEditor = new TextEditorController(this );
0196:
0197:                // init controller for the editor depending on message type
0198:                if (getModel().isHtml())
0199:                    currentEditorController = htmlEditor;
0200:                else
0201:                    currentEditorController = textEditor;
0202:
0203:                initComponents();
0204:
0205:                // add JPanel with useful HTML related actions.
0206:                htmlToolbar = new HtmlToolbar(this );
0207:
0208:                layoutComponents();
0209:
0210:                showAttachmentPanel();
0211:
0212:                // Hack to ensure charset is set correctly at start-up
0213:                XmlElement charsetElement = optionsElement
0214:                        .getElement("charset");
0215:
0216:                if (charsetElement != null) {
0217:                    String charset = charsetElement.getAttribute("name");
0218:
0219:                    if (charset != null) {
0220:                        try {
0221:                            setCharset(Charset.forName(charset));
0222:                        } catch (UnsupportedCharsetException ex) {
0223:                            // ignore this
0224:                        }
0225:                    }
0226:                }
0227:
0228:                // Setup DnD for the text and attachment list control.
0229:                ComposerAttachmentTransferHandler dndTransferHandler = new ComposerAttachmentTransferHandler(
0230:                        attachmentController);
0231:                attachmentController.getView().setDragEnabled(true);
0232:                attachmentController.getView().setTransferHandler(
0233:                        dndTransferHandler);
0234:
0235:                JEditorPane editorComponent = (JEditorPane) getCurrentEditor()
0236:                        .getComponent();
0237:                MultipleTransferHandler compositeHandler = new MultipleTransferHandler();
0238:                compositeHandler.addTransferHandler(editorComponent
0239:                        .getTransferHandler());
0240:                compositeHandler.addTransferHandler(dndTransferHandler);
0241:                editorComponent.setDragEnabled(true);
0242:                editorComponent.setTransferHandler(compositeHandler);
0243:            }
0244:
0245:            private void initHtmlConfiguration(XmlElement optionsElement) {
0246:
0247:                XmlElement htmlElement = optionsElement.getElement("html");
0248:
0249:                // create default element if not available
0250:                if (htmlElement == null) {
0251:                    htmlElement = optionsElement.addSubElement("html");
0252:                }
0253:
0254:                String enableHtml = htmlElement.getAttribute("enable", "false");
0255:
0256:                // register for configuration changes for the html(enabled/disabled)
0257:                // state
0258:                htmlElement.addObserver(this );
0259:
0260:                // set model based on configuration
0261:                if (enableHtml.equals("true")) {
0262:                    getModel().setHtml(true);
0263:                } else {
0264:                    getModel().setHtml(false);
0265:                }
0266:            }
0267:
0268:            /**
0269:             * Show attachment panel
0270:             * <p>
0271:             * Asks the ComposerModel if message contains attachments. If so, show the
0272:             * attachment panel. Otherwise, hide the attachment panel.
0273:             */
0274:            public void showAttachmentPanel() {
0275:                if (attachmentPanelShown == getAttachmentController().getView()
0276:                        .count() > 0)
0277:                    return;
0278:
0279:                // remove all components from container
0280:                centerPanel.removeAll();
0281:
0282:                // re-add all top components like recipient editor/subject editor
0283:                centerPanel.add(topPanel, BorderLayout.NORTH);
0284:
0285:                // if message contains attachments
0286:                if (getAttachmentController().getView().count() > 0) {
0287:                    // create scrollapen
0288:                    JScrollPane attachmentScrollPane = new JScrollPane(
0289:                            getAttachmentController().getView());
0290:                    attachmentScrollPane
0291:                            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0292:                    attachmentScrollPane.setBorder(BorderFactory
0293:                            .createEmptyBorder(1, 1, 1, 1));
0294:                    // create splitpane containing the bodytext editor and the
0295:                    // attachment panel
0296:                    attachmentSplitPane = new JSplitPane(
0297:                            JSplitPane.VERTICAL_SPLIT, editorScrollPane,
0298:                            attachmentScrollPane);
0299:                    attachmentSplitPane.setDividerLocation(0.80);
0300:                    attachmentSplitPane.setBorder(null);
0301:
0302:                    // add splitpane to the center
0303:                    centerPanel.add(attachmentSplitPane, BorderLayout.CENTER);
0304:
0305:                    // ViewItem viewItem = getViewItem();
0306:
0307:                    // default value is 200 pixel
0308:                    // int pos =
0309:                    // viewItem.getIntegerWithDefault("splitpanes","attachment", 200);
0310:                    attachmentSplitPane.setDividerLocation(200);
0311:
0312:                    attachmentPanelShown = true;
0313:                } else {
0314:                    // no attachments
0315:                    // -> only show bodytext editor
0316:                    centerPanel.add(editorPanel, BorderLayout.CENTER);
0317:
0318:                    attachmentPanelShown = false;
0319:                }
0320:
0321:                // re-paint composer-view
0322:                SwingUtilities.invokeLater(new Runnable() {
0323:                    public void run() {
0324:                        fireLayoutChanged();
0325:                    }
0326:                });
0327:
0328:            }
0329:
0330:            /**
0331:             * @return Returns the attachmentSplitPane.
0332:             */
0333:            public JSplitPane getAttachmentSplitPane() {
0334:                return attachmentSplitPane;
0335:            }
0336:
0337:            /**
0338:             * init components
0339:             */
0340:            protected void initComponents() {
0341:                subjectLabel = new LabelWithMnemonic(MailResourceLoader
0342:                        .getString("dialog", "composer", "subject"));
0343:                smtpLabel = new LabelWithMnemonic(MailResourceLoader.getString(
0344:                        "dialog", "composer", "identity"));
0345:                priorityLabel = new LabelWithMnemonic(MailResourceLoader
0346:                        .getString("dialog", "composer", "priority"));
0347:
0348:                editorScrollPane = new TextEditorPanel();
0349:            }
0350:
0351:            /**
0352:             * Layout components
0353:             */
0354:            public void layoutComponents() {
0355:                centerPanel.removeAll();
0356:
0357:                editorPanel.setLayout(new BorderLayout());
0358:
0359:                toolbarPanel.setLayout(new BorderLayout());
0360:                toolbarPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 4,
0361:                        0));
0362:                toolbarPanel.add(htmlToolbar);
0363:                toolbarPanel.setBackground(UIManager
0364:                        .getColor("TextArea.background"));
0365:
0366:                topPanel = new JPanel();
0367:                topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
0368:
0369:                FormLayout layout = new FormLayout(new ColumnSpec[] {
0370:                        new ColumnSpec("center:max(pref;50dlu)"),
0371:                        FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
0372:                        FormFactory.GROWING_BUTTON_COLSPEC,
0373:                        FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
0374:                        FormFactory.DEFAULT_COLSPEC,
0375:                        FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
0376:                        FormFactory.GROWING_BUTTON_COLSPEC }, new RowSpec[] {
0377:                        new RowSpec(RowSpec.FILL, Sizes.DEFAULT,
0378:                                FormSpec.NO_GROW),
0379:                        FormFactory.LINE_GAP_ROWSPEC,
0380:                        new RowSpec(RowSpec.FILL, Sizes.DEFAULT,
0381:                                FormSpec.NO_GROW),
0382:                        FormFactory.LINE_GAP_ROWSPEC,
0383:                        new RowSpec(RowSpec.FILL, Sizes.DEFAULT,
0384:                                FormSpec.NO_GROW),
0385:                        FormFactory.LINE_GAP_ROWSPEC,
0386:                        new RowSpec(RowSpec.FILL, Sizes.DEFAULT,
0387:                                FormSpec.NO_GROW),
0388:                        FormFactory.LINE_GAP_ROWSPEC,
0389:                        new RowSpec(RowSpec.FILL, Sizes.DEFAULT,
0390:                                FormSpec.NO_GROW) });
0391:                layout.setRowGroups(new int[][] { { 1, 3, 5, 7, 9 } });
0392:                layout.setColumnGroups(new int[][] { { 1 } });
0393:
0394:                topPanel.setLayout(layout);
0395:
0396:                CellConstraints c = new CellConstraints();
0397:
0398:                topPanel.add(smtpLabel, c.xy(1, 1, CellConstraints.CENTER,
0399:                        CellConstraints.DEFAULT));
0400:
0401:                topPanel.add(getAccountController().getView(), c.xy(3, 1));
0402:                topPanel.add(priorityLabel, c.xy(5, 1));
0403:                topPanel.add(getPriorityController().getView(), c.xy(7, 1));
0404:
0405:                getHeaderController().getView().layoutComponents(topPanel);
0406:
0407:                topPanel.add(subjectLabel, c.xy(1, 9, CellConstraints.CENTER,
0408:                        CellConstraints.DEFAULT));
0409:
0410:                topPanel.add(getSubjectController().getView(), c.xywh(3, 9, 5,
0411:                        1));
0412:
0413:                if (composerModel.isHtml())
0414:                    editorPanel.add(toolbarPanel, BorderLayout.NORTH);
0415:
0416:                editorScrollPane.getContentPane().add(
0417:                        getCurrentEditor().getViewUIComponent(),
0418:                        BorderLayout.CENTER);
0419:
0420:                editorPanel.add(editorScrollPane, BorderLayout.CENTER);
0421:
0422:                Border outterBorder = BorderFactory.createCompoundBorder(
0423:                        BorderFactory.createEmptyBorder(5, 5, 5, 5),
0424:                        new MessageBorder(Color.LIGHT_GRAY, 1, true));
0425:                Border innerBorder = BorderFactory.createCompoundBorder(
0426:                        outterBorder, new LineBorder(Color.WHITE, 5, true));
0427:                editorPanel.setBorder(innerBorder);
0428:
0429:                AccountItem item = (AccountItem) getAccountController()
0430:                        .getView().getSelectedItem();
0431:                if (item.getIdentity().getSignature() != null)
0432:                    editorScrollPane.getContentPane().add(signatureView,
0433:                            BorderLayout.SOUTH);
0434:
0435:                editorScrollPane.addMouseListener(new MouseListener() {
0436:
0437:                    public void mouseClicked(MouseEvent e) {
0438:                        currentEditorController.getComponent().requestFocus();
0439:                    }
0440:
0441:                    public void mouseEntered(MouseEvent e) {
0442:                    }
0443:
0444:                    public void mouseExited(MouseEvent e) {
0445:                    }
0446:
0447:                    public void mousePressed(MouseEvent e) {
0448:                    }
0449:
0450:                    public void mouseReleased(MouseEvent e) {
0451:                    }
0452:
0453:                });
0454:
0455:                centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0,
0456:                        0));
0457:                centerPanel.setLayout(new BorderLayout());
0458:
0459:                centerPanel.add(topPanel, BorderLayout.NORTH);
0460:
0461:                // no attachments
0462:                // -> only show bodytext editor
0463:                centerPanel.add(editorPanel, BorderLayout.CENTER);
0464:
0465:                attachmentPanelShown = false;
0466:            }
0467:
0468:            /**
0469:             * Returns a reference to the panel, that holds the editor view. This is
0470:             * used by the ComposerController when adding a listener to that panel.
0471:             *
0472:             * @return editor panel reference
0473:             */
0474:            public JPanel getEditorPanel() {
0475:                return editorScrollPane.getContentPane();
0476:            }
0477:
0478:            /**
0479:             * Used to update the panel, that holds the editor viewer. This is necessary
0480:             * e.g. if the ComposerModel is changed to hold another message type (text /
0481:             * html), which the previous editor can not handle. If so a new editor
0482:             * controller is created, and thereby a new view.
0483:             */
0484:            public void layoutEditorContainer() {
0485:
0486:                // update panel
0487:                editorScrollPane.getContentPane().removeAll();
0488:                editorScrollPane.getContentPane().add(
0489:                        getCurrentEditor().getViewUIComponent(),
0490:                        BorderLayout.CENTER);
0491:
0492:                AccountItem item = (AccountItem) getAccountController()
0493:                        .getView().getSelectedItem();
0494:                if (item.getIdentity().getSignature() != null)
0495:                    editorScrollPane.getContentPane().add(signatureView,
0496:                            BorderLayout.SOUTH);
0497:
0498:                editorScrollPane.getContentPane().validate();
0499:            }
0500:
0501:            public boolean isAccountInfoPanelVisible() {
0502:                // TODO (@author fdietz): fix account info panel check
0503:
0504:                /*
0505:                 * return isToolbarEnabled(ACCOUNTINFOPANEL);
0506:                 */
0507:
0508:                return true;
0509:            }
0510:
0511:            /**
0512:             * Check if data was entered correctly.
0513:             * <p>
0514:             * This includes currently a test for an empty subject and a valid recipient
0515:             * (to/cc/bcc) list.
0516:             *
0517:             * @return true, if data was entered correctly
0518:             */
0519:            public boolean checkState() {
0520:                // update ComposerModel based on user-changes in ComposerView
0521:                updateComponents(false);
0522:
0523:                if (!subjectController.checkState()) {
0524:                    return false;
0525:                }
0526:
0527:                return !headerController.checkState();
0528:            }
0529:
0530:            public void updateComponents(boolean b) {
0531:                subjectController.updateComponents(b);
0532:                currentEditorController.updateComponents(b);
0533:                priorityController.updateComponents(b);
0534:                accountController.updateComponents(b);
0535:                attachmentController.updateComponents(b);
0536:                headerController.updateComponents(b);
0537:
0538:                // show attachment panel if necessary
0539:                if (b)
0540:                    showAttachmentPanel();
0541:            }
0542:
0543:            /**
0544:             * @return AccountController
0545:             */
0546:            public AccountController getAccountController() {
0547:                return accountController;
0548:            }
0549:
0550:            /**
0551:             * @return AttachmentController
0552:             */
0553:            public AttachmentController getAttachmentController() {
0554:                return attachmentController;
0555:            }
0556:
0557:            /**
0558:             * @return ComposerSpellCheck
0559:             */
0560:            public ComposerSpellCheck getComposerSpellCheck() {
0561:                return composerSpellCheck;
0562:            }
0563:
0564:            /**
0565:             * @return TextEditorController
0566:             */
0567:            public AbstractEditorController getCurrentEditor() {
0568:                /*
0569:                 * *20030906, karlpeder* Method signature changed to return an
0570:                 * AbstractEditorController
0571:                 */
0572:                return currentEditorController;
0573:            }
0574:
0575:            public TextEditorController getTextEditorController() {
0576:                return textEditor;
0577:            }
0578:
0579:            public HtmlEditorController2 getHtmlEditorController() {
0580:                return htmlEditor;
0581:            }
0582:
0583:            /**
0584:             * @return HeaderViewer
0585:             */
0586:            public HeaderController getHeaderController() {
0587:                return headerController;
0588:            }
0589:
0590:            /**
0591:             * @return PriorityController
0592:             */
0593:            public PriorityController getPriorityController() {
0594:                return priorityController;
0595:            }
0596:
0597:            /**
0598:             * @return SubjectController
0599:             */
0600:            public SubjectController getSubjectController() {
0601:                return subjectController;
0602:            }
0603:
0604:            /**
0605:             * @see org.columba.core.gui.FrameController#reset()
0606:             */
0607:            protected void init() {
0608:
0609:            }
0610:
0611:            /**
0612:             * Returns the composer model
0613:             *
0614:             * @return Composer model
0615:             */
0616:            public ComposerModel getModel() {
0617:                // if (composerModel == null) // *20030907, karlpeder* initialized in
0618:                // init
0619:                // composerModel = new ComposerModel();
0620:                return composerModel;
0621:            }
0622:
0623:            /**
0624:             * Sets the composer model. If the message type of the new model (html /
0625:             * text) is different from the message type of the existing, the editor
0626:             * controller is changed and the view is changed accordingly. <br>
0627:             * Finally the components are updated according to the new model.
0628:             *
0629:             * @param model
0630:             *            New composer model
0631:             */
0632:            public void setComposerModel(ComposerModel model) {
0633:                boolean wasHtml = composerModel.isHtml();
0634:                composerModel = model;
0635:
0636:                //		if (wasHtml != composerModel.isHtml()) {
0637:                //			setHtmlState(composerModel.isHtml());
0638:                //		}
0639:
0640:                // Update all component according to the new model
0641:                updateComponents(true);
0642:
0643:            }
0644:
0645:            public Charset getCharset() {
0646:                return charset;
0647:            }
0648:
0649:            public void setCharset(Charset charset) {
0650:                this .charset = charset;
0651:
0652:                ((ComposerModel) getModel()).setCharset(charset);
0653:                fireCharsetChanged(new CharsetEvent(this , charset));
0654:            }
0655:
0656:            public void addCharsetListener(CharsetListener l) {
0657:                listenerList.add(CharsetListener.class, l);
0658:            }
0659:
0660:            public void removeCharsetListener(CharsetListener l) {
0661:                listenerList.remove(CharsetListener.class, l);
0662:            }
0663:
0664:            protected void fireCharsetChanged(CharsetEvent e) {
0665:                // Guaranteed to return a non-null array
0666:                Object[] listeners = listenerList.getListenerList();
0667:
0668:                // Process the listeners last to first, notifying
0669:                // those that are interested in this event
0670:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0671:                    if (listeners[i] == CharsetListener.class) {
0672:                        ((CharsetListener) listeners[i + 1]).charsetChanged(e);
0673:                    }
0674:                }
0675:            }
0676:
0677:            public void setHtmlState(boolean enableHtml) {
0678:
0679:                composerModel.setHtml(enableHtml);
0680:
0681:                // sync model with the current (old) view
0682:                updateComponents(false);
0683:
0684:                // convert body text to comply with new editor format
0685:                String oldBody = composerModel.getBodyText();
0686:                String newBody = null;
0687:
0688:                if (enableHtml) {
0689:                    LOG.fine("Converting body text to html");
0690:                    Charset charset = getCharset();
0691:                    if (charset == null)
0692:                        charset = Charset.defaultCharset();
0693:                    newBody = HtmlParser.textToHtml(oldBody, "", null, charset
0694:                            .toString());
0695:                } else {
0696:                    LOG.fine("Converting body text to text");
0697:                    newBody = HtmlParser.htmlToText(oldBody);
0698:                }
0699:
0700:                composerModel.setBodyText(newBody);
0701:
0702:                // switch editor and resync view with model
0703:                if (enableHtml)
0704:                    currentEditorController = htmlEditor;
0705:                else
0706:                    currentEditorController = textEditor;
0707:
0708:                // sync view with new update to date model
0709:                updateComponents(true);
0710:
0711:                // change ui container
0712:                layoutEditorContainer();
0713:
0714:                // enable/disable html toolbar
0715:                if (enableHtml) {
0716:                    editorPanel.add(toolbarPanel, BorderLayout.NORTH);
0717:                } else {
0718:                    editorPanel.remove(toolbarPanel);
0719:                }
0720:
0721:                editorPanel.validate();
0722:            }
0723:
0724:            /**
0725:             * @param container
0726:             * @see org.columba.core.gui.frame.DefaultFrameController#close(org.columba.api.gui.frame.IContainer)
0727:             */
0728:            public void close(IContainer container) {
0729:
0730:                // don't prompt user if composer should be closed
0731:                if (isPromptOnDialogClosing() == false)
0732:                    return;
0733:
0734:                // only prompt user, if composer contains some text
0735:                if (currentEditorController.getViewText().length() == 0) {
0736:                    fireVisibilityChanged(false);
0737:
0738:                    // close Columba, if composer is only visible frame
0739:                    FrameManager.getInstance().close(null);
0740:
0741:                    return;
0742:                }
0743:
0744:                Object[] options = { "Close", "Cancel", "Save" };
0745:                int n = JOptionPane
0746:                        .showOptionDialog(
0747:                                container.getFrame(),
0748:                                "Message wasn't sent. Would you like to save your changes?",
0749:                                "Warning: Message was modified",
0750:                                JOptionPane.YES_NO_CANCEL_OPTION,
0751:                                JOptionPane.QUESTION_MESSAGE, null, options,
0752:                                options[2]); // default button title
0753:
0754:                if (n == 2) {
0755:                    saveConfiguration();
0756:
0757:                    // save changes
0758:                    new SaveAsDraftAction(ComposerController.this )
0759:                            .actionPerformed(null);
0760:
0761:                    // close composer
0762:                    fireVisibilityChanged(false);
0763:
0764:                    // close Columba, if composer is only visible frame
0765:                    FrameManager.getInstance().close(null);
0766:                } else if (n == 1) {
0767:                    // cancel question dialog and don't close composer
0768:                } else {
0769:                    saveConfiguration();
0770:
0771:                    // close composer
0772:                    fireVisibilityChanged(false);
0773:
0774:                    // close Columba, if composer is only visible frame
0775:                    FrameManager.getInstance().close(null);
0776:                }
0777:
0778:            }
0779:
0780:            private void saveConfiguration() {
0781:
0782:                // save charset
0783:                XmlElement optionsElement = MailConfig.getInstance().get(
0784:                        "composer_options").getElement("/options");
0785:                XmlElement charsetElement = optionsElement
0786:                        .getElement("charset");
0787:
0788:                if (getCharset() == null) {
0789:                    optionsElement.removeElement(charsetElement);
0790:                } else {
0791:                    if (charsetElement == null) {
0792:                        charsetElement = new XmlElement("charset");
0793:                        optionsElement.addElement(charsetElement);
0794:                    }
0795:
0796:                    charsetElement.addAttribute("name", getCharset().name());
0797:                }
0798:
0799:                // save html state
0800:                XmlElement htmlElement = optionsElement.getElement("html");
0801:                htmlElement.addAttribute("enable", Boolean.toString(getModel()
0802:                        .isHtml()));
0803:            }
0804:
0805:            public class ComposerFocusTraversalPolicy extends
0806:                    FocusTraversalPolicy {
0807:
0808:                public Component getComponentAfter(Container focusCycleRoot,
0809:                        Component aComponent) {
0810:                    if (aComponent.equals(accountController.getView()))
0811:                        return priorityController.getView();
0812:                    else if (aComponent.equals(priorityController.getView()))
0813:                        return headerController.getView().getToComboBox();
0814:                    else if (aComponent.equals(headerController.getView()
0815:                            .getToComboBox()))
0816:                        return headerController.getView().getCcComboBox();
0817:                    else if (aComponent.equals(headerController.getView()
0818:                            .getCcComboBox()))
0819:                        return headerController.getView().getBccComboBox();
0820:                    else if (aComponent.equals(headerController.getView()
0821:                            .getBccComboBox()))
0822:                        return subjectController.getView();
0823:                    else if (aComponent.equals(subjectController.getView()))
0824:                        return currentEditorController.getComponent();
0825:
0826:                    return headerController.getView().getToComboBox();
0827:                }
0828:
0829:                public Component getComponentBefore(Container focusCycleRoot,
0830:                        Component aComponent) {
0831:                    if (aComponent.equals(currentEditorController
0832:                            .getComponent()))
0833:                        return subjectController.getView();
0834:                    else if (aComponent.equals(subjectController.getView()))
0835:                        return headerController.getView().getBccComboBox();
0836:                    else if (aComponent.equals(headerController.getView()
0837:                            .getBccComboBox()))
0838:                        return headerController.getView().getCcComboBox();
0839:                    else if (aComponent.equals(headerController.getView()
0840:                            .getCcComboBox()))
0841:                        return headerController.getView().getToComboBox();
0842:                    else if (aComponent.equals(headerController.getView()
0843:                            .getToComboBox()))
0844:                        return priorityController.getView();
0845:                    else if (aComponent.equals(priorityController.getView()))
0846:                        return accountController.getView();
0847:
0848:                    return currentEditorController.getComponent();
0849:                }
0850:
0851:                public Component getDefaultComponent(Container focusCycleRoot) {
0852:                    return headerController.getView().getToComboBox();
0853:                }
0854:
0855:                public Component getLastComponent(Container focusCycleRoot) {
0856:                    return currentEditorController.getComponent();
0857:                }
0858:
0859:                public Component getFirstComponent(Container focusCycleRoot) {
0860:                    return accountController.getView();
0861:                }
0862:            }
0863:
0864:            /**
0865:             * @return panel
0866:             * @see org.columba.api.gui.frame.IContentPane#getComponent()
0867:             */
0868:            public JComponent getComponent() {
0869:                JPanel panel = new JPanel();
0870:                panel.setLayout(new BorderLayout());
0871:
0872:                panel.add(centerPanel, BorderLayout.CENTER);
0873:
0874:                return panel;
0875:            }
0876:
0877:            /**
0878:             * @see org.columba.api.gui.frame.IFrameMediator#getString(java.lang.String,
0879:             *      java.lang.String, java.lang.String)
0880:             */
0881:            public String getString(String sPath, String sName, String sID) {
0882:                return MailResourceLoader.getString(sPath, sName, sID);
0883:            }
0884:
0885:            class MyDocumentListener implements  DocumentListener {
0886:
0887:                public void changedUpdate(DocumentEvent arg0) {
0888:                    handleEvent(arg0);
0889:                }
0890:
0891:                public void insertUpdate(DocumentEvent arg0) {
0892:                    handleEvent(arg0);
0893:                }
0894:
0895:                public void removeUpdate(DocumentEvent arg0) {
0896:                    handleEvent(arg0);
0897:                }
0898:
0899:                private void handleEvent(DocumentEvent arg0) {
0900:                    Document doc = arg0.getDocument();
0901:                    try {
0902:                        String subject = doc.getText(0, doc.getLength());
0903:
0904:                        fireTitleChanged(subject);
0905:                    } catch (BadLocationException e) {
0906:                    }
0907:                }
0908:
0909:            }
0910:
0911:            /**
0912:             * @return Returns the promptOnDialogClosing.
0913:             */
0914:            public boolean isPromptOnDialogClosing() {
0915:                return promptOnDialogClosing;
0916:            }
0917:
0918:            /**
0919:             * @param promptOnDialogClosing
0920:             *            The promptOnDialogClosing to set.
0921:             */
0922:            public void setPromptOnDialogClosing(boolean promptOnDialogClosing) {
0923:                this .promptOnDialogClosing = promptOnDialogClosing;
0924:            }
0925:
0926:            public void itemStateChanged(ItemEvent e) {
0927:                if (e.getStateChange() == ItemEvent.SELECTED) {
0928:
0929:                    AccountItem item = (AccountItem) getAccountController()
0930:                            .getView().getSelectedItem();
0931:                    if (item.getIdentity().getSignature() != null) {
0932:                        // show signature viewer
0933:                        editorScrollPane.getContentPane().add(signatureView,
0934:                                BorderLayout.SOUTH);
0935:                        editorScrollPane.revalidate();
0936:                    } else {
0937:                        // hide signature viewer
0938:                        editorScrollPane.getContentPane().remove(signatureView);
0939:                        editorScrollPane.revalidate();
0940:                    }
0941:                }
0942:
0943:            }
0944:
0945:            public JPanel getContentPane() {
0946:                return (JPanel) getComponent();
0947:            }
0948:
0949:            /**
0950:             * container callbacks
0951:             *
0952:             * @param container
0953:             */
0954:
0955:            public void extendMenu(IContainer container) {
0956:                try {
0957:                    InputStream is = DiskIO
0958:                            .getResourceStream("org/columba/mail/action/composer_menu.xml");
0959:                    container.extendMenu(this , is);
0960:
0961:                } catch (IOException e) {
0962:                    LOG.severe(e.getMessage());
0963:                }
0964:            }
0965:
0966:            public void extendToolBar(IContainer container) {
0967:                try {
0968:                    File configDirectory = MailConfig.getInstance()
0969:                            .getConfigDirectory();
0970:                    InputStream is2 = new FileInputStream(new File(
0971:                            configDirectory, "composer_toolbar.xml"));
0972:                    container.extendToolbar(this , is2);
0973:                } catch (IOException e) {
0974:                    e.printStackTrace();
0975:                }
0976:            }
0977:
0978:            public void initFrame(IContainer container) {
0979:                container.getFrame().setFocusTraversalPolicy(
0980:                        new ComposerFocusTraversalPolicy());
0981:
0982:                // make sure that JFrame is not closed automatically
0983:                // -> we want to prompt the user to save his work
0984:                container.setCloseOperation(false);
0985:            }
0986:
0987:            /**
0988:             * Method is called when composer configuration changed
0989:             *
0990:             * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
0991:             */
0992:            public void update(Observable observable, Object obj) {
0993:                //		if (observable instanceof XmlElement) {
0994:                //			// possibly change btw. html and text
0995:                //			XmlElement e = (XmlElement) obj;
0996:                //
0997:                //			if (e.getName().equals("html")) {
0998:                //				String enableHtml = e.getAttribute("enable", "false");
0999:                //
1000:                //				// This action should only be enabled in html mode
1001:                //				getModel().setHtml(Boolean.valueOf(enableHtml).booleanValue());
1002:                //			}
1003:                //		}
1004:            }
1005:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.