/******************************************************************************* * Copyright 2010 Simon Mieth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.kabeja.ui.impl; import java.awt.Component; import java.awt.Container; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import org.kabeja.DraftDocument; import org.kabeja.parser.Parser; import org.kabeja.processing.ProcessPipeline; import org.kabeja.processing.ProcessingManager; import org.kabeja.tools.IOUtils; import org.kabeja.ui.ApplicationMenuBar; import org.kabeja.ui.ApplicationToolBar; import org.kabeja.ui.DraftDocumentViewComponent; import org.kabeja.ui.PropertiesEditor; import org.kabeja.ui.PropertiesListener; import org.kabeja.ui.ServiceManager; import org.kabeja.ui.Serviceable; import org.kabeja.ui.UIException; import org.kabeja.ui.ViewComponent; import org.kabeja.ui.event.DraftDocumentChangeEventProvider; import org.kabeja.ui.event.DraftDocumentChangeListener; import de.miethxml.toolkit.ui.PanelFactory; import de.miethxml.toolkit.ui.UIUtils; public class ProcessingRunViewComponent implements ViewComponent, Serviceable, ActionListener, PropertiesListener, DraftDocumentChangeEventProvider { protected JTabbedPane tabbedPane; protected JComponent view; protected JPanel pipelinePanel; protected boolean locked = false; protected boolean initialized = false; protected List viewComponents = new ArrayList(); protected String processingPipeline; protected JTextArea logView; protected ProcessingManager manager; protected String baseDir = "./samples/dxf"; protected File sourceFile; protected DraftDocument doc; protected boolean autogenerateOutput = false; protected Map properties = new HashMap(); protected ArrayList listeners = new ArrayList(); public String getTitle() { return "Run Processing"; } public JComponent getView() { this.initialize(); return this.view; } protected void initialize() { if (!this.initialized) { JPanel panel = PanelFactory .createTitledPanel( new JPanel(), Messages .getString("ProcessingRunViewComponent.processing.pipeline"), new ImageIcon(UIUtils.resourceToBytes(this .getClass(), "/icons/project.gif"))); pipelinePanel = new JPanel(new GridLayout(0, 1, 0, 3)); pipelinePanel .setBorder(BorderFactory.createEmptyBorder(4, 5, 4, 5)); JScrollPane scroll = new JScrollPane(pipelinePanel); scroll.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); panel.add(scroll); JSplitPane sp = PanelFactory.createOneTouchSplitPane(); sp.setLeftComponent(panel); tabbedPane = new JTabbedPane(); tabbedPane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); sp.setRightComponent(tabbedPane); sp.setDividerLocation(150); JSplitPane sp2 = PanelFactory .createOneTouchSplitPane(JSplitPane.VERTICAL_SPLIT); sp2.setTopComponent(sp); this.logView = new JTextArea(); scroll = new JScrollPane(this.logView); scroll.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); JPanel p = PanelFactory.createTitledPanel(scroll, Messages .getString("ProcessingRunViewComponent.processing.output")); sp2.setBottomComponent(p); sp2.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); sp2.setDividerLocation(400); this.view = sp2; DraftFileTransferHandler handler = new DraftFileTransferHandler(this); this.view.setTransferHandler(handler); this.initialized = true; } } public void setProcessingManager(ProcessingManager manager) { this.manager = manager; this.initialize(); // setup the pipelines pipelinePanel.removeAll(); Iterator i = manager.getProcessPipelines().keySet().iterator(); while (i.hasNext()) { String pipelineName = (String) i.next(); ProcessPipeline p = manager.getProcessPipeline(pipelineName); JButton button = new JButton(pipelineName); button.setActionCommand(pipelineName); button.addActionListener(this); button.setToolTipText(p.getDescription()); button.setPreferredSize(button.getPreferredSize()); pipelinePanel.add(button); } pipelinePanel.repaint(); } public void setServiceManager(ServiceManager manager) { Object[] objects = manager .getServiceComponents(ApplicationToolBar.SERVICE); Action action = new AbstractAction(Messages .getString("ProcessingRunViewComponent.open.draft"), new ImageIcon(UIUtils.resourceToBytes(this.getClass(), "/icons/open.gif"))) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { Runnable r = new Runnable() { public void run() { chooseInput(); } }; Thread t = new Thread(r); t.start(); } }; // we set the action to all toolbars if there are more then on for (int i = 0; i < objects.length; i++) { ((ApplicationToolBar) objects[i]).addAction(action); } objects = manager.getServiceComponents(PropertiesEditor.SERVICE); for (int i = 0; i < objects.length; i++) { ((PropertiesEditor) objects[i]).addPropertiesListener(this); } // view menu ApplicationMenuBar mbar = ((ApplicationMenuBar) manager .getServiceComponents(ApplicationMenuBar.SERVICE)[0]); JMenu viewMenu = new JMenu(Messages .getString("ProcessingRunViewComponent.process.view.menuitem")); if (!mbar.hasMenu(ApplicationMenuBar.MENU_ID_VIEW)) { mbar.setMenu(ApplicationMenuBar.MENU_ID_VIEW, new JMenu(Messages .getString("menu.view"))); } objects = manager .getServiceComponents(DraftDocumentViewComponent.SERVICE); for (int i = 0; i < objects.length; i++) { ViewControl c = new ViewControl( (DraftDocumentViewComponent) objects[i]); this.viewComponents.add(c); JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(c.getTitle()); menuItem.setSelected(c.isEnabled()); menuItem.addItemListener(c); viewMenu.add(menuItem); } mbar.setJMenuItem(ApplicationMenuBar.MENU_ID_VIEW, viewMenu); mbar.setAction(ApplicationMenuBar.MENU_ID_FILE, action); } public void actionPerformed(ActionEvent e) { if (!this.locked) { this.processingPipeline = e.getActionCommand(); this.locked = true; Runnable r = new Runnable() { public void run() { process(); } }; Thread t = new Thread(r); t.start(); } } protected void process() { try { if (this.sourceFile.isDirectory()) { File[] files = this.sourceFile.listFiles(); // we have to parse every file for (int i = 0; i < files.length; i++) { this.processFile(files[i]); } // file already parsed } else if (this.sourceFile.isFile()) { this.processFile(this.sourceFile); } } catch (Exception e) { this.logException(e); } this.locked = false; } protected void processFile(File f) { String ext = f.getAbsolutePath(); int index = ext.lastIndexOf("."); if ((index + 1) < ext.length()) { ext = ext.substring(index + 1); try { this.logView.append(Messages .getString("ProcessingRunViewComponent.log.processing") + f.getAbsolutePath() + "\n"); File out = null; if (this.autogenerateOutput) { out = new File(f.getAbsolutePath().substring(0, index) + "." + this.manager.getProcessPipeline( this.processingPipeline).getGenerator() .getSuffix()); } else { JFileChooser fc = new JFileChooser(this.baseDir); int value = fc.showSaveDialog(null); if (value == JFileChooser.APPROVE_OPTION) { out = fc.getSelectedFile(); } } this.manager.process(new FileInputStream(f), ext, new HashMap(), this.processingPipeline, new FileOutputStream(out)); this.manager.process(doc, this.properties, this.processingPipeline, new FileOutputStream(out)); this.log(Messages .getString("ProcessingRunViewComponent.log.finished") + out.getAbsolutePath() + "\n"); } catch (Exception e) { e.printStackTrace(); this.logException(e); } } } protected void chooseInput() { JFileChooser fc = new JFileChooser(this.baseDir); fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); JCheckBox cb = new JCheckBox(); cb.setSelected(true); JPanel p = new JPanel(new FlowLayout()); p.add(cb); p .add(new JLabel( Messages .getString("ProcessingRunViewComponent.file.dialog.autogenerate"))); fc.setAccessory(p); int value = fc.showOpenDialog(null); if (value == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); this.autogenerateOutput = cb.isSelected(); if (file.isFile()) { this.baseDir = file.getParent(); this.processInput(file); } else if (file.isDirectory()) { this.baseDir = file.getAbsolutePath(); this .log(Messages .getString("ProcessingRunViewComponent.log.select.directory") + file.getAbsolutePath() + "\n"); this.log("No preview\n"); } } } protected void propagateDraftDocument(DraftDocument doc) throws Exception { Iterator i = this.viewComponents.iterator(); while (i.hasNext()) { ViewControl c = (ViewControl) i.next(); if (c.isEnabled()) { c.getDraftDocumentViewComponent().showDraftDocument(doc); } } } protected void logException(Exception e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); this.log(sw.toString()); } protected void log(String msg) { this.logView.append(msg); this.logView.setCaretPosition(this.logView.getDocument().getLength()); } public void propertiesChanged(Map props) { // copy changed properties to my properties Iterator i = props.keySet().iterator(); while (i.hasNext()) { String key = (String) i.next(); this.properties.put(key, props.get(key)); } } public void addDraftDocumentChangeListener(DraftDocumentChangeListener listener) { this.listeners.add(listener); } public void removeDraftDocumentChangeListener( DraftDocumentChangeListener listener) { this.listeners.remove(listener); } protected void fireDraftDocumentChangeEvent() throws Exception { Iterator i = ((ArrayList) this.listeners.clone()).iterator(); while (i.hasNext()) { DraftDocumentChangeListener l = (DraftDocumentChangeListener) i.next(); if (!(l instanceof DraftDocumentViewComponent)) { // avoid double event l.changed(this.doc); } } this.propagateDraftDocument(this.doc); } public void processInput(File file) { if(file.isFile()){ try { String extension = IOUtils.getFileExtension(file); Parser p = this.manager.getParser(extension); this.doc = p.parse(new FileInputStream(file),new HashMap()); this.fireDraftDocumentChangeEvent(); } catch (Exception e) { e.printStackTrace(); this.logException(e); } } } private class ViewControl implements ItemListener { private JComponent view; private String title; private DraftDocumentViewComponent component; private int index; ViewControl(DraftDocumentViewComponent component) { this.component = component; this.view = component.getView(); this.index = tabbedPane.getTabCount(); tabbedPane.add(component.getTitle(), view); } public boolean isEnabled() { return this.view.isEnabled(); } public void setEnabled(boolean b) { this.view.setEnabled(b); this.enableChildren(b, this.view); tabbedPane.setEnabledAt(this.index, b); if (b && (doc != null)) { try { this.component.showDraftDocument(doc); } catch (UIException e) { e.printStackTrace(); } } } public DraftDocumentViewComponent getDraftDocumentViewComponent() { return this.component; } public String getTitle() { return this.component.getTitle(); } public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { SwingUtilities.invokeLater(new Runnable() { public void run() { setEnabled(true); } }); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { setEnabled(false); } }); } } protected void enableChildren(boolean b, Container c) { for (int i = 0; i < c.getComponentCount(); i++) { Component comp = c.getComponent(i); comp.setEnabled(b); if (comp instanceof Container) { enableChildren(b, (Container) comp); } } } } }