/****************************************************************************** * Copyright (C) 2008 Low Heng Sin All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius * * or via info@posterita.org or http://www.posterita.org/ * *****************************************************************************/ package org.adempiere.webui.panel; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.logging.Level; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ListItem; import org.adempiere.webui.component.Listbox; import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; import org.adempiere.webui.window.FDialog; import org.compiere.model.MAttachment; import org.compiere.model.MAttachmentEntry; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; import org.zkoss.util.media.AMedia; import org.zkoss.util.media.Media; import org.zkoss.zk.au.AuScript; import org.zkoss.zk.au.out.AuEcho; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zkex.zul.Borderlayout; import org.zkoss.zkex.zul.Center; import org.zkoss.zkex.zul.North; import org.zkoss.zkex.zul.South; import org.zkoss.zul.Div; import org.zkoss.zul.Filedownload; import org.zkoss.zul.Fileupload; import org.zkoss.zul.Hbox; import org.zkoss.zul.Iframe; import org.zkoss.zul.Timer; /** * * @author Low Heng Sin * */ @SuppressWarnings("deprecation") public class WAttachment extends Window implements EventListener { /** * */ private static final long serialVersionUID = 2923895336573554570L; private static CLogger log = CLogger.getCLogger(WAttachment.class); /** Window No */ private int m_WindowNo; /** Attachment */ private MAttachment m_attachment; /** Change */ private boolean m_change = false; private Iframe preview = new Iframe(); private Textbox text = new Textbox(); private Listbox cbContent = new Listbox(); private Button bDelete = new Button(); private Button bSave = new Button(); private Button bDeleteAll = new Button(); private Button bLoad = new Button(); private Button bCancel = new Button(); private Button bOk = new Button(); private Button bRefresh = new Button(); private Panel previewPanel = new Panel(); private Borderlayout mainPanel = new Borderlayout(); private Hbox toolBar = new Hbox(); private Hbox confirmPanel = new Hbox(); private int displayIndex; /** * Constructor. * loads Attachment, if ID <> 0 * @param WindowNo window no * @param AD_Attachment_ID attachment * @param AD_Table_ID table * @param Record_ID record key * @param trxName transaction */ public WAttachment( int WindowNo, int AD_Attachment_ID, int AD_Table_ID, int Record_ID, String trxName) { super(); log.config("ID=" + AD_Attachment_ID + ", Table=" + AD_Table_ID + ", Record=" + Record_ID); m_WindowNo = WindowNo; try { staticInit(); } catch (Exception ex) { log.log(Level.SEVERE, "", ex); } // Create Model if (AD_Attachment_ID == 0) m_attachment = new MAttachment (Env.getCtx(), AD_Table_ID, Record_ID, trxName); else m_attachment = new MAttachment (Env.getCtx(), AD_Attachment_ID, trxName); loadAttachments(); try { setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); AEnv.showWindow(this); displayData(0, true); String script = "setTimeout(\"$e('"+ preview.getUuid() + "').src = $e('" + preview.getUuid() + "').src\", 1000)"; Clients.response(new AuScript(null, script)); //enter modal doModal(); } catch (Exception e) { } } // WAttachment /** * Static setup. * <pre> * - northPanel * - toolBar * - title * - centerPane [split] * - previewPanel (left) * - text (right) * - confirmPanel * </pre> * @throws Exception */ void staticInit() throws Exception { this.setMaximizable(true); this.setWidth("700px"); this.setHeight("600px"); this.setTitle("Attachment"); this.setClosable(true); this.setSizable(true); this.setBorder("normal"); this.appendChild(mainPanel); mainPanel.setHeight("100%"); mainPanel.setWidth("100%"); North northPanel = new North(); northPanel.setCollapsible(false); northPanel.setSplittable(false); cbContent.setMold("select"); cbContent.setRows(0); cbContent.addEventListener(Events.ON_SELECT, this); toolBar.appendChild(bLoad); toolBar.appendChild(bDelete); toolBar.appendChild(bSave); toolBar.appendChild(cbContent); mainPanel.appendChild(northPanel); Div div = new Div(); div.appendChild(toolBar); text.setRows(3); text.setWidth("100%"); div.appendChild(text); northPanel.appendChild(div); bSave.setEnabled(false); bSave.setImage("/images/Export24.png"); bSave.setTooltiptext(Msg.getMsg(Env.getCtx(), "AttachmentSave")); bSave.addEventListener(Events.ON_CLICK, this); bLoad.setImage("/images/Import24.png"); bLoad.setTooltiptext(Msg.getMsg(Env.getCtx(), "Load")); bLoad.addEventListener(Events.ON_CLICK, this); bDelete.setImage("/images/Delete24.png"); bDelete.setTooltiptext(Msg.getMsg(Env.getCtx(), "Delete")); bDelete.addEventListener(Events.ON_CLICK, this); previewPanel.appendChild(preview); preview.setHeight("100%"); preview.setWidth("100%"); Center centerPane = new Center(); centerPane.setAutoscroll(true); centerPane.setFlex(true); mainPanel.appendChild(centerPane); centerPane.appendChild(previewPanel); South southPane = new South(); mainPanel.appendChild(southPane); southPane.appendChild(confirmPanel); southPane.setHeight("30px"); bCancel.setImage("/images/Cancel24.png"); bCancel.addEventListener(Events.ON_CLICK, this); bOk.setImage("/images/Ok24.png"); bOk.addEventListener(Events.ON_CLICK, this); bDeleteAll.setImage("/images/Delete24.png"); bDeleteAll.addEventListener(Events.ON_CLICK, this); bRefresh.setImage("/images/Refresh24.png"); bRefresh.addEventListener(Events.ON_CLICK, this); confirmPanel.appendChild(bDeleteAll); confirmPanel.appendChild(bRefresh); confirmPanel.appendChild(bCancel); confirmPanel.appendChild(bOk); } /** * Dispose */ public void dispose () { preview = null; this.detach(); } // dispose /** * Load Attachments */ private void loadAttachments() { log.config(""); // Set Text/Description String sText = m_attachment.getTextMsg(); if (sText == null) text .setText(""); else text.setText(sText); // Set Combo int size = m_attachment.getEntryCount(); for (int i = 0; i < size; i++) cbContent.appendItem(m_attachment.getEntryName(i), m_attachment.getEntryName(i)); if (size > 0) { cbContent.setSelectedIndex(0); } } // loadAttachment /** * Display gif or jpg in gifPanel * @param index index */ private void displayData (int index, boolean immediate) { // Reset UI preview.setSrc(null); bDelete.setEnabled(false); bSave.setEnabled(false); displayIndex = index; if (immediate) displaySelected(); else Clients.response(new AuEcho(this, "displaySelected", null)); } // displayData /** * Use to refresh preview frame, don't call directly. */ public void displaySelected() { MAttachmentEntry entry = m_attachment.getEntry(displayIndex); log.config("Index=" + displayIndex + " - " + entry); if (entry != null && entry.getData() != null) { bSave.setEnabled(true); bDelete.setEnabled(true); log.config(entry.toStringX()); try { AMedia media = new AMedia(entry.getName(), null, entry.getContentType(), entry.getData()); preview.setContent(media); preview.setVisible(true); preview.invalidate(); } catch (Exception e) { log.log(Level.SEVERE, "attachment", e); } } } /** * Get File Name with index * @param index index * @return file name or null */ private String getFileName (int index) { String fileName = null; if (cbContent.getItemCount() > index) { ListItem listitem = cbContent.getItemAtIndex(index); fileName = (String)listitem.getValue(); } return fileName; } // getFileName /** * Action Listener * @param e event */ public void onEvent(Event e) { // Save and Close if (e.getTarget() == bOk) { String newText = text.getText(); if (newText == null) newText = ""; String oldText = m_attachment.getTextMsg(); if (oldText == null) oldText = ""; if (!m_change) m_change = !newText.equals(oldText); if (newText.length() > 0 || m_attachment.getEntryCount() > 0) { if (m_change) { m_attachment.setBinaryData(new byte[0]); // ATTENTION! HEAVY HACK HERE... Else it will not save :( m_attachment.setTextMsg(text.getText()); m_attachment.save(); } } else m_attachment.delete(true); dispose(); } // Cancel else if (e.getTarget() == bCancel) { dispose(); } // Delete Attachment else if (e.getTarget() == bDeleteAll) { deleteAttachment(); dispose(); } // Delete individual entry and Return else if (e.getTarget() == bDelete) deleteAttachmentEntry(); // Show Data else if (e.getTarget() == cbContent) displayData (cbContent.getSelectedIndex(), false); // Load Attachment else if (e.getTarget() == bLoad) loadFile(); // Open Attachment else if (e.getTarget() == bSave) saveAttachmentToFile(); else if (e.getTarget() == bRefresh) displayData(displayIndex, true); else if (e.getTarget() instanceof Timer) displayData(displayIndex, true); } // onEvent /************************************************************************** * Load file for attachment */ private void loadFile() { log.info(""); preview.setVisible(false); Media media = null; try { media = Fileupload.get(true); if (media != null) { // pdfViewer.setContent(media); ; } else { preview.setVisible(true); preview.invalidate(); return; } } catch (InterruptedException e) { log.log(Level.WARNING, e.getLocalizedMessage(), e); } String fileName = media.getName(); log.config(fileName); int cnt = m_attachment.getEntryCount(); //update for (int i = 0; i < cnt; i++) { if (m_attachment.getEntryName(i).equals(fileName)) { m_attachment.updateEntry(i, getMediaData(media)); cbContent.setSelectedIndex(i); displayData(cbContent.getSelectedIndex(), false); m_change = true; return; } } //new if (m_attachment.addEntry(fileName, getMediaData(media))) { cbContent.appendItem(media.getName(), media.getName()); cbContent.setSelectedIndex(cbContent.getItemCount()-1); displayData(cbContent.getSelectedIndex(), false); m_change = true; } } // getFileName private byte[] getMediaData(Media media) { byte[] bytes = null; if (media.inMemory()) bytes = media.getByteData(); else { InputStream is = media.getStreamData(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buf = new byte[ 1000 ]; int byteread = 0; try { while (( byteread=is.read(buf) )!=-1) baos.write(buf,0,byteread); } catch (IOException e) { log.log(Level.SEVERE, e.getLocalizedMessage(), e); throw new IllegalStateException(e.getLocalizedMessage()); } bytes = baos.toByteArray(); } return bytes; } /** * Delete entire Attachment */ private void deleteAttachment() { log.info(""); if (FDialog.ask(m_WindowNo, this, "AttachmentDelete?")) m_attachment.delete(true); } // deleteAttachment /** * Delete Attachment Entry */ private void deleteAttachmentEntry() { log.info(""); int index = cbContent.getSelectedIndex(); String fileName = getFileName(index); if (fileName == null) return; if (FDialog.ask(m_WindowNo, this, "AttachmentDeleteEntry?")) { if (m_attachment.deleteEntry(index)) cbContent.removeItemAt(index); m_change = true; } } // deleteAttachment /** * Save Attachment to File */ private void saveAttachmentToFile() { int index = cbContent.getSelectedIndex(); log.info("index=" + index); if (m_attachment.getEntryCount() < index) return; MAttachmentEntry entry = m_attachment.getEntry(index); if (entry != null && entry.getData() != null) { try { AMedia media = new AMedia(entry.getName(), null, entry.getContentType(), entry.getData()); Filedownload.save(media); } catch (Exception e) { log.log(Level.SEVERE, "attachment", e); } } } // saveAttachmentToFile }