/* Copyright (c) 2013, Fivium Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Fivium Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package net.foxopen.foxydocs.view; import static net.foxopen.foxydocs.FoxyDocs.EVENT_DOWN; import static net.foxopen.foxydocs.FoxyDocs.EVENT_UP; import static net.foxopen.foxydocs.FoxyDocs.appConfig; import static net.foxopen.foxydocs.FoxyDocs.saveConfiguration; import static net.foxopen.foxydocs.utils.Logger.logStdout; import java.io.File; import java.io.IOException; import net.foxopen.foxydocs.model.Directory; import net.foxopen.foxydocs.model.FoxModule; import net.foxopen.foxydocs.model.abstractObject.AbstractFSItem; import net.foxopen.foxydocs.utils.Export; import net.foxopen.foxydocs.utils.Loader; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.action.StatusLineManager; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.ApplicationWindow; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.wb.rcp.databinding.BeansListObservableFactory; import org.eclipse.wb.rcp.databinding.TreeBeanAdvisor; import org.eclipse.wb.swt.SWTResourceManager; public class FoxyDocsMainWindow extends ApplicationWindow { private Action action_exit; private final AbstractFSItem root = new Directory(null); public TreeViewer treeViewerFileList; public static CTabFolder tabFolder; private Action action_open; private Action action_close; private Action action_about; private Action action_nextentry; private Action action_previousentry; private Action action_save; private String lastUsedPath; private Action action_export_pdf; private Action action_load_last; private Action action_export_html; private Text searchField; private FormData fd_searchField; /** * Create the application window. */ public FoxyDocsMainWindow() { super(null); createActions(); addToolBar(SWT.FLAT | SWT.WRAP); addMenuBar(); addStatusLine(); } /** * Create contents of the application window. * * @param parent */ @Override protected Control createContents(Composite parent) { setStatus("Welcome to FoxyDocs"); Composite container = new Composite(parent, SWT.NONE); container.setLayout(new FillLayout(SWT.HORIZONTAL)); { SashForm sashForm = new SashForm(container, SWT.NONE); sashForm.setSashWidth(5); { final Composite composite = new Composite(sashForm, SWT.NONE); composite.setLayout(new FormLayout()); { searchField = new Text(composite, SWT.BORDER); fd_searchField = new FormData(); fd_searchField.bottom = new FormAttachment(0, 26); fd_searchField.top = new FormAttachment(0); searchField.setLayoutData(fd_searchField); } { treeViewerFileList = new TreeViewer(composite, SWT.BORDER); Tree fileList = treeViewerFileList.getTree(); fd_searchField.left = new FormAttachment(fileList, 0, SWT.LEFT); fd_searchField.right = new FormAttachment(fileList, 0, SWT.RIGHT); FormData fd_fileList = new FormData(); fd_fileList.top = new FormAttachment(searchField, 6); fd_fileList.bottom = new FormAttachment(100); fd_fileList.left = new FormAttachment(0); fd_fileList.right = new FormAttachment(100); fileList.setLayoutData(fd_fileList); treeViewerFileList.setExpandPreCheckFilters(true); treeViewerFileList.setAutoExpandLevel(3); treeViewerFileList.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { IStructuredSelection thisSelection = (IStructuredSelection) event.getSelection(); Object selectedNode = thisSelection.getFirstElement(); if (selectedNode instanceof FoxModule) { try { Tab.open(tabFolder, (FoxModule) selectedNode); } catch (IOException e) { MessageDialog.openError(getShell(), "Error", e.getMessage()); } } else { treeViewerFileList.setExpandedState(selectedNode, !treeViewerFileList.getExpandedState(selectedNode)); } } }); } } { tabFolder = new CTabFolder(sashForm, SWT.BORDER | SWT.CLOSE); tabFolder.setSimple(false); tabFolder.setSelectionBackground(Display.getCurrent().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT)); } sashForm.setWeights(new int[] { 1, 3 }); } initDataBindings(); return container; } /** * Create the actions. */ private void createActions() { { action_exit = new Action("&Exit") { @Override public void run() { close(); } }; action_exit.setImageDescriptor(getIcon("/img/icons/emblem-unreadable.png")); action_exit.setAccelerator(SWT.CTRL | 'Q'); } { action_open = new Action("&Open...") { @Override public void run() { // Get Last Path lastUsedPath = appConfig.getProperty("lastUsedPath"); // User has selected to save a file DirectoryDialog dlg = new DirectoryDialog(getShell(), SWT.OPEN); if (lastUsedPath != null) { dlg.setFilterPath(lastUsedPath); } lastUsedPath = dlg.open(); if (lastUsedPath != null) { appConfig.setProperty("lastUsedPath", lastUsedPath); saveConfiguration(); } if (lastUsedPath != null) { try { root.open(lastUsedPath); new ProgressMonitorDialog(getShell()).run(true, true, Loader.LoadContent(root)); } catch (InterruptedException e) { e.printStackTrace(); MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage()); } catch (Exception e) { e.printStackTrace(); MessageDialog.openInformation(getShell(), "Error", e.getMessage()); } } } }; action_open.setAccelerator(SWT.CTRL | 'O'); action_open.setImageDescriptor(getIcon("/img/icons/folder-open.png")); } { action_close = new Action("&Close Tab") { @Override public void run() { if (tabFolder.getSelection() != null) { tabFolder.getSelection().dispose(); } } }; action_close.setAccelerator(SWT.CTRL | 'W'); } { action_about = new Action("&About...") { @Override public void run() { MessageDialog.openInformation(getShell(), "About", "A Fox Documentation Editor\n\nDeveloper : pierredominique.putallaz@fivium.co.uk\nWith the help of mike.leonard@fivium.co.uk\nXSL : william.friesen@fivium.co.uk\n\nhttps://github.com/Akkenar/FoxyDocs"); } }; action_about.setImageDescriptor(getIcon("/img/icons/help-browser.png")); } { action_nextentry = new Action("Next Entry") { @Override public void run() { if (tabFolder.getSelection() != null) { tabFolder.getSelection().notifyListeners(EVENT_DOWN, new Event()); } } }; action_nextentry.setAccelerator(SWT.ALT | 'S'); action_nextentry.setImageDescriptor(getIcon("/img/icons/go-down.png")); } { action_previousentry = new Action("Previous Entry") { @Override public void run() { if (tabFolder.getSelection() != null) { tabFolder.getSelection().notifyListeners(EVENT_UP, new Event()); } } }; action_previousentry.setAccelerator(SWT.ALT | 'W'); action_previousentry.setImageDescriptor(getIcon("/img/icons/go-up.png")); } { action_save = new Action("&Save") { @Override public void run() { try { root.save(); } catch (Exception e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Error", e.getMessage()); e.printStackTrace(); } } }; action_save.setImageDescriptor(getIcon("/img/icons/media-floppy.png")); action_save.setAccelerator(SWT.CTRL | 'S'); } { action_export_pdf = new Action("to &PDF...") { @Override public void run() { try { if (tabFolder.getSelection() == null) throw new RuntimeException("You must open a module before generating documentation"); Tab tab = (Tab) tabFolder.getSelection(); DirectoryDialog dlg = new DirectoryDialog(getShell(), SWT.OPEN); String targetDir = dlg.open(); if (targetDir != null) new ProgressMonitorDialog(getShell()).run(true, true, Export.toPDF(tab.getContent().getFile(), new File(targetDir))); } catch (Exception e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Error", e.getMessage()); e.printStackTrace(); } } }; action_export_pdf.setImageDescriptor(getIcon("/img/icons/x-office-document.png")); action_export_pdf.setAccelerator(SWT.CTRL | 'P'); } { action_load_last = new Action("Load the last location") { @Override public void run() { lastUsedPath = appConfig.getProperty("lastUsedPath"); if (lastUsedPath != null) { try { root.open(lastUsedPath); new ProgressMonitorDialog(getShell()).run(true, true, Loader.LoadContent(root)); } catch (InterruptedException e) { MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage()); } catch (Exception e) { e.printStackTrace(); MessageDialog.openError(getParentShell(), "Error", e.getMessage()); } } else { MessageDialog.openError(Display.getDefault().getActiveShell(), "Error", "No last location"); } } }; action_load_last.setImageDescriptor(getIcon("/img/icons/view-refresh.png")); action_load_last.setAccelerator(SWT.CTRL | 'R'); } { action_export_html = new Action("to HTML report...") { @Override public void run() { try { DirectoryDialog dlg = new DirectoryDialog(getShell(), SWT.OPEN); String targetDir = dlg.open(); if (targetDir != null) new ProgressMonitorDialog(getShell()).run(true, true, Export.toHTML(root, new File(targetDir))); } catch (Exception e) { MessageDialog.openError(Display.getDefault().getActiveShell(), "Error", e.getMessage()); e.printStackTrace(); } } }; action_export_html.setAccelerator(SWT.CTRL | 'H'); } } /** * Create the menu manager. * * @return the menu manager */ @Override protected MenuManager createMenuManager() { MenuManager menuManager = new MenuManager("menu"); { MenuManager menu_file = new MenuManager("&File"); menuManager.add(menu_file); menu_file.add(action_open); menu_file.add(action_save); menu_file.add(new Separator()); menu_file.add(action_load_last); menu_file.add(new Separator()); { MenuManager menu_export = new MenuManager("E&xport"); menu_file.add(menu_export); menu_export.add(action_export_pdf); menu_export.add(action_export_html); } menu_file.add(new Separator()); menu_file.add(action_exit); } { MenuManager menu_edit = new MenuManager("&Edit"); menuManager.add(menu_edit); } MenuManager menu_entries = new MenuManager("&Browse"); menuManager.add(menu_entries); menu_entries.add(action_previousentry); menu_entries.add(action_nextentry); menu_entries.add(new Separator()); menu_entries.add(new Separator()); menu_entries.add(action_close); MenuManager menu_help = new MenuManager("&Help"); menuManager.add(menu_help); menu_help.add(action_about); return menuManager; } /** * Create the toolbar manager. * * @return the toolbar manager */ @Override protected ToolBarManager createToolBarManager(int style) { ToolBarManager toolBarManager = new ToolBarManager(SWT.NONE); toolBarManager.add(action_open); toolBarManager.add(action_save); return toolBarManager; } /** * Create the status line manager. * * @return the status line manager */ @Override protected StatusLineManager createStatusLineManager() { StatusLineManager statusLineManager = new StatusLineManager(); return statusLineManager; } /** * Configure the shell. * * @param newShell */ @Override protected void configureShell(final Shell newShell) { newShell.setImage(SWTResourceManager.getImage(FoxyDocsMainWindow.class, "/img/icons/face-monkey.png")); newShell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { logStdout("Disposed"); } }); newShell.addShellListener(new ShellAdapter() { @Override public void shellClosed(ShellEvent e) { logStdout("Closed"); } }); super.configureShell(newShell); newShell.setText("FoxyDocs - Dev 0.4"); } /** * Return the initial size of the window. */ @Override protected Point getInitialSize() { return new Point(405, 415); } protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); // BeansListObservableFactory treeObservableFactory = new BeansListObservableFactory(AbstractFSItem.class, "children"); TreeBeanAdvisor treeAdvisor = new TreeBeanAdvisor(AbstractFSItem.class, "parent", "children", "hasChildren"); ObservableListTreeContentProvider treeContentProvider = new ObservableListTreeContentProvider(treeObservableFactory, treeAdvisor); treeViewerFileList.setLabelProvider(new FoxLabelProvider(treeContentProvider.getKnownElements(), AbstractFSItem.class, "name", "image")); treeViewerFileList.setContentProvider(treeContentProvider); // IObservableList childrenRootObserveList = BeanProperties.list("children").observe(root); treeViewerFileList.setInput(childrenRootObserveList); // return bindingContext; } public static ImageDescriptor getIcon(String url) { return ImageDescriptor.createFromImage(getImage(url)); } public static Image getImage(String url) { return SWTResourceManager.getImage(FoxyDocsMainWindow.class, url); } }