source: trunk/LogicMail/src/org/logicprobe/LogicMail/ui/NavigationController.java @ 917

Revision 917, 10.0 KB checked in by octorian, 10 months ago (diff)

Added initial auto-start support, completely refactoring the startup code for clarity and using a dedicated container object for runtime store state information. Also made "close" on MailHomeScreen simply hide the app instead of exiting it. (refs #329, fixes #78)

  • Property svn:mime-type set to text/plain
Line 
1/*-
2 * Copyright (c) 2009, Derek Konigsberg
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its
15 *    contributors may be used to endorse or promote products derived
16 *    from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31package org.logicprobe.LogicMail.ui;
32
33import net.rim.device.api.i18n.ResourceBundle;
34import net.rim.device.api.ui.Screen;
35import net.rim.device.api.ui.UiApplication;
36import net.rim.device.api.ui.component.Dialog;
37import net.rim.device.api.ui.component.Status;
38
39import org.logicprobe.LogicMail.LogicMailResource;
40import org.logicprobe.LogicMail.mail.MailConnectionListener;
41import org.logicprobe.LogicMail.mail.MailConnectionLoginEvent;
42import org.logicprobe.LogicMail.mail.MailConnectionManager;
43import org.logicprobe.LogicMail.mail.MailConnectionStateEvent;
44import org.logicprobe.LogicMail.mail.MailConnectionStatusEvent;
45import org.logicprobe.LogicMail.model.MailManager;
46import org.logicprobe.LogicMail.model.MailRootNode;
47import org.logicprobe.LogicMail.model.MailboxNode;
48import org.logicprobe.LogicMail.model.MessageNode;
49import org.logicprobe.LogicMail.model.NetworkAccountNode;
50import org.logicprobe.LogicMail.util.EventObjectRunnable;
51
52/**
53 * Controller class for screen creation.
54 * This class is intended to hide all screen creation logic
55 * from the rest of the UI, and provide a simple interface
56 * in terms of viewing data model objects.
57 */
58public final class NavigationController {
59        private static ResourceBundle resources = ResourceBundle.getBundle(LogicMailResource.BUNDLE_ID, LogicMailResource.BUNDLE_NAME);
60        private ScreenFactory screenFactory;
61        private MailRootNode mailRootNode;
62       
63        private UiApplication uiApplication;
64        private StandardScreen mailHomeScreen;
65       
66        private MessageActions messageActions;
67       
68        public NavigationController(UiApplication uiApplication) {
69                this.uiApplication = uiApplication;
70                this.screenFactory = ScreenFactory.getInstance();
71                this.mailRootNode = MailManager.getInstance().getMailRootNode();
72                this.messageActions = this.screenFactory.getMessageActions(this);
73               
74                MailConnectionManager.getInstance().addMailConnectionListener(new MailConnectionListener() {
75                        public void mailConnectionStateChanged(MailConnectionStateEvent e) { }
76                        public void mailConnectionStatus(MailConnectionStatusEvent e) {
77                                handleMailConnectionStatus(e);
78                        }
79                        public void mailConnectionError(MailConnectionStatusEvent e) {
80                                handleMailConnectionError(e);
81                        }
82                        public void mailConnectionLogin(MailConnectionLoginEvent e) {
83                                handleMailConnectionLogin(e);
84                        }
85                });
86        }
87
88        public synchronized void displayMailHome() {
89                if(mailHomeScreen == null) {
90                        mailHomeScreen = screenFactory.getMailHomeScreen(this, mailRootNode);
91                }
92                uiApplication.pushScreen(mailHomeScreen);
93        }
94       
95        public synchronized void displayAccountConfigurationWizard() {
96                UiApplication.getUiApplication().invokeLater(new Runnable() {
97                        public void run() {
98                                // Start the new account configuration wizard
99                                AccountConfigWizard wizard = new AccountConfigWizard();
100                                wizard.start();
101                        }
102                });
103        }
104       
105        public synchronized void displayMailbox(MailboxNode mailboxNode) {
106                StandardScreen screen = screenFactory.getMailboxScreen(this, mailboxNode);
107        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_SLIDE);
108                uiApplication.pushScreen(screen);
109        }
110       
111        public synchronized void displayMessage(MessageNode messageNode) {
112                StandardScreen screen = screenFactory.getMessageScreen(this, messageNode);
113        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_SLIDE);
114                uiApplication.pushScreen(screen);
115        }
116       
117        public synchronized void displayComposition(NetworkAccountNode accountNode) {
118                StandardScreen screen = screenFactory.getCompositionScreen(this, accountNode);
119        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_ZOOM);
120                uiApplication.pushScreen(screen);
121        }
122
123        public synchronized void displayComposition(NetworkAccountNode accountNode, MessageNode messageNode) {
124                StandardScreen screen = screenFactory.getCompositionScreen(
125                                this,
126                                accountNode,
127                                messageNode);
128        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_ZOOM);
129                uiApplication.pushScreen(screen);
130        }
131
132        public synchronized void displayComposition(NetworkAccountNode accountNode, String address) {
133                StandardScreen screen = screenFactory.getCompositionScreen(this, accountNode, address);
134        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_ZOOM);
135                uiApplication.pushScreen(screen);
136        }
137       
138        public synchronized void displayCompositionReply(NetworkAccountNode accountNode, MessageNode messageNode, boolean replyAll) {
139                StandardScreen screen = screenFactory.getCompositionReplyScreen(
140                                this,
141                                accountNode,
142                                messageNode,
143                                replyAll);
144        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_ZOOM);
145                uiApplication.pushScreen(screen);
146        }
147
148        public synchronized void displayCompositionForward(NetworkAccountNode accountNode, MessageNode messageNode) {
149                StandardScreen screen = screenFactory.getCompositionForwardScreen(
150                                this,
151                                accountNode,
152                                messageNode);
153        ScreenFactory.getInstance().attachScreenTransition(screen, ScreenFactory.TRANSITION_ZOOM);
154                uiApplication.pushScreen(screen);
155        }
156       
157        /**
158         * Gets the delegate for handling actions on message nodes.
159         *
160         * @return the message actions delegate instance
161         */
162        public MessageActions getMessageActions() {
163            return this.messageActions;
164        }
165       
166        /**
167         * Gets the current status text.
168         *
169         * @return the current status text
170         */
171        public String getCurrentStatus() {
172                return statusRunnable.getCurrentStatus();
173        }
174       
175        private void handleMailConnectionStatus(MailConnectionStatusEvent e) {
176            if(e.getRequest() == null || e.getRequest().isDeliberate()) {
177                statusRunnable.updateStatus(e);
178            }
179        }
180
181        private final MailConnectionStatusRunnable statusRunnable = new MailConnectionStatusRunnable();
182       
183        private static class MailConnectionStatusRunnable implements Runnable {
184        private final Object lockObj = new Object();
185            private MailConnectionStatusEvent event;
186            private boolean onQueue;
187           
188            public void updateStatus(MailConnectionStatusEvent event) {
189                synchronized(lockObj) {
190                    this.event = event;
191                    if(!onQueue) {
192                        onQueue = true;
193                        UiApplication.getUiApplication().invokeLater(this);
194                    }
195                }
196        }
197           
198            public String getCurrentStatus() {
199                String currentStatus;
200                synchronized(lockObj) {
201                    if(event != null) {
202                        currentStatus = event.getMessage();
203                    }
204                    else {
205                        currentStatus = "";
206                    }
207                }
208                return currentStatus;
209            }
210           
211            public void run() {
212                synchronized(lockObj) {
213                    if(event != null) {
214                        Screen activeScreen =
215                            UiApplication.getUiApplication().getActiveScreen();
216                        if(activeScreen instanceof StandardScreen) {
217                            StandardScreen screen = (StandardScreen)activeScreen;
218                            screen.updateStatus(event.getMessage());
219                        }
220                    }
221                    onQueue = false;
222                }
223            }
224        }
225       
226        private void handleMailConnectionError(MailConnectionStatusEvent e) {
227            if(e.getRequest() != null && !e.getRequest().isDeliberate()) { return; }
228           
229                UiApplication.getUiApplication().invokeLater(new EventObjectRunnable(e) {
230                        public void run() {
231                                String message = ((MailConnectionStatusEvent)getEvent()).getMessage();
232                                if(message == null) { message = resources.getString(LogicMailResource.ERROR_UNKNOWN); }
233                    try {
234                        Screen activeScreen =
235                                UiApplication.getUiApplication().getActiveScreen();
236                        if(activeScreen instanceof Status) {
237                            UiApplication.getUiApplication().popScreen(activeScreen);
238                        }
239                    } catch (Exception e) { }
240                    Status.show(message, 5000);
241                        }
242                });
243        }
244
245        private void handleMailConnectionLogin(MailConnectionLoginEvent e) {
246                UiApplication.getUiApplication().invokeAndWait(new EventObjectRunnable(e) {
247                        public void run() {
248                                MailConnectionLoginEvent e = (MailConnectionLoginEvent)getEvent();
249                                LoginDialog dialog = new LoginDialog(e.getUsername(), e.getPassword());
250                                if(dialog.doModal() == Dialog.OK) {
251                                        e.setUsername(dialog.getUsername());
252                                        e.setPassword(dialog.getPassword());
253                                }
254                                else {
255                                        e.setCanceled(true);
256                                }
257                        }
258                });
259        }
260}
Note: See TracBrowser for help on using the repository browser.