PageRenderTime 88ms CodeModel.GetById 41ms app.highlight 41ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/columba-1.0/src/mail/core/org/columba/mail/gui/frame/ThreePaneMailFrameController.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 579 lines | 340 code | 119 blank | 120 comment | 38 complexity | c8ced38abd1f48e6849d9f314b4e5765 MD5 | raw file
  1// The contents of this file are subject to the Mozilla Public License Version
  2// 1.1
  3//(the "License"); you may not use this file except in compliance with the
  4//License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  5//
  6//Software distributed under the License is distributed on an "AS IS" basis,
  7//WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  8//for the specific language governing rights and
  9//limitations under the License.
 10//
 11//The Original Code is "The Columba Project"
 12//
 13//The Initial Developers of the Original Code are Frederik Dietz and Timo
 14// Stich.
 15//Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
 16//
 17//All Rights Reserved.
 18package org.columba.mail.gui.frame;
 19
 20import java.awt.BorderLayout;
 21import java.awt.Color;
 22import java.awt.Point;
 23import java.awt.event.KeyEvent;
 24import java.awt.event.MouseAdapter;
 25import java.awt.event.MouseEvent;
 26import java.io.File;
 27import java.io.FileInputStream;
 28import java.io.IOException;
 29import java.io.InputStream;
 30
 31import javax.swing.JComponent;
 32import javax.swing.JPanel;
 33import javax.swing.JScrollPane;
 34import javax.swing.JSplitPane;
 35import javax.swing.JTable;
 36import javax.swing.JViewport;
 37import javax.swing.KeyStroke;
 38import javax.swing.SwingUtilities;
 39import javax.swing.tree.TreePath;
 40
 41import org.columba.api.gui.frame.IContentPane;
 42import org.columba.api.selection.ISelectionListener;
 43import org.columba.api.selection.SelectionChangedEvent;
 44import org.columba.core.config.ViewItem;
 45import org.columba.core.gui.base.UIFSplitPane;
 46import org.columba.core.io.DiskIO;
 47import org.columba.mail.command.IMailFolderCommandReference;
 48import org.columba.mail.config.MailConfig;
 49import org.columba.mail.folder.IMailFolder;
 50import org.columba.mail.folder.IMailbox;
 51import org.columba.mail.gui.composer.HeaderController;
 52import org.columba.mail.gui.infopanel.FolderInfoPanel;
 53import org.columba.mail.gui.message.action.ViewMessageAction;
 54import org.columba.mail.gui.table.FilterToolbar;
 55import org.columba.mail.gui.table.ITableController;
 56import org.columba.mail.gui.table.TableController;
 57import org.columba.mail.gui.table.action.DeleteAction;
 58import org.columba.mail.gui.table.action.OpenMessageWithComposerAction;
 59import org.columba.mail.gui.table.action.OpenMessageWithMessageFrameAction;
 60import org.columba.mail.gui.table.action.ViewHeaderListAction;
 61import org.columba.mail.gui.table.model.HeaderTableModel;
 62import org.columba.mail.gui.table.model.MessageNode;
 63import org.columba.mail.gui.table.selection.TableSelectionChangedEvent;
 64import org.columba.mail.gui.table.selection.TableSelectionHandler;
 65import org.columba.mail.gui.tree.FolderTreeModel;
 66import org.columba.mail.gui.tree.ITreeController;
 67import org.columba.mail.gui.tree.TreeController;
 68import org.columba.mail.gui.tree.action.MoveDownAction;
 69import org.columba.mail.gui.tree.action.MoveUpAction;
 70import org.columba.mail.gui.tree.action.RenameFolderAction;
 71import org.columba.mail.gui.tree.selection.TreeSelectionChangedEvent;
 72import org.columba.mail.gui.tree.selection.TreeSelectionHandler;
 73import org.columba.mail.util.MailResourceLoader;
 74
 75/**
 76 * @author fdietz
 77 * 
 78 */
 79public class ThreePaneMailFrameController extends AbstractMailFrameController
 80		implements TreeViewOwner, TableViewOwner, IContentPane,
 81		ISelectionListener {
 82
 83	public TreeController treeController;
 84
 85	public TableController tableController;
 86
 87	public HeaderController headerController;
 88
 89	public FilterToolbar filterToolbar;
 90
 91	public JSplitPane mainSplitPane;
 92
 93	public JSplitPane rightSplitPane;
 94
 95	private JPanel tablePanel;
 96
 97	private JPanel messagePanel;
 98
 99	public FolderInfoPanel folderInfoPanel;
100
101	/**
102	 * true, if the messagelist table selection event was triggered by a popup
103	 * event. False, otherwise.
104	 */
105	public boolean isTablePopupEvent;
106
107	/**
108	 * true, if the tree selection event was triggered by a popup event. False,
109	 * otherwise.
110	 */
111	public boolean isTreePopupEvent;
112
113	/**
114	 * @param container
115	 */
116	public ThreePaneMailFrameController(ViewItem viewItem) {
117		super(viewItem);
118
119		treeController = new TreeController(this, FolderTreeModel.getInstance());
120		tableController = new TableController(this);
121
122		// create selection handlers
123		TableSelectionHandler tableHandler = new TableSelectionHandler(
124				tableController);
125		getSelectionManager().addSelectionHandler(tableHandler);
126		tableHandler.addSelectionListener(this);
127
128		TreeSelectionHandler treeHandler = new TreeSelectionHandler(
129				treeController.getView());
130		getSelectionManager().addSelectionHandler(treeHandler);
131
132		// double-click mouse listener
133		tableController.getView().addMouseListener(new TableMouseListener());
134
135		treeController.getView().addMouseListener(new TreeMouseListener());
136
137		folderInfoPanel = new FolderInfoPanel(this);
138
139		// table registers interest in tree selection events
140		treeHandler.addSelectionListener(tableHandler);
141
142		// also register interest in tree seleciton events
143		// for updating the title
144		treeHandler.addSelectionListener(this);
145
146		filterToolbar = new FilterToolbar(tableController);
147
148		RenameFolderAction renameFolderAction = new RenameFolderAction(this);
149
150		// Register F2 hotkey for renaming folder when the message panel has
151		// focus
152		tableController.getView().getActionMap().put("F2", renameFolderAction);
153		tableController.getView().getInputMap().put(
154				KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "F2");
155
156		// Register F2 hotkey for renaming folder when the folder tree itself
157		// has focus
158		treeController.getView().getActionMap().put("F2", renameFolderAction);
159		treeController.getView().getInputMap().put(
160				KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "F2");
161
162		// Register Alt-Up hotkey for moving up folder when folder tree or
163		// table have focus
164		MoveUpAction moveUpAction = new MoveUpAction(this);
165		tableController.getView().getActionMap().put("ALT_UP", moveUpAction);
166		tableController.getView().getInputMap().put(
167				KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK),
168				"ALT_UP");
169
170		treeController.getView().getActionMap().put("ALT_UP", moveUpAction);
171		treeController.getView().getInputMap().put(
172				KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK),
173				"ALT_UP");
174
175		// Register Alt-Down hotkey for moving up folder when folder tree or
176		// table have focus
177		MoveDownAction moveDownAction = new MoveDownAction(this);
178		tableController.getView().getActionMap()
179				.put("ALT_DOWN", moveDownAction);
180		tableController.getView().getInputMap().put(
181				KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK),
182				"ALT_DOWN");
183
184		treeController.getView().getActionMap().put("ALT_DOWN", moveDownAction);
185		treeController.getView().getInputMap().put(
186				KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK),
187				"ALT_DOWN");
188
189		DeleteAction deleteAction = new DeleteAction(this);
190		tableController.getView().getActionMap().put("DEL", deleteAction);
191		tableController.getView().getInputMap().put(
192				KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DEL");
193
194	}
195
196	public void enableMessagePreview(boolean enable) {
197		getViewItem().setBoolean("header_enabled", enable);
198
199		if (enable) {
200			rightSplitPane = new UIFSplitPane();
201			rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
202			rightSplitPane.add(tablePanel, JSplitPane.LEFT);
203			rightSplitPane.add(messagePanel, JSplitPane.RIGHT);
204
205			mainSplitPane.add(rightSplitPane, JSplitPane.RIGHT);
206		} else {
207			rightSplitPane = null;
208
209			mainSplitPane.add(tablePanel, JSplitPane.RIGHT);
210		}
211
212		mainSplitPane.setDividerLocation(viewItem.getIntegerWithDefault(
213				"splitpanes", "main", 100));
214
215		if (enable)
216			rightSplitPane.setDividerLocation(viewItem.getIntegerWithDefault(
217					"splitpanes", "header", 100));
218
219		getContainer().getFrame().validate();
220	}
221
222	/**
223	 * @return Returns the filterToolbar.
224	 */
225	public FilterToolbar getFilterToolbar() {
226		return filterToolbar;
227	}
228
229	/**
230	 * @see org.columba.mail.gui.frame.TreeViewOwner#getTreeController()
231	 */
232	public ITreeController getTreeController() {
233		return treeController;
234	}
235
236	/**
237	 * @see org.columba.mail.gui.frame.TableViewOwner#getTableController()
238	 */
239	public ITableController getTableController() {
240		return tableController;
241	}
242
243	/**
244	 * @see org.columba.api.gui.frame.IContentPane#getComponent()
245	 */
246	public JComponent getComponent() {
247		JPanel panel = new JPanel();
248
249		mainSplitPane = new UIFSplitPane();
250		mainSplitPane.setBorder(null);
251
252		panel.setLayout(new BorderLayout());
253
254		panel.add(mainSplitPane, BorderLayout.CENTER);
255
256		mainSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
257
258		JScrollPane treeScrollPane = new JScrollPane(treeController.getView());
259
260		// treeScrollPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1,
261		// 1));
262		mainSplitPane.add(treeScrollPane, JSplitPane.LEFT);
263
264		messagePanel = new JPanel();
265		messagePanel.setLayout(new BorderLayout());
266		messagePanel.add(messageController, BorderLayout.CENTER);
267
268		tablePanel = new JPanel();
269		tablePanel.setLayout(new BorderLayout());
270
271		ViewItem viewItem = getViewItem();
272
273		tablePanel.add(filterToolbar, BorderLayout.NORTH);
274
275		JScrollPane tableScrollPane = new JScrollPane(tableController.getView());
276		tableScrollPane
277				.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
278
279		tableScrollPane.getViewport().setScrollMode(
280				JViewport.BACKINGSTORE_SCROLL_MODE);
281
282		tableScrollPane.getViewport().setBackground(Color.white);
283		tablePanel.add(tableScrollPane, BorderLayout.CENTER);
284
285		if (viewItem
286				.getBooleanWithDefault("splitpanes", "header_enabled", true)) {
287
288			rightSplitPane = new UIFSplitPane();
289			rightSplitPane.setBorder(null);
290			rightSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
291			rightSplitPane.add(tablePanel, JSplitPane.LEFT);
292			rightSplitPane.add(messagePanel, JSplitPane.RIGHT);
293
294			mainSplitPane.add(rightSplitPane, JSplitPane.RIGHT);
295		} else {
296			mainSplitPane.add(tablePanel, JSplitPane.RIGHT);
297		}
298
299		getContainer().setInfoPanel(folderInfoPanel);
300
301		int count = MailConfig.getInstance().getAccountList().count();
302
303		if (count == 0) {
304			// pack();
305			rightSplitPane.setDividerLocation(150);
306		} else {
307			mainSplitPane.setDividerLocation(viewItem.getIntegerWithDefault(
308					"splitpanes", "main", 100));
309
310			if (viewItem.getBooleanWithDefault("splitpanes", "header_enabled",
311					true))
312				rightSplitPane.setDividerLocation(viewItem
313						.getIntegerWithDefault("splitpanes", "header", 100));
314		}
315
316		try {
317			InputStream is = DiskIO
318					.getResourceStream("org/columba/mail/action/menu.xml");
319			getContainer().extendMenu(this, is);
320
321			File configDirectory = MailConfig.getInstance()
322					.getConfigDirectory();
323			InputStream is2 = new FileInputStream(new File(configDirectory, "main_toolbar.xml"));
324			getContainer().extendToolbar(this, is2);
325
326		} catch (IOException e) {
327			e.printStackTrace();
328		}
329
330		tableController.createPopupMenu();
331		treeController.createPopupMenu();
332		messageController.createPopupMenu();
333
334		// TODO: fixme
335		// JFrame frame = (JFrame) getContainer().getFrame();
336		// ColumbaMenu menu = (ColumbaMenu) frame.getJMenuBar();
337		// menu.addMenuItem("my_reply_action_id", new ReplyAction(this),
338		// ColumbaMenu.MENU_VIEW, ColumbaMenu.PLACEHOLDER_BOTTOM);
339
340		return panel;
341	}
342
343	public void showFilterToolbar() {
344		tablePanel.add(filterToolbar, BorderLayout.NORTH);
345		tablePanel.validate();
346
347	}
348
349	public void hideFilterToolbar() {
350		tablePanel.remove(filterToolbar);
351		tablePanel.validate();
352
353	}
354
355	public void savePositions(ViewItem viewItem) {
356		super.savePositions(viewItem);
357
358		// splitpanes
359		viewItem.setInteger("splitpanes", "main", mainSplitPane
360				.getDividerLocation());
361
362		if (rightSplitPane != null)
363			viewItem.setInteger("splitpanes", "header", rightSplitPane
364					.getDividerLocation());
365		viewItem.setBoolean("splitpanes", "header_enabled",
366				rightSplitPane != null);
367
368		IMailFolderCommandReference r = getTreeSelection();
369
370		if (r != null) {
371			IMailFolder folder = (IMailFolder) r.getSourceFolder();
372
373			// folder-based configuration
374
375			if (folder instanceof IMailbox)
376				getFolderOptionsController().save((IMailbox) folder);
377		}
378	}
379
380	/**
381	 * @return Returns the folderInfoPanel.
382	 */
383	public FolderInfoPanel getFolderInfoPanel() {
384		return folderInfoPanel;
385	}
386
387	/**
388	 * @see org.columba.api.gui.frame.IFrameMediator#getString(java.lang.String,
389	 *      java.lang.String, java.lang.String)
390	 */
391	public String getString(String sPath, String sName, String sID) {
392		return MailResourceLoader.getString(sPath, sName, sID);
393	}
394
395	/**
396	 * @see org.columba.api.gui.frame.IFrameMediator#getContentPane()
397	 */
398	public IContentPane getContentPane() {
399		return this;
400	}
401
402	/**
403	 * @see org.columba.api.selection.ISelectionListener#selectionChanged(org.columba.api.selection.SelectionChangedEvent)
404	 */
405	public void selectionChanged(SelectionChangedEvent e) {
406
407		if (e instanceof TreeSelectionChangedEvent) {
408			// tree selection event
409			TreeSelectionChangedEvent event = (TreeSelectionChangedEvent) e;
410
411			IMailFolder[] selectedFolders = event.getSelected();
412
413			if (isTreePopupEvent == false) {
414				// view headerlist in message list viewer
415				new ViewHeaderListAction(this).actionPerformed(null);
416
417				getFolderInfoPanel().selectionChanged(e);
418
419				// update frame title
420				if (selectedFolders.length == 1 && selectedFolders[0] != null) {
421					getContainer().getFrame().setTitle(
422							selectedFolders[0].getName());
423				} else {
424					getContainer().getFrame().setTitle("");
425				}
426			}
427
428			isTreePopupEvent = false;
429
430		} else if (e instanceof TableSelectionChangedEvent) {
431			// messagelist table selection event
432			TableSelectionChangedEvent event = (TableSelectionChangedEvent) e;
433
434			if (isTablePopupEvent == false)
435				// show message content
436				new ViewMessageAction(this).actionPerformed(null);
437
438			isTablePopupEvent = false;
439		} else
440			throw new IllegalArgumentException(
441					"unknown selection changed event");
442	}
443
444	/**
445	 * Double-click mouse listener for message list table component.
446	 * <p>
447	 * If message is marked as draft, the composer will be opened to edit the
448	 * message. Otherwise, the message will be viewed in the message frame.
449	 * 
450	 * @author Frederik Dietz
451	 */
452	class TableMouseListener extends MouseAdapter {
453
454		/**
455		 * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
456		 */
457		public void mousePressed(MouseEvent event) {
458			if (event.isPopupTrigger()) {
459				processPopup(event);
460			}
461		}
462
463		/**
464		 * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
465		 */
466		public void mouseReleased(MouseEvent event) {
467			if (event.isPopupTrigger()) {
468				processPopup(event);
469			}
470		}
471
472		/**
473		 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
474		 */
475		public void mouseClicked(MouseEvent event) {
476			// if mouse button was pressed twice times
477			if (event.getClickCount() == 2) {
478				// get selected row
479				int selectedRow = tableController.getView().getSelectedRow();
480
481				// get message node at selected row
482				MessageNode node = (MessageNode) ((HeaderTableModel) tableController
483						.getHeaderTableModel())
484						.getMessageNodeAtRow(selectedRow);
485
486				// is the message marked as draft ?
487				boolean markedAsDraft = node.getHeader().getFlags().getDraft();
488
489				if (markedAsDraft) {
490					// edit message in composer
491					new OpenMessageWithComposerAction(
492							ThreePaneMailFrameController.this)
493							.actionPerformed(null);
494				} else {
495					// open message in new message-frame
496					new OpenMessageWithMessageFrameAction(
497							ThreePaneMailFrameController.this)
498							.actionPerformed(null);
499				}
500			}
501		}
502
503		protected void processPopup(final MouseEvent event) {
504
505			isTablePopupEvent = true;
506
507			JTable table = tableController.getView();
508
509			int selectedRows = table.getSelectedRowCount();
510
511			if (selectedRows <= 1) {
512				// select node
513				int row = table
514						.rowAtPoint(new Point(event.getX(), event.getY()));
515				table.setRowSelectionInterval(row, row);
516			}
517
518			SwingUtilities.invokeLater(new Runnable() {
519
520				public void run() {
521					tableController.getPopupMenu().show(event.getComponent(),
522							event.getX(), event.getY());
523					isTablePopupEvent = false;
524				}
525			});
526		}
527	}
528
529	class TreeMouseListener extends MouseAdapter {
530
531		/**
532		 * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
533		 */
534		public void mousePressed(MouseEvent event) {
535			if (event.isPopupTrigger()) {
536				processPopup(event);
537			}
538		}
539
540		/**
541		 * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
542		 */
543		public void mouseReleased(MouseEvent event) {
544			if (event.isPopupTrigger()) {
545				processPopup(event);
546			}
547		}
548
549		/**
550		 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
551		 */
552		public void mouseClicked(MouseEvent event) {
553			// if mouse button was pressed twice times
554			if (event.getClickCount() == 2) {
555				// get selected row
556
557			}
558		}
559
560		protected void processPopup(final MouseEvent event) {
561
562			isTreePopupEvent = true;
563
564			Point point = event.getPoint();
565			TreePath path = treeController.getView().getClosestPathForLocation(
566					point.x, point.y);
567			treeController.getView().setSelectionPath(path);
568
569			SwingUtilities.invokeLater(new Runnable() {
570
571				public void run() {
572					treeController.getPopupMenu().show(event.getComponent(),
573							event.getX(), event.getY());
574					isTreePopupEvent = false;
575				}
576			});
577		}
578	}
579}