diff --git a/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java b/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java index 00b2a02fed..32c22c291e 100644 --- a/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java +++ b/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java @@ -29,9 +29,13 @@ import java.math.BigDecimal; import java.security.GeneralSecurityException; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Properties; +import org.adempiere.base.Core; +import org.adempiere.base.upload.IUploadService; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.SecureEngine; @@ -192,5 +196,21 @@ public class MAuthorizationAccount extends X_AD_AuthorizationAccount { refresh(); return getAccessToken(); } + + /** + * + * @return map of {@link MAuthorizationAccount} and {@link IUploadService} + */ + public static Map getUserUploadServices() { + Map uploadServicesMap = new HashMap<>(); + List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); + for (MAuthorizationAccount account : accounts) { + IUploadService service = Core.getUploadService(account); + if (service != null) { + uploadServicesMap.put(account, service); + } + } + return uploadServicesMap; + } } // MAuthorizationAccount diff --git a/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF b/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF index 528acc2fa0..b09ae0a60b 100644 --- a/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF +++ b/org.adempiere.report.jasper.library/META-INF/MANIFEST.MF @@ -14,6 +14,8 @@ Bundle-ClassPath: ., lib/jasperreports-fonts.jar, lib/jasperreports-functions.jar, lib/olap4j.jar, - lib/xmpcore.jar + lib/xmpcore.jar, + lib/SparseBitSet.jar Automatic-Module-Name: org.adempiere.report.jasper.library Bundle-Vendor: iDempiere Community +Export-Package: com.zaxxer.sparsebits diff --git a/org.adempiere.report.jasper.library/build.properties b/org.adempiere.report.jasper.library/build.properties index 171ad02aa4..ce497492af 100644 --- a/org.adempiere.report.jasper.library/build.properties +++ b/org.adempiere.report.jasper.library/build.properties @@ -7,4 +7,5 @@ bin.includes = META-INF/,\ lib/jasperreports-fonts.jar,\ lib/jasperreports-functions.jar,\ lib/olap4j.jar,\ - lib/xmpcore.jar + lib/xmpcore.jar,\ + lib/SparseBitSet.jar diff --git a/org.adempiere.report.jasper.library/pom.xml b/org.adempiere.report.jasper.library/pom.xml index 5feac9bfc2..3ae6b5f6b0 100644 --- a/org.adempiere.report.jasper.library/pom.xml +++ b/org.adempiere.report.jasper.library/pom.xml @@ -63,6 +63,11 @@ xmpcore 5.1.3 + + com.zaxxer + SparseBitSet + 1.2 + lib true diff --git a/org.adempiere.server-feature/feature.xml b/org.adempiere.server-feature/feature.xml index 72a1869276..abd8dc62ed 100644 --- a/org.adempiere.server-feature/feature.xml +++ b/org.adempiere.server-feature/feature.xml @@ -552,4 +552,12 @@ version="0.0.0" unpack="false"/> + + diff --git a/org.adempiere.server-feature/server.product.launch b/org.adempiere.server-feature/server.product.launch index 22fe12cf1c..e58b970d74 100644 --- a/org.adempiere.server-feature/server.product.launch +++ b/org.adempiere.server-feature/server.product.launch @@ -408,6 +408,7 @@ + diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 8b62a485ef..c646c66ebe 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -5,7 +5,20 @@ Bundle-SymbolicName: org.adempiere.ui.zk;singleton:=true Bundle-Version: 8.2.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=11))" -Import-Package: groovy.transform.stc;version="2.4.7", +Import-Package: com.google.common.annotations;version="30.1.1", + com.google.common.base;version="30.1.1", + com.google.common.cache;version="30.1.1", + com.google.common.collect;version="30.1.1", + com.google.common.escape;version="30.1.1", + com.google.common.graph;version="30.1.1", + com.google.common.hash;version="30.1.1", + com.google.common.io;version="30.1.1", + com.google.common.math;version="30.1.1", + com.google.common.net;version="30.1.1", + com.google.common.primitives;version="30.1.1", + com.google.common.reflect;version="30.1.1", + com.google.common.util.concurrent;version="30.1.1", + groovy.transform.stc;version="2.4.7", javax.annotation, javax.annotation.processing, javax.annotation.security, @@ -89,14 +102,15 @@ Export-Package: fi.jawsy.jawwa.zk.atmosphere, org.adempiere.webui.theme, org.adempiere.webui.util, org.adempiere.webui.window, + org.idempiere.ui.zk.media, org.zkforge.ckez, org.zkforge.keylistener, web.chosenbox.img, + web.ckez.html, + web.ckez.img, web.js.chosenbox, web.js.chosenbox.css, web.js.chosenbox.mold, - web.ckez.html, - web.ckez.img, web.js.ckez, web.js.ckez.ext.CKeditor, web.js.ckez.ext.CKeditor.adapters, diff --git a/org.adempiere.ui.zk/WEB-INF/jetty-web.xml b/org.adempiere.ui.zk/WEB-INF/jetty-web.xml index aa789f9821..5c82bcacd7 100644 --- a/org.adempiere.ui.zk/WEB-INF/jetty-web.xml +++ b/org.adempiere.ui.zk/WEB-INF/jetty-web.xml @@ -4,4 +4,5 @@ 1048576 + 2000 \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java index f11559e697..7be2c32fd9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/Extensions.java @@ -43,6 +43,8 @@ import org.compiere.grid.IPaymentFormFactory; import org.compiere.model.GridTab; import org.compiere.model.MDashboardContent; import org.compiere.util.CCache; +import org.idempiere.ui.zk.media.IMediaView; +import org.idempiere.ui.zk.media.IMediaViewProvider; import org.zkoss.zk.ui.Component; /** @@ -317,5 +319,46 @@ public class Extensions { return quickEntry; } return null; - } + } + + private static final CCache> s_mediaViewProviderCache = new CCache<>("_IMediaViewProvider_Cache", "IMediaViewProvider", 100, false); + + /** + * + * @param contentType + * @param extension + * @param mobile + * @return {@link IMediaView} + */ + public static IMediaView getMediaView(String contentType, String extension, boolean mobile) { + String key = contentType + "|" + extension; + + IMediaView view = null; + IServiceReferenceHolder cache = s_mediaViewProviderCache.get(key); + if (cache != null) { + IMediaViewProvider service = cache.getService(); + if (service != null) { + view = service.getMediaView(contentType, extension, mobile); + if (view != null) + return view; + } + s_mediaViewProviderCache.remove(key); + } + List> serviceReferences = Service.locator().list(IMediaViewProvider.class).getServiceReferences(); + if (serviceReferences == null) + return null; + for (IServiceReferenceHolder serviceReference : serviceReferences) + { + IMediaViewProvider service = serviceReference.getService(); + if (service != null) { + view = service.getMediaView(contentType, extension, mobile); + if (view != null) { + s_mediaViewProviderCache.put(key, serviceReference); + return view; + } + } + } + + return null; + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java index aeb9ce905a..f865f3e4bf 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java @@ -140,7 +140,6 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis }; private CustomForm form; -// private Vbox queryPanel = new Vbox(); private Checkbox reportField = new Checkbox(); private Label processLabel = new Label(Msg.translate(Env.getCtx(), "AD_Process_ID")); private Listbox processField = new Listbox(); @@ -160,7 +159,6 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis private Datebox createdQFrom = new Datebox(); private Datebox createdQTo = new Datebox(); -// private Vbox viewEnterPanel = new Vbox(); private Button bBack = new Button(); private Button bNext = new Button(); private Label positionInfo = new Label("."); @@ -259,7 +257,7 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis private void jbInit() throws Exception { ZKUpdateUtil.setWidth(tabbox, "100%"); - ZKUpdateUtil.setHeight(tabbox, "90%"); + ZKUpdateUtil.setVflex(tabbox, "1"); tabbox.appendChild(tabs); tabbox.appendChild(tabpanels); tabbox.addEventListener(Events.ON_SELECT, this); @@ -573,6 +571,8 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis tabpanels.appendChild(tabViewPanel); confirmPanel.addActionListener(this); + ZKUpdateUtil.setVflex(confirmPanel, "min"); + confirmPanel.setStyle("padding-top: 2px;padding-bottom: 2px;"); updateQDisplay(); iframe.setId("reportFrame"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index 3f10c5c1ad..e45318c9d3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -17,6 +17,7 @@ import java.util.Properties; import java.util.TreeMap; import java.util.logging.Level; +import org.adempiere.base.upload.IUploadService; import org.adempiere.exceptions.AdempiereException; import org.adempiere.impexp.AbstractExcelExporter; import org.adempiere.model.IInfoColumn; @@ -49,6 +50,7 @@ import org.adempiere.webui.component.Tabpanels; import org.adempiere.webui.component.Tabs; import org.adempiere.webui.component.WInfoWindowListItemRenderer; import org.adempiere.webui.component.WListbox; +import org.adempiere.webui.component.Window; import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WSearchEditor; import org.adempiere.webui.editor.WTableDirEditor; @@ -75,6 +77,7 @@ import org.compiere.model.GridWindow; import org.compiere.model.InfoColumnVO; import org.compiere.model.InfoRelatedVO; import org.compiere.model.Lookup; +import org.compiere.model.MAuthorizationAccount; import org.compiere.model.MInfoColumn; import org.compiere.model.MInfoWindow; import org.compiere.model.MLookupFactory; @@ -93,6 +96,9 @@ import org.compiere.util.Msg; import org.compiere.util.Trx; import org.compiere.util.Util; import org.compiere.util.ValueNamePair; +import org.idempiere.ui.zk.media.IMediaView; +import org.idempiere.ui.zk.media.Medias; +import org.idempiere.ui.zk.media.WMediaOptions; import org.zkoss.util.media.AMedia; import org.zkoss.zk.au.out.AuEcho; import org.zkoss.zk.ui.Component; @@ -2603,7 +2609,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL String dataSql = buildDataSQL(0, 0); - File file = File.createTempFile("Export", ".xls"); + File file = File.createTempFile(infoWindow.get_Translation("Name")+"_", ".xls"); testCount(); @@ -2641,9 +2647,24 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL currentRow = -1; } - AMedia media = null; - media = new AMedia(file.getName(), null, "application/vnd.ms-excel", file, true); - Filedownload.save(media); + AMedia media = new AMedia(file.getName(), null, Medias.EXCEL_MIME_TYPE, file, true); + IMediaView view = Extensions.getMediaView(Medias.EXCEL_MIME_TYPE, Medias.EXCEL_FILE_EXT, ClientInfo.isMobile()); + Map uploadServicesMap = MAuthorizationAccount.getUserUploadServices(); + if (view != null || uploadServicesMap.size() > 0) { + WMediaOptions options = new WMediaOptions(media, view != null ? () -> { + Window viewWindow = new Window(); + viewWindow.setWidth("100%"); + viewWindow.setHeight("100%"); + viewWindow.setTitle(media.getName()); + viewWindow.setAttribute(Window.MODE_KEY, Mode.EMBEDDED); + AEnv.showWindow(viewWindow); + view.renderMediaView(viewWindow, media, false); + } : null, uploadServicesMap); + options.setPage(getPage()); + options.doHighlighted(); + } else { + Filedownload.save(media); + } } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java index 1ecd8c63ac..06fab1f190 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java @@ -30,6 +30,7 @@ import org.adempiere.exceptions.AdempiereException; import org.adempiere.util.Callback; import org.adempiere.webui.AdempiereWebUI; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ConfirmPanel; @@ -53,9 +54,11 @@ import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.ui.zk.media.IMediaView; import org.zkoss.util.media.AMedia; import org.zkoss.util.media.Media; import org.zkoss.zk.au.out.AuEcho; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; @@ -125,6 +128,8 @@ public class WAttachment extends Window implements EventListener private int maxPreviewSize; + private Component customPreviewComponent; + private static List autoPreviewList; static { @@ -465,6 +470,18 @@ public class WAttachment extends Window implements EventListener else { clearPreview(); + IMediaView view = Extensions.getMediaView(mimeType, getExtension(entry.getName()), ClientInfo.isMobile()); + if (view != null) + { + if (data.length <= maxPreviewSize) { + AMedia media = new AMedia(entry.getName(), null, mimeType, entry.getData()); + customPreviewComponent = view.renderMediaView(previewPanel, media, true); + return true; + } else { + return false; + } + } + return false; } } @@ -478,6 +495,14 @@ public class WAttachment extends Window implements EventListener } } + private String getExtension(String name) { + int index = name.lastIndexOf("."); + if (index > 0) { + return name.substring(index+1); + } + return ""; + } + /** * Display gif or jpg in gifPanel * @param index index @@ -501,6 +526,11 @@ public class WAttachment extends Window implements EventListener { preview.setSrc(null); preview.setVisible(false); + if (customPreviewComponent != null) + { + customPreviewComponent.detach(); + customPreviewComponent = null; + } } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java index 91bb654e75..74600e4673 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java @@ -29,6 +29,7 @@ import java.util.Map; import org.adempiere.base.upload.IUploadService; import org.compiere.model.MAuthorizationAccount; +import org.idempiere.ui.zk.media.Medias; import org.zkoss.util.media.AMedia; /** @@ -38,24 +39,24 @@ import org.zkoss.util.media.AMedia; */ public interface IReportViewerExportSource { - public static final String CSV_MIME_TYPE = "text/csv"; - public static final String EXCEL_MIME_TYPE = "application/vnd.ms-excel"; - public static final String EXCEL_XML_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; - public static final String HTML_MIME_TYPE = "text/html"; - public static final String PDF_MIME_TYPE = "application/pdf"; - public static final String POSTSCRIPT_MIME_TYPE = "application/postscript"; - public static final String TEXT_MIME_TYPE = "text/plain"; - public static final String XML_MIME_TYPE = "text/xml"; + public static final String CSV_MIME_TYPE = Medias.CSV_MIME_TYPE; + public static final String EXCEL_MIME_TYPE = Medias.EXCEL_MIME_TYPE; + public static final String EXCEL_XML_MIME_TYPE = Medias.EXCEL_XML_MIME_TYPE; + public static final String HTML_MIME_TYPE = Medias.HTML_MIME_TYPE; + public static final String PDF_MIME_TYPE = Medias.PDF_MIME_TYPE; + public static final String POSTSCRIPT_MIME_TYPE = Medias.POSTSCRIPT_MIME_TYPE; + public static final String TEXT_MIME_TYPE = Medias.TEXT_MIME_TYPE; + public static final String XML_MIME_TYPE = Medias.XML_MIME_TYPE; - public static final String CSV_FILE_EXT = "csv"; - public static final String SSV_FILE_EXT = "ssv"; - public static final String EXCEL_FILE_EXT = "xls"; - public static final String EXCEL_XML_FILE_EXT = "xlsx"; - public static final String HTML_FILE_EXT = "html"; - public static final String PDF_FILE_EXT = "pdf"; - public static final String POSTSCRIPT_FILE_EXT = "ps"; - public static final String TEXT_FILE_EXT = "txt"; - public static final String XML_FILE_EXT = "xml"; + public static final String CSV_FILE_EXT = Medias.CSV_FILE_EXT; + public static final String SSV_FILE_EXT = Medias.SSV_FILE_EXT; + public static final String EXCEL_FILE_EXT = Medias.EXCEL_FILE_EXT; + public static final String EXCEL_XML_FILE_EXT = Medias.EXCEL_XML_FILE_EXT; + public static final String HTML_FILE_EXT = Medias.HTML_FILE_EXT; + public static final String PDF_FILE_EXT = Medias.PDF_FILE_EXT; + public static final String POSTSCRIPT_FILE_EXT = Medias.POSTSCRIPT_FILE_EXT; + public static final String TEXT_FILE_EXT = Medias.TEXT_FILE_EXT; + public static final String XML_FILE_EXT = Medias.XML_FILE_EXT; /** * Get media/content by content type and file extension diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index 8b6ba9c505..3aed3bc9f9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -7,17 +7,16 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.function.Supplier; import java.util.logging.Level; import javax.activation.FileDataSource; -import org.adempiere.base.Core; import org.adempiere.base.upload.IUploadService; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Listbox; @@ -40,6 +39,8 @@ import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.ui.zk.media.IMediaView; +import org.idempiere.ui.zk.media.WMediaOptions; import org.zkoss.util.media.AMedia; import org.zkoss.util.media.Media; import org.zkoss.zk.ui.Component; @@ -114,7 +115,6 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl protected static final String CSV_OUTPUT_TYPE = "CSV"; protected static final String HTML_OUTPUT_TYPE = "HTML"; protected static final String PDF_OUTPUT_TYPE = "PDF"; - protected static final String SSV_OUTPUT_TYPE = "SSV"; protected static final String XLS_OUTPUT_TYPE = "XLS"; protected static final String XLSX_OUTPUT_TYPE = "XLSX"; @@ -129,6 +129,8 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl new ExportFormat(EXCEL_XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), EXCEL_XML_FILE_EXT, EXCEL_XML_MIME_TYPE), new ExportFormat(SSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), SSV_FILE_EXT, CSV_MIME_TYPE) }; + + private Center center; public ZkJRViewer(JasperPrint jasperPrint, String title, PrintInfo printInfo) { super(); @@ -178,6 +180,12 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()));//It gets default Jasper output type } + if (Util.isEmpty(defaultType)) { + defaultType = PDF_OUTPUT_TYPE; + } + + initMediaSuppliers(); + Borderlayout layout = new Borderlayout(); layout.setStyle("position: absolute; height: 99%; width: 99%"); this.appendChild(layout); @@ -193,7 +201,6 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.appendItem(HTML_OUTPUT_TYPE, HTML_OUTPUT_TYPE); previewType.appendItem(XLS_OUTPUT_TYPE, XLS_OUTPUT_TYPE); previewType.appendItem(CSV_OUTPUT_TYPE, CSV_OUTPUT_TYPE); - previewType.appendItem(SSV_OUTPUT_TYPE, SSV_OUTPUT_TYPE); previewType.appendItem(XLSX_OUTPUT_TYPE, XLSX_OUTPUT_TYPE); if (PDF_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(0); @@ -203,10 +210,8 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setSelectedIndex(2); } else if (CSV_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(3); - } else if (SSV_OUTPUT_TYPE.equals(defaultType)) { - previewType.setSelectedIndex(4); } else if (XLSX_OUTPUT_TYPE.equals(defaultType)) { - previewType.setSelectedIndex(5); + previewType.setSelectedIndex(4); } else { previewType.setSelectedIndex(0); log.info("Format not Valid: "+defaultType); @@ -222,8 +227,6 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setSelectedIndex(0); // default to PDF if cannot export } else if ("CSV".equals(defaultType)) { previewType.setSelectedIndex(0); // default to PDF if cannot export - } else if ("SSV".equals(defaultType)) { - previewType.setSelectedIndex(0); // default to PDF if cannot export } else if ("XLSX".equals(defaultType)) { previewType.setSelectedIndex(0); // default to PDF if cannot export } else { @@ -269,13 +272,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl if (ThemeManager.isUseFontIconForImage()) LayoutUtils.addSclass("medium-toolbarbutton", bExport); - List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); - for (MAuthorizationAccount account : accounts) { - IUploadService service = Core.getUploadService(account); - if (service != null) { - uploadServicesMap.put(account, service); - } - } + uploadServicesMap = MAuthorizationAccount.getUserUploadServices(); if (uploadServicesMap.size() > 0) { bCloudUpload.setName("CloudUpload"); if (ThemeManager.isUseFontIconForImage()) @@ -293,7 +290,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl north.appendChild(toolbar); ZKUpdateUtil.setVflex(north, "min"); - Center center = new Center(); + center = new Center(); layout.appendChild(center); iframe = new Iframe(); ZKUpdateUtil.setHflex(iframe, "true"); @@ -310,9 +307,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } center.appendChild(iframe); - this.setBorder("normal"); - - initMediaSuppliers(); + this.setBorder("normal"); } private void initMediaSuppliers() { @@ -456,7 +451,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); exporter.exportReport(); - return new AMedia(m_title+"."+CSV_FILE_EXT, CSV_FILE_EXT, CSV_MIME_TYPE, file, true); + return new AMedia(m_title+"."+CSV_FILE_EXT, CSV_FILE_EXT, CSV_MIME_TYPE, file, false); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -490,7 +485,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl exporter.setConfiguration(csvConfig); exporter.exportReport(); - return new AMedia(m_title+"."+SSV_FILE_EXT, SSV_FILE_EXT, CSV_MIME_TYPE, file, true); + return new AMedia(m_title+"."+SSV_FILE_EXT, SSV_FILE_EXT, CSV_MIME_TYPE, file, false); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -614,11 +609,9 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } else if (XLS_OUTPUT_TYPE.equals(reportType)) { createNewMedia(EXCEL_MIME_TYPE, EXCEL_FILE_EXT); } else if (XLSX_OUTPUT_TYPE.equals(reportType)) { - createNewMedia(EXCEL_XML_MIME_TYPE, EXCEL_FILE_EXT); + createNewMedia(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT); } else if (CSV_OUTPUT_TYPE.equals(reportType)) { createNewMedia(CSV_MIME_TYPE, CSV_FILE_EXT); - }else if (SSV_OUTPUT_TYPE.equals(reportType)) { - createNewMedia(CSV_MIME_TYPE, SSV_FILE_EXT); } } finally { Thread.currentThread().setContextClassLoader(cl); @@ -655,26 +648,75 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } public void onRenderReport() { - if (ClientInfo.isMobile()) { - Listitem selected = previewType.getSelectedItem(); - String reportType=selected.getValue(); + Listitem selected = previewType.getSelectedItem(); + String reportType=selected.getValue(); + if (ClientInfo.isMobile()) { if ( PDF_OUTPUT_TYPE.equals( reportType ) ) { openWithPdfJsViewer(); - return; + } else if (HTML_OUTPUT_TYPE.equals(reportType)) { + attachIFrame(); + iframe.setSrc(null); + iframe.setContent(media); + } else { + IMediaView view = null; + boolean showOptions = false; + if (XLS_OUTPUT_TYPE.equals(reportType) || XLSX_OUTPUT_TYPE.equals(reportType)) { + if (XLS_OUTPUT_TYPE.equals(reportType)) + view = Extensions.getMediaView(EXCEL_MIME_TYPE, EXCEL_FILE_EXT, true); + else + view = Extensions.getMediaView(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT, true); + showOptions = true; + } else if (CSV_OUTPUT_TYPE.equals(reportType)) { + view = Extensions.getMediaView(CSV_MIME_TYPE, CSV_FILE_EXT, true); + showOptions = true; + } + + if (showOptions && (view != null || uploadServicesMap.size() > 0)) { + clearPreviewContainer(); + final IMediaView fview = view; + WMediaOptions options = new WMediaOptions(media, fview != null ? () -> fview.renderMediaView(center, media, true) : null, uploadServicesMap); + options.setPage(getPage()); + options.doHighlighted(); + } else { + attachIFrame(); + iframe.setSrc(null); + iframe.setContent(media); + } } } else { - Listitem selected = previewType.getSelectedItem(); - String reportType=selected.getValue(); if (MSysConfig.getBooleanValue(MSysConfig.ZK_USE_PDF_JS_VIEWER, false, Env.getAD_Client_ID(Env.getCtx())) && "PDF".equals( reportType ) ) { openWithPdfJsViewer(); } else { - iframe.setSrc(null); - iframe.setContent(media); + IMediaView view = null; + boolean showOptions = false; + if (XLS_OUTPUT_TYPE.equals(reportType) || XLSX_OUTPUT_TYPE.equals(reportType)) { + if (XLS_OUTPUT_TYPE.equals(reportType)) + view = Extensions.getMediaView(EXCEL_MIME_TYPE, EXCEL_FILE_EXT, false); + else + view = Extensions.getMediaView(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT, false); + showOptions = true; + } else if (CSV_OUTPUT_TYPE.equals(reportType)) { + view = Extensions.getMediaView(CSV_MIME_TYPE, CSV_FILE_EXT, false); + showOptions = true; + } + + if (showOptions && (view != null || uploadServicesMap.size() > 0)) { + clearPreviewContainer(); + final IMediaView fview = view; + WMediaOptions options = new WMediaOptions(media, fview != null ? () -> fview.renderMediaView(center, media, true) : null, uploadServicesMap); + options.setPage(getPage()); + options.doHighlighted(); + } else { + attachIFrame(); + iframe.setSrc(null); + iframe.setContent(media); + } } } } protected void openWithPdfJsViewer() { + attachIFrame(); mediaVersion++; String url = Utils.getDynamicMediaURI(this, mediaVersion, media.getName(), media.getFormat()); String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; @@ -682,6 +724,17 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl iframe.setSrc(pdfJsUrl); } + private void clearPreviewContainer() { + center.getChildren().clear(); + } + + private void attachIFrame() { + if (iframe != null && iframe.getPage() == null) { + center.getChildren().clear(); + center.appendChild(iframe); + } + } + @Override public void onClose(Tabpanel tabPanel) { Tab tab = tabPanel.getLinkedTab(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java index 1b43f3165b..fd6e02aa2e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java @@ -24,7 +24,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Properties; import java.util.function.Supplier; @@ -33,12 +32,12 @@ import java.util.logging.Level; import javax.activation.FileDataSource; import javax.servlet.http.HttpServletRequest; -import org.adempiere.base.Core; import org.adempiere.base.upload.IUploadService; import org.adempiere.exceptions.DBException; import org.adempiere.pdf.Document; import org.adempiere.util.ContextRunnable; import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.Extensions; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.BusyDialog; @@ -90,6 +89,8 @@ import org.compiere.util.KeyNamePair; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.idempiere.ui.zk.media.IMediaView; +import org.idempiere.ui.zk.media.WMediaOptions; import org.zkoss.util.media.AMedia; import org.zkoss.util.media.Media; import org.zkoss.zk.au.out.AuScript; @@ -224,6 +225,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab }; private final Map> mediaSuppliers = new HashMap>(); + + private Center center; /** * Static Layout * @throws Exception @@ -325,7 +328,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab } File file = File.createTempFile(prefix, "."+CSV_FILE_EXT, new File(path)); m_reportEngine.createCSV(file, ',', AEnv.getLanguage(Env.getCtx())); - return new AMedia(file.getName(), CSV_FILE_EXT, CSV_MIME_TYPE, file, true); + return new AMedia(file.getName(), CSV_FILE_EXT, CSV_MIME_TYPE, file, false); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -363,21 +366,21 @@ public class ZkReportViewer extends Window implements EventListener, ITab mediaSuppliers.put(toMediaType(XML_MIME_TYPE, XML_FILE_EXT), () -> { StringWriter sw = new StringWriter(); m_reportEngine.createXML(sw); - byte[] data = sw.getBuffer().toString().getBytes(); + String data = sw.getBuffer().toString(); return new AMedia(m_reportEngine.getName() + "."+XML_FILE_EXT, XML_FILE_EXT, XML_MIME_TYPE, data); }); mediaSuppliers.put(toMediaType(CSV_MIME_TYPE, SSV_FILE_EXT), () -> { StringWriter sw = new StringWriter(); m_reportEngine.createCSV(sw, ';', m_reportEngine.getPrintFormat().getLanguage()); - byte[] data = sw.getBuffer().toString().getBytes(); + String data = sw.getBuffer().toString(); return new AMedia(m_reportEngine.getName() + "."+SSV_FILE_EXT, SSV_FILE_EXT, CSV_MIME_TYPE, data); }); mediaSuppliers.put(toMediaType(TEXT_MIME_TYPE, TEXT_FILE_EXT), () -> { StringWriter sw = new StringWriter(); m_reportEngine.createCSV(sw, '\t', m_reportEngine.getPrintFormat().getLanguage()); - byte[] data = sw.getBuffer().toString().getBytes(); + String data = sw.getBuffer().toString(); return new AMedia(m_reportEngine.getName() + "."+TEXT_FILE_EXT, TEXT_FILE_EXT, TEXT_MIME_TYPE, data); }); } @@ -412,10 +415,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab private void init() { Borderlayout layout = new Borderlayout(); - layout.setStyle("position: absolute; height: 97%; width: 98%; border:none; padding:none; margin:none;"); + layout.setWidth("100%"); + layout.setHeight("100%"); this.appendChild(layout); - this.setStyle("width: 100%; height: 100%; position: absolute; border:none; padding:none; margin:none;"); - + this.setWidth("100%"); + this.setHeight("100%"); + ZKUpdateUtil.setHeight(toolBar, "32px"); ZKUpdateUtil.setWidth(toolBar, "100%"); @@ -698,13 +703,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab if (m_isCanExport) { - List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); - for (MAuthorizationAccount account : accounts) { - IUploadService service = Core.getUploadService(account); - if (service != null) { - uploadServicesMap.put(account, service); - } - } + uploadServicesMap = MAuthorizationAccount.getUserUploadServices(); if (uploadServicesMap.size() > 0) { bCloudUpload.setName("CloudUpload"); if (ThemeManager.isUseFontIconForImage()) @@ -728,7 +727,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab north.appendChild(toolBar); ZKUpdateUtil.setVflex(north, "min"); - Center center = new Center(); + center = new Center(); layout.appendChild(center); iframe = new Iframe(); ZKUpdateUtil.setWidth(iframe, "100%"); @@ -851,27 +850,74 @@ public class ZkReportViewer extends Window implements EventListener, ITab reportLink.setHref(url); reportLink.setLabel(media.getName()); - if (ClientInfo.isMobile()) { - Listitem selected = previewType.getSelectedItem(); - if (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue())) { + Listitem selected = previewType.getSelectedItem(); + String outputType = previewType.getSelectedItem().getValue(); + if (ClientInfo.isMobile()) { + if (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue())) { + attachIFrame(); iframe.setSrc(pdfJsUrl); - } else if (HTML_OUTPUT_TYPE.equals(previewType.getSelectedItem().getValue())) { + } else if (HTML_OUTPUT_TYPE.equals(outputType)) { + attachIFrame(); iframe.setSrc(null); iframe.setContent(media); } else { - iframe.setSrc(null); - iframe.setContent(null); - String script = "zk.Widget.$('#" + reportLink.getUuid()+"').$n().click();"; - Clients.evalJavaScript(script); + IMediaView view = null; + boolean showOptions = false; + if (XLS_OUTPUT_TYPE.equals(outputType) || XLSX_OUTPUT_TYPE.equals(outputType)) { + if (XLS_OUTPUT_TYPE.equals(outputType)) + view = Extensions.getMediaView(EXCEL_MIME_TYPE, EXCEL_FILE_EXT, true); + else + view = Extensions.getMediaView(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT, true); + showOptions = true; + } else if (CSV_OUTPUT_TYPE.equals(outputType)) { + view = Extensions.getMediaView(CSV_MIME_TYPE, CSV_FILE_EXT, true); + showOptions = true; + } + + if (showOptions && (view != null || uploadServicesMap.size() > 0)) { + detachIFrame(); + final IMediaView fview = view; + WMediaOptions options = new WMediaOptions(media, fview != null ? () -> fview.renderMediaView(center, media, true) : null, uploadServicesMap); + options.setPage(getPage()); + options.doHighlighted(); + } else { + attachIFrame(); + iframe.setSrc(null); + iframe.setContent(null); + String script = "zk.Widget.$('#" + reportLink.getUuid()+"').$n().click();"; + Clients.evalJavaScript(script); + } } } else { - Listitem selected = previewType.getSelectedItem(); if (MSysConfig.getBooleanValue(MSysConfig.ZK_USE_PDF_JS_VIEWER, false, Env.getAD_Client_ID(Env.getCtx())) && (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue()))) { + attachIFrame(); iframe.setSrc(pdfJsUrl); } else { - iframe.setSrc(null); - iframe.setContent(media); + IMediaView view = null; + boolean showOptions = false; + if (XLS_OUTPUT_TYPE.equals(outputType) || XLSX_OUTPUT_TYPE.equals(outputType)) { + if (XLS_OUTPUT_TYPE.equals(outputType)) + view = Extensions.getMediaView(EXCEL_MIME_TYPE, EXCEL_FILE_EXT, false); + else + view = Extensions.getMediaView(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT, false); + showOptions = true; + } else if (CSV_OUTPUT_TYPE.equals(outputType)) { + view = Extensions.getMediaView(CSV_MIME_TYPE, CSV_FILE_EXT, false); + showOptions = true; + } + + if (showOptions && (view != null || uploadServicesMap.size() > 0)) { + detachIFrame(); + final IMediaView fview = view; + WMediaOptions options = new WMediaOptions(media, fview != null ? () -> fview.renderMediaView(center, media, true) : null, uploadServicesMap); + options.setPage(getPage()); + options.doHighlighted(); + } else { + attachIFrame(); + iframe.setSrc(null); + iframe.setContent(media); + } } } @@ -881,6 +927,17 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } + private void detachIFrame() { + center.getChildren().clear(); + } + + private void attachIFrame() { + if (iframe != null && iframe.getPage() == null) { + center.getChildren().clear(); + center.appendChild(iframe); + } + } + private String makePrefix(String name) { StringBuilder prefix = new StringBuilder(); char[] nameArray = name.toCharArray(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaView.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaView.java new file mode 100644 index 0000000000..d2fb3d324e --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaView.java @@ -0,0 +1,37 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.ui.zk.media; + +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.Component; + +/** + * @author hengsin + * + */ +public interface IMediaView { + + public Component renderMediaView(Component container, AMedia media, boolean readOnly); +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaViewProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaViewProvider.java new file mode 100644 index 0000000000..d0ac70ab4f --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/IMediaViewProvider.java @@ -0,0 +1,41 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.ui.zk.media; + +/** + * @author hengsin + * + */ +public interface IMediaViewProvider { + + /** + * + * @param contentType mime type + * @param extension file extension + * @param mobile + * @return {@link IMediaView} instance or null + */ + public IMediaView getMediaView(String contentType, String extension, boolean mobile); +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/Medias.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/Medias.java new file mode 100644 index 0000000000..4ed74bc00f --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/Medias.java @@ -0,0 +1,58 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.ui.zk.media; + +import com.google.common.net.MediaType; + +/** + * + * @author hengsin + * + */ +public final class Medias { + + public static final String CSV_MIME_TYPE = MediaType.CSV_UTF_8.toString(); + public static final String EXCEL_MIME_TYPE = MediaType.MICROSOFT_EXCEL.toString(); + public static final String EXCEL_XML_MIME_TYPE = MediaType.OOXML_SHEET.toString(); + public static final String HTML_MIME_TYPE = MediaType.HTML_UTF_8.toString(); + public static final String PDF_MIME_TYPE = MediaType.PDF.toString(); + public static final String POSTSCRIPT_MIME_TYPE = MediaType.POSTSCRIPT.toString(); + public static final String TEXT_MIME_TYPE = MediaType.PLAIN_TEXT_UTF_8.toString(); + public static final String XML_MIME_TYPE = MediaType.XML_UTF_8.toString(); + + public static final String CSV_FILE_EXT = "csv"; + public static final String SSV_FILE_EXT = "ssv"; + public static final String EXCEL_FILE_EXT = "xls"; + public static final String EXCEL_XML_FILE_EXT = "xlsx"; + public static final String HTML_FILE_EXT = "html"; + public static final String PDF_FILE_EXT = "pdf"; + public static final String POSTSCRIPT_FILE_EXT = "ps"; + public static final String TEXT_FILE_EXT = "txt"; + public static final String XML_FILE_EXT = "xml"; + + private Medias() { + } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/WMediaOptions.java b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/WMediaOptions.java new file mode 100644 index 0000000000..3e4954d893 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/idempiere/ui/zk/media/WMediaOptions.java @@ -0,0 +1,134 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.ui.zk.media; + +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import org.adempiere.base.upload.IUploadHandler; +import org.adempiere.base.upload.IUploadService; +import org.adempiere.base.upload.UploadMedia; +import org.adempiere.base.upload.UploadResponse; +import org.adempiere.webui.component.Button; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.report.LinkWindow; +import org.adempiere.webui.util.ReaderInputStream; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.model.MAuthorizationAccount; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Filedownload; +import org.zkoss.zul.Vlayout; + +/** + * @author hengsin + * + */ +public class WMediaOptions extends Window { + + /** + * generated serial id + */ + private static final long serialVersionUID = 1642315087176748005L; + + /** + * + * @param media + * @param preview + * @param uploadServicesMap + */ + public WMediaOptions(AMedia media, Runnable preview, Map uploadServicesMap) { + setClosable(true); + setTitle(media.getName()); + ZKUpdateUtil.setWindowWidthX(this, 400); + setPosition("center,center"); + Vlayout vlayout = new Vlayout(); + vlayout.setHflex("1"); + appendChild(vlayout); + Button btn = new Button(Msg.getMsg(Env.getCtx(), "SaveFile")); + btn.setHflex("1"); + btn.setStyle("padding: 4px 8px"); + btn.addEventListener(Events.ON_CLICK, evt -> { + detach(); + Filedownload.save(media); + }); + vlayout.appendChild(btn); + + this.setSclass("popup-dialog"); + vlayout.setSclass("dialog-content"); + + if (preview != null) { + btn = new Button(Msg.getMsg(Env.getCtx(), "Preview")); + btn.setHflex("1"); + btn.setStyle("padding: 4px 8px"); + btn.addEventListener(Events.ON_CLICK, evt -> { + detach(); + preview.run(); + }); + vlayout.appendChild(btn); + } + + if (uploadServicesMap != null && !uploadServicesMap.isEmpty()) { + for(MAuthorizationAccount account : uploadServicesMap.keySet()) { + IUploadService uploadService = uploadServicesMap.get(account); + IUploadHandler[] handlers = uploadService.getUploadHandlers(media.getContentType()); + if (handlers != null && handlers.length > 0) { + for(IUploadHandler handler : handlers) { + btn = new Button(handler.getLabel()); + btn.setHflex("1"); + btn.setStyle("padding: 4px 8px"); + btn.addEventListener(Events.ON_CLICK, evt -> { + Page page = WMediaOptions.this.getPage(); + Clients.showBusy(this, Msg.getMsg(Env.getCtx(), "Processing")); + Executions.schedule(getDesktop(), e -> { + uploadMedia(media, account, handler, page); + Clients.clearBusy(WMediaOptions.this); + WMediaOptions.this.detach(); + }, new Event("onUploadMedia")); + }); + vlayout.appendChild(btn); + } + } + } + } + } + + private void uploadMedia(AMedia media, MAuthorizationAccount account, IUploadHandler handler, Page page) { + UploadResponse response = handler.uploadMedia(new UploadMedia(media.getName(), media.getContentType(), + media.isBinary() ? media.getStreamData() : new ReaderInputStream(media.getReaderData(), StandardCharsets.UTF_8.name()), + media.isBinary() ? media.getByteData().length : 0), account); + if (response != null && response.getLink() != null) { + LinkWindow linkWindow = new LinkWindow(response.getLink(), response.getLinkLabel()); + linkWindow.setPage(page); + linkWindow.doHighlighted(); + } + } +} diff --git a/org.adempiere.ui.zk/plugin.xml b/org.adempiere.ui.zk/plugin.xml index 92cd671eb9..7477968a47 100644 --- a/org.adempiere.ui.zk/plugin.xml +++ b/org.adempiere.ui.zk/plugin.xml @@ -3,5 +3,4 @@ - diff --git a/org.idempiere.keikai/.project b/org.idempiere.keikai/.project new file mode 100644 index 0000000000..b484d1a34c --- /dev/null +++ b/org.idempiere.keikai/.project @@ -0,0 +1,39 @@ + + + org.idempiere.keikai + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + + diff --git a/org.idempiere.keikai/.settings/org.eclipse.core.resources.prefs b/org.idempiere.keikai/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..99f26c0203 --- /dev/null +++ b/org.idempiere.keikai/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/org.idempiere.keikai/.settings/org.eclipse.m2e.core.prefs b/org.idempiere.keikai/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..f897a7f1cb --- /dev/null +++ b/org.idempiere.keikai/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/org.idempiere.keikai/META-INF/MANIFEST.MF b/org.idempiere.keikai/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..93b55988c5 --- /dev/null +++ b/org.idempiere.keikai/META-INF/MANIFEST.MF @@ -0,0 +1,214 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: zk keikai +Bundle-SymbolicName: org.idempiere.keikai +Bundle-Version: 8.2.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=11))" +Bundle-ClassPath: ., + lib/keikai-oss.jar, + lib/keikai-model-oss.jar, + lib/zpoi.jar, + lib/ooxml-schemas.jar +Export-Package: io.keikai.api, + io.keikai.api.impl, + io.keikai.api.model, + io.keikai.api.model.impl, + io.keikai.app, + io.keikai.app.impl, + io.keikai.model, + io.keikai.model.chart, + io.keikai.model.impl, + io.keikai.model.impl.chart, + io.keikai.model.impl.sys, + io.keikai.model.impl.sys.formula, + io.keikai.model.sys, + io.keikai.model.sys.dependency, + io.keikai.model.sys.format, + io.keikai.model.sys.formula, + io.keikai.model.sys.input, + io.keikai.model.util, + io.keikai.range, + io.keikai.range.impl, + io.keikai.range.impl.autofill, + io.keikai.range.impl.imexp, + io.keikai.theme, + io.keikai.ui, + io.keikai.ui.au.in, + io.keikai.ui.au.out, + io.keikai.ui.event, + io.keikai.ui.fn, + io.keikai.ui.impl, + io.keikai.ui.impl.ua, + io.keikai.ui.impl.undo, + io.keikai.ui.sys, + metainfo.tld, + metainfo.zk, + org.zkoss.poi, + org.zkoss.poi.common.usermodel, + org.zkoss.poi.ddf, + org.zkoss.poi.dev, + org.zkoss.poi.extractor, + org.zkoss.poi.hdf.event, + org.zkoss.poi.hdf.extractor, + org.zkoss.poi.hdf.extractor.data, + org.zkoss.poi.hdf.extractor.util, + org.zkoss.poi.hdf.model, + org.zkoss.poi.hdf.model.hdftypes, + org.zkoss.poi.hdf.model.hdftypes.definitions, + org.zkoss.poi.hdf.model.util, + org.zkoss.poi.hdgf, + org.zkoss.poi.hdgf.chunks, + org.zkoss.poi.hdgf.dev, + org.zkoss.poi.hdgf.exceptions, + org.zkoss.poi.hdgf.extractor, + org.zkoss.poi.hdgf.pointers, + org.zkoss.poi.hdgf.streams, + org.zkoss.poi.hmef, + org.zkoss.poi.hmef.attribute, + org.zkoss.poi.hmef.dev, + org.zkoss.poi.hmef.extractor, + org.zkoss.poi.hpbf, + org.zkoss.poi.hpbf.dev, + org.zkoss.poi.hpbf.extractor, + org.zkoss.poi.hpbf.model, + org.zkoss.poi.hpbf.model.qcbits, + org.zkoss.poi.hpsf, + org.zkoss.poi.hpsf.extractor, + org.zkoss.poi.hpsf.wellknown, + org.zkoss.poi.hslf, + org.zkoss.poi.hslf.blip, + org.zkoss.poi.hslf.dev, + org.zkoss.poi.hslf.exceptions, + org.zkoss.poi.hslf.extractor, + org.zkoss.poi.hslf.model, + org.zkoss.poi.hslf.model.textproperties, + org.zkoss.poi.hslf.record, + org.zkoss.poi.hslf.usermodel, + org.zkoss.poi.hslf.util, + org.zkoss.poi.hsmf, + org.zkoss.poi.hsmf.datatypes, + org.zkoss.poi.hsmf.dev, + org.zkoss.poi.hsmf.exceptions, + org.zkoss.poi.hsmf.extractor, + org.zkoss.poi.hsmf.parsers, + org.zkoss.poi.hssf, + org.zkoss.poi.hssf.converter, + org.zkoss.poi.hssf.dev, + org.zkoss.poi.hssf.eventmodel, + org.zkoss.poi.hssf.eventusermodel, + org.zkoss.poi.hssf.eventusermodel.dummyrecord, + org.zkoss.poi.hssf.extractor, + org.zkoss.poi.hssf.model, + org.zkoss.poi.hssf.record, + org.zkoss.poi.hssf.record.aggregates, + org.zkoss.poi.hssf.record.cf, + org.zkoss.poi.hssf.record.chart, + org.zkoss.poi.hssf.record.common, + org.zkoss.poi.hssf.record.cont, + org.zkoss.poi.hssf.record.crypto, + org.zkoss.poi.hssf.record.pivottable, + org.zkoss.poi.hssf.usermodel, + org.zkoss.poi.hssf.util, + org.zkoss.poi.hwpf, + org.zkoss.poi.hwpf.converter, + org.zkoss.poi.hwpf.dev, + org.zkoss.poi.hwpf.extractor, + org.zkoss.poi.hwpf.model, + org.zkoss.poi.hwpf.model.io, + org.zkoss.poi.hwpf.model.types, + org.zkoss.poi.hwpf.sprm, + org.zkoss.poi.hwpf.usermodel, + org.zkoss.poi.openxml4j.exceptions, + org.zkoss.poi.openxml4j.opc, + org.zkoss.poi.openxml4j.opc.internal, + org.zkoss.poi.openxml4j.opc.internal.marshallers, + org.zkoss.poi.openxml4j.opc.internal.signature, + org.zkoss.poi.openxml4j.opc.internal.unmarshallers, + org.zkoss.poi.openxml4j.opc.signature, + org.zkoss.poi.openxml4j.util, + org.zkoss.poi.poifs.common, + org.zkoss.poi.poifs.crypt, + org.zkoss.poi.poifs.dev, + org.zkoss.poi.poifs.eventfilesystem, + org.zkoss.poi.poifs.filesystem, + org.zkoss.poi.poifs.nio, + org.zkoss.poi.poifs.property, + org.zkoss.poi.poifs.storage, + org.zkoss.poi.sl.usermodel, + org.zkoss.poi.ss, + org.zkoss.poi.ss.extractor, + org.zkoss.poi.ss.format, + org.zkoss.poi.ss.formula, + org.zkoss.poi.ss.formula.atp, + org.zkoss.poi.ss.formula.constant, + org.zkoss.poi.ss.formula.eval, + org.zkoss.poi.ss.formula.eval.forked, + org.zkoss.poi.ss.formula.function, + org.zkoss.poi.ss.formula.functions, + org.zkoss.poi.ss.formula.ptg, + org.zkoss.poi.ss.formula.udf, + org.zkoss.poi.ss.usermodel, + org.zkoss.poi.ss.usermodel.charts, + org.zkoss.poi.ss.util, + org.zkoss.poi.ss.util.cellwalk, + org.zkoss.poi.util, + org.zkoss.poi.xslf, + org.zkoss.poi.xslf.extractor, + org.zkoss.poi.xslf.model, + org.zkoss.poi.xslf.model.geom, + org.zkoss.poi.xslf.usermodel, + org.zkoss.poi.xslf.util, + org.zkoss.poi.xssf.dev, + org.zkoss.poi.xssf.eventusermodel, + org.zkoss.poi.xssf.extractor, + org.zkoss.poi.xssf.model, + org.zkoss.poi.xssf.streaming, + org.zkoss.poi.xssf.usermodel, + org.zkoss.poi.xssf.usermodel.charts, + org.zkoss.poi.xssf.usermodel.extensions, + org.zkoss.poi.xssf.usermodel.helpers, + org.zkoss.poi.xssf.util, + org.zkoss.poi.xwpf.extractor, + org.zkoss.poi.xwpf.model, + org.zkoss.poi.xwpf.usermodel, + web.js.zss, + web.js.zss.css, + web.js.zss.lang, + web.js.zss.mold, + web.zss.img +Require-Bundle: zcommon, + zel, + zhtml, + zk, + zkbind, + zkplus, + zul, + zweb, + zjavassist, + org.apache.commons.fileupload;bundle-version="1.2.2", + org.adempiere.base;bundle-version="8.2.0" +Import-Package: javax.imageio, + javax.servlet;version="3.1.0", + javax.servlet.annotation;version="3.1.0", + javax.servlet.descriptor;version="3.1.0", + javax.servlet.http;version="3.1.0", + org.apache.commons.codec.binary;version="1.13.0", + org.apache.commons.codec.digest;version="1.13.0", + org.apache.xmlbeans, + org.apache.xmlbeans.impl.schema, + org.apache.xmlbeans.impl.values, + org.dom4j;version="2.1.1", + org.dom4j.io;version="2.1.1", + org.osgi.service.component;version="1.4.0", + org.osgi.service.component.annotations;version="1.3.0", + org.slf4j;version="1.7.2", + org.supercsv.io;version="2.4.0", + org.supercsv.prefs;version="2.4.0", + org.w3c.dom +Automatic-Module-Name: org.idempiere.keikai +Bundle-Vendor: iDempiere Community +Service-Component: OSGI-INF/org.idempiere.keikai.view.KeikaiMediaViewProvider.xml +Bundle-ActivationPolicy: lazy +Fragment-Host: org.adempiere.ui.zk;bundle-version="8.2.0" +Jetty-WarPatchFragmentFolderPath: / diff --git a/org.idempiere.keikai/OSGI-INF/org.idempiere.keikai.view.KeikaiMediaViewProvider.xml b/org.idempiere.keikai/OSGI-INF/org.idempiere.keikai.view.KeikaiMediaViewProvider.xml new file mode 100644 index 0000000000..bf5040bf93 --- /dev/null +++ b/org.idempiere.keikai/OSGI-INF/org.idempiere.keikai.view.KeikaiMediaViewProvider.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/org.idempiere.keikai/build.properties b/org.idempiere.keikai/build.properties new file mode 100644 index 0000000000..f0f18240ed --- /dev/null +++ b/org.idempiere.keikai/build.properties @@ -0,0 +1,9 @@ +source.. = src/ +output.. = target/classes/ +bin.includes = META-INF/,\ + .,\ + lib/keikai-oss.jar,\ + lib/keikai-model-oss.jar,\ + lib/zpoi.jar,\ + OSGI-INF/,\ + lib/ooxml-schemas.jar diff --git a/org.idempiere.keikai/pom.xml b/org.idempiere.keikai/pom.xml new file mode 100644 index 0000000000..b03c8ee991 --- /dev/null +++ b/org.idempiere.keikai/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + org.idempiere + org.idempiere.parent + 8.2.0-SNAPSHOT + ../org.idempiere.parent/pom.xml + + org.idempiere.keikai + eclipse-plugin + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + validate + + copy + + + + + io.keikai + keikai-oss + 5.0.0.1 + + + io.keikai + keikai-model-oss + 5.0.0.1 + + + org.zkoss.poi + zpoi + 3.9.16 + + + org.apache.poi + ooxml-schemas + 1.4 + + + lib + true + true + true + + + + + + + \ No newline at end of file diff --git a/org.idempiere.keikai/src/org/idempiere/keikai/view/CSVMediaView.java b/org.idempiere.keikai/src/org/idempiere/keikai/view/CSVMediaView.java new file mode 100644 index 0000000000..782d099394 --- /dev/null +++ b/org.idempiere.keikai/src/org/idempiere/keikai/view/CSVMediaView.java @@ -0,0 +1,121 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.keikai.view; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; + +import org.idempiere.ui.zk.media.IMediaView; +import org.supercsv.io.CsvListReader; +import org.supercsv.io.ICsvListReader; +import org.supercsv.prefs.CsvPreference; +import org.zkoss.poi.xssf.usermodel.XSSFWorkbook; +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.Component; + +import io.keikai.api.Importer; +import io.keikai.api.Importers; +import io.keikai.api.Ranges; +import io.keikai.api.model.Book; +import io.keikai.api.model.Sheet; +import io.keikai.ui.AuxAction; +import io.keikai.ui.Spreadsheet; +import io.keikai.ui.UserActionManager; +import io.keikai.ui.impl.DefaultUserActionManagerCtrl; + +/** + * @author hengsin + * + */ +public class CSVMediaView implements IMediaView { + + public static final CSVMediaView INSTANCE = new CSVMediaView(); + + /** + * default constructor + */ + private CSVMediaView() { + } + + @Override + public Component renderMediaView(Component container, AMedia media, boolean readOnly) { + Spreadsheet spreadsheet = new Spreadsheet(); + if (!readOnly) { + spreadsheet.setShowFormulabar(true); + spreadsheet.setShowContextMenu(true); + } + spreadsheet.setShowToolbar(true); + spreadsheet.setHeight("100%"); + spreadsheet.setWidth("100%"); + container.appendChild(spreadsheet); + + try { + XSSFWorkbook xw = new XSSFWorkbook(); + xw.createSheet(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + xw.write(baos); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + Importer importer = Importers.getImporter(); + Book book = importer.imports(bais, media.getName()); + spreadsheet.setBook(book); + Sheet sheet = book.getSheetAt(0); + ICsvListReader csvListReader = new CsvListReader(media.getReaderData(), CsvPreference.STANDARD_PREFERENCE); + List headers = csvListReader.read(); + if (headers != null) { + for(int i = 0; i < headers.size(); i++) { + Ranges.range(sheet, 0, i).setCellValue(headers.get(i)); + } + } + List line = null; + int row = 0; + while ((line = csvListReader.read()) != null) { + row++; + for(int i = 0; i < line.size(); i++) { + Ranges.range(sheet, row, i).setCellValue(line.get(i) != null ? line.get(i) : ""); + } + } + csvListReader.close(); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + + if (readOnly) { + Book book = spreadsheet.getBook(); + Helper.protectSheet(book.getSheetAt(0)); + } + + Helper.customizeToolbar(container, readOnly); + + UserActionManager actionManager = spreadsheet.getUserActionManager(); + actionManager.registerHandler( + DefaultUserActionManagerCtrl.Category.AUXACTION.getName(), + AuxAction.SAVE_BOOK.getAction(), new SaveBookHandler()); + + return spreadsheet; + } + +} diff --git a/org.idempiere.keikai/src/org/idempiere/keikai/view/ExcelMediaView.java b/org.idempiere.keikai/src/org/idempiere/keikai/view/ExcelMediaView.java new file mode 100644 index 0000000000..096cb072a0 --- /dev/null +++ b/org.idempiere.keikai/src/org/idempiere/keikai/view/ExcelMediaView.java @@ -0,0 +1,89 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.keikai.view; + +import java.io.IOException; + +import org.idempiere.ui.zk.media.IMediaView; +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.Component; + +import io.keikai.api.Importer; +import io.keikai.api.Importers; +import io.keikai.api.model.Book; +import io.keikai.ui.AuxAction; +import io.keikai.ui.Spreadsheet; +import io.keikai.ui.UserActionManager; +import io.keikai.ui.impl.DefaultUserActionManagerCtrl; + +/** + * @author hengsin + * + */ +public class ExcelMediaView implements IMediaView { + + public final static ExcelMediaView INSTANCE = new ExcelMediaView(); + + /** + * + */ + private ExcelMediaView() { + } + + @Override + public Component renderMediaView(Component container, AMedia media, boolean readOnly) { + Spreadsheet spreadsheet = new Spreadsheet(); + if (!readOnly) { + spreadsheet.setShowFormulabar(true); + spreadsheet.setShowContextMenu(true); + } + spreadsheet.setShowToolbar(true); + spreadsheet.setHeight("100%"); + spreadsheet.setWidth("100%"); + container.appendChild(spreadsheet); + + Importer importer = Importers.getImporter(); + Book book; + try { + book = importer.imports(media.getStreamData(), media.getName()); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + spreadsheet.setBook(book); + if (readOnly) { + Helper.protectSheet(book.getSheetAt(0)); + } + + Helper.customizeToolbar(container, readOnly); + + UserActionManager actionManager = spreadsheet.getUserActionManager(); + actionManager.registerHandler( + DefaultUserActionManagerCtrl.Category.AUXACTION.getName(), + AuxAction.SAVE_BOOK.getAction(), new SaveBookHandler()); + + return spreadsheet; + } + +} diff --git a/org.idempiere.keikai/src/org/idempiere/keikai/view/Helper.java b/org.idempiere.keikai/src/org/idempiere/keikai/view/Helper.java new file mode 100644 index 0000000000..e060363267 --- /dev/null +++ b/org.idempiere.keikai/src/org/idempiere/keikai/view/Helper.java @@ -0,0 +1,88 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.keikai.view; + +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.util.Clients; + +import io.keikai.api.Ranges; +import io.keikai.api.model.Sheet; + +/** + * + * @author hengsin + * + */ +public final class Helper { + + private Helper() { + } + + /** + * + * @param sheet + */ + public static void protectSheet(Sheet sheet) { + /** + * String password, boolean allowSelectingLockedCells, boolean + * allowSelectingUnlockedCells, boolean allowFormattingCells, boolean + * allowFormattingColumns, boolean allowFormattingRows, boolean + * allowInsertColumns, boolean allowInsertRows, boolean + * allowInsertingHyperlinks, boolean allowDeletingColumns, boolean + * allowDeletingRows, boolean allowSorting, boolean allowFiltering, boolean + * allowUsingPivotTables, boolean drawingObjects, boolean scenarios); + **/ + Ranges.range(sheet).protectSheet(null, true, true, true, true, true, false, false, false, false, false, true, + true, false, false, false); + } + + /** + * + * @param container + * @param readOnly + */ + public static void customizeToolbar(Component container, boolean readOnly) { + // hide toolbar items that's not applicable or only available for ee + String uuid = "#" + container.getUuid(); + StringBuilder script = new StringBuilder(); + script.append("var wgt=zk('").append(uuid).append(" .zstbtn-insertPicture').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-insertChart').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-exportPDF').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-newBook').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-hyperlink').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zschktbtn-gridlines + a').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zschktbtn-protectSheet').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-mergeAndCenter').$();if(wgt) wgt.setVisible(false);"); + if (readOnly) { + script.append("wgt=zk('").append(uuid).append(" .zstbtn-cut').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-paste').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-clear').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-insert').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-del').$();if(wgt) wgt.setVisible(false);"); + script.append("wgt=zk('").append(uuid).append(" .zstbtn-del + a').$();if(wgt) wgt.setVisible(false);"); + } + Clients.evalJavaScript(script.toString()); + } +} diff --git a/org.idempiere.keikai/src/org/idempiere/keikai/view/KeikaiMediaViewProvider.java b/org.idempiere.keikai/src/org/idempiere/keikai/view/KeikaiMediaViewProvider.java new file mode 100644 index 0000000000..b9900b1545 --- /dev/null +++ b/org.idempiere.keikai/src/org/idempiere/keikai/view/KeikaiMediaViewProvider.java @@ -0,0 +1,62 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.keikai.view; + +import org.idempiere.ui.zk.media.IMediaView; +import org.idempiere.ui.zk.media.IMediaViewProvider; +import org.idempiere.ui.zk.media.Medias; +import org.osgi.service.component.annotations.Component; + +/** + * @author hengsin + * + */ +@Component(name = "org.idempiere.keikai.view.KeikaiMediaViewProvider", immediate = true, service = IMediaViewProvider.class) +public class KeikaiMediaViewProvider implements IMediaViewProvider { + + /** + * default constructor + */ + public KeikaiMediaViewProvider() { + } + + @Override + public IMediaView getMediaView(String contentType, String extension, boolean mobile) { + //keikai ose doesn't support mobile devices + if (mobile) + return null; + + if (Medias.CSV_MIME_TYPE.equals(contentType) && Medias.CSV_FILE_EXT.equals(extension)) { + return CSVMediaView.INSTANCE; + } else if (Medias.EXCEL_MIME_TYPE.equals(contentType) && Medias.EXCEL_FILE_EXT.equals(extension)) { + return ExcelMediaView.INSTANCE; + } else if (Medias.EXCEL_XML_MIME_TYPE.equals(contentType) && Medias.EXCEL_XML_FILE_EXT.equals(extension)) { + return ExcelMediaView.INSTANCE; + } + + return null; + } + +} diff --git a/org.idempiere.keikai/src/org/idempiere/keikai/view/SaveBookHandler.java b/org.idempiere.keikai/src/org/idempiere/keikai/view/SaveBookHandler.java new file mode 100644 index 0000000000..8701624485 --- /dev/null +++ b/org.idempiere.keikai/src/org/idempiere/keikai/view/SaveBookHandler.java @@ -0,0 +1,112 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * 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., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.keikai.view; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +import org.idempiere.ui.zk.media.Medias; +import org.zkoss.util.media.AMedia; +import org.zkoss.zul.Filedownload; + +import io.keikai.api.Exporter; +import io.keikai.api.Exporters; +import io.keikai.api.Ranges; +import io.keikai.api.model.Book; +import io.keikai.api.model.Sheet; +import io.keikai.ui.UserActionContext; +import io.keikai.ui.UserActionHandler; + +/** + * @author hengsin + * + */ +public class SaveBookHandler implements UserActionHandler { + + /** + * default constructor + */ + public SaveBookHandler() { + } + + @Override + public boolean isEnabled(Book book, Sheet sheet) { + return book != null && sheet != null; + } + + @Override + public boolean process(UserActionContext context) { + Book book = context.getBook(); + String bookName = book.getBookName(); + if (bookName.endsWith(".csv")) { + bookName = bookName.substring(0, bookName.length()-4) + ".xlsx"; + } + + //don't export as protected/readonly + boolean isProtected = book.getSheetAt(0).isProtected(); + if (isProtected) + Ranges.range(book.getSheetAt(0)).unprotectSheet(null); + + Exporter exporter = bookName.endsWith(".xls") ? Exporters.getExporter("xls") : Exporters.getExporter("xlsx"); + File file = null; + try { + file = File.createTempFile(Long.toString(System.currentTimeMillis()),"temp"); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + FileOutputStream fos = null; + try { + fos = new FileOutputStream(file); + exporter.export(book, fos); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } finally{ + if(fos!=null){ + try { + fos.close(); + } catch (IOException e) { + } + } + } + + String contentType = bookName.endsWith(".xls") ? Medias.EXCEL_MIME_TYPE : Medias.EXCEL_XML_MIME_TYPE; + String extension = bookName.endsWith(".xls") ? Medias.EXCEL_FILE_EXT : Medias.EXCEL_XML_FILE_EXT; + try { + Filedownload.save(new AMedia(bookName, contentType, extension, file, true)); + } catch (FileNotFoundException e) { + throw new RuntimeException(e.getMessage(), e); + } + + //restore protection + if (isProtected) { + Helper.protectSheet(book.getSheetAt(0)); + } + + return true; + } + +} diff --git a/org.idempiere.zk.extra/META-INF/MANIFEST.MF b/org.idempiere.zk.extra/META-INF/MANIFEST.MF index 0df105fabc..65797c6015 100644 --- a/org.idempiere.zk.extra/META-INF/MANIFEST.MF +++ b/org.idempiere.zk.extra/META-INF/MANIFEST.MF @@ -13,20 +13,7 @@ Bundle-ClassPath: ., lib/timelinez.jar, lib/timeplotz.jar, lib/iceblue_c.jar -Export-Package: com.google.common.annotations, - com.google.common.base, - com.google.common.cache, - com.google.common.collect, - com.google.common.escape, - com.google.common.graph, - com.google.common.hash, - com.google.common.io, - com.google.common.math, - com.google.common.net, - com.google.common.primitives, - com.google.common.reflect, - com.google.common.util.concurrent, - com.google.debugging.sourcemap, +Export-Package: com.google.debugging.sourcemap, com.google.debugging.sourcemap.proto, com.google.errorprone.annotations, com.google.errorprone.annotations.concurrent, diff --git a/pom.xml b/pom.xml index 6848f9d2d7..36a3df8212 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,7 @@ org.idempiere.webservices org.idempiere.webservices-feature org.idempiere.zk.extra + org.idempiere.keikai org.adempiere.report.jasper-feature org.adempiere.base-feature org.adempiere.replication-feature