diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java index 650341c9f..d16bfd182 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java @@ -20,6 +20,8 @@ package org.zkoss.ganttz; +import static org.zkoss.ganttz.i18n.I18nHelper._; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -48,6 +50,13 @@ import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.util.Interval; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.Button; +import org.zkoss.zul.Radiogroup; +import org.zkoss.zul.Window; public class FunctionalityExposedForExtensions implements IContext { @@ -373,7 +382,41 @@ public class FunctionalityExposedForExtensions implements IContext { if (!isPrintEnabled()) { throw new UnsupportedOperationException("print is not supported"); } - configuration.print(); + + final Window printProperties = (Window) Executions.createComponents( + "/planner/print_configuration.zul", planner, null); + + Button printButton = new Button(_("Print")); + printButton.addEventListener(Events.ON_CLICK, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + Radiogroup layout = (Radiogroup) printProperties + .getFellow("print_layout"); + HashMap parameters = new HashMap(); + if (layout.getSelectedIndex() == 2) { + parameters.put("extension", ".png"); + } + configuration.print(parameters); + } + }); + printButton.setParent(printProperties); + + Button cancelPrint = new Button(_("Cancel")); + printButton.addEventListener(Events.ON_CLICK, new EventListener() { + @Override + public void onEvent(Event event) throws Exception { + // get Print properties and params + printProperties.setVisible(false); + } + }); + cancelPrint.setParent(printProperties); + + try { + printProperties.doModal(); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java index e6263b3dc..5cf256359 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java @@ -50,10 +50,10 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.Button; import org.zkoss.zul.ListModel; import org.zkoss.zul.Separator; import org.zkoss.zul.SimpleListModel; -import org.zkoss.zul.api.Button; public class Planner extends HtmlMacroComponent { @@ -144,6 +144,7 @@ public class Planner extends HtmlMacroComponent { } public void setZoomLevel(final ZoomLevel zoomLevel) { + if (ganttPanel == null) { return; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java index e087aff2c..e2b232ca3 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; import org.apache.commons.lang.Validate; import org.zkoss.ganttz.data.constraint.Constraint; @@ -44,6 +45,8 @@ public class PlannerConfiguration implements IDisabilityConfiguration { public interface IPrintAction { public void doPrint(); + + public void doPrint(Map parameters); } public interface IReloadChartListener { @@ -310,4 +313,11 @@ public class PlannerConfiguration implements IDisabilityConfiguration { printAction.doPrint(); } + public void print(Map parameters) { + if (!isPrintEnabled()) { + throw new UnsupportedOperationException("print not supported"); + } + printAction.doPrint(parameters); + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java index 9eab207e2..af949ccbc 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java @@ -439,6 +439,12 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel { public void doPrint() { CutyPrint.print(); } + + @Override + public void doPrint(Map parameters) { + CutyPrint.print(parameters); + } + }); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java index e5528741a..f2d6e474f 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java @@ -246,6 +246,12 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel { public void doPrint() { CutyPrint.print(order); } + + @Override + public void doPrint(Map parameters) { + CutyPrint.print(order, parameters); + } + }); } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/print/CutyPrint.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/print/CutyPrint.java index 899be6085..989c89612 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/print/CutyPrint.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/print/CutyPrint.java @@ -27,15 +27,24 @@ public class CutyPrint { private static final String CUTYCAPT_COMMAND = "/usr/bin/CutyCapt "; - // Calculate dynamically width and delay parameters - private static final String CUTYCAPT_PARAMETERS = " --min-width=2500 --delay=1000 "; - - public static void print() { - print("/planner/index.zul", Collections. emptyMap()); + public static void print(Order order) { + print("/planner/index.zul", entryPointForShowingOrder(order), + Collections. emptyMap()); } - public static void print(Order order) { - print("/planner/index.zul", entryPointForShowingOrder(order)); + public static void print(Order order, Map parameters) { + print("/planner/index.zul", entryPointForShowingOrder(order), + parameters); + } + + public static void print() { + print("/planner/index.zul", Collections. emptyMap(), + Collections. emptyMap()); + } + + public static void print(Map parameters) { + print("/planner/index.zul", Collections. emptyMap(), + parameters); } private static Map entryPointForShowingOrder(Order order) { @@ -45,7 +54,8 @@ public class CutyPrint { } public static void print(final String forwardURL, - final Map entryPointsMap) { + final Map entryPointsMap, + Map parameters) { HttpServletRequest request = (HttpServletRequest) Executions .getCurrent().getNativeRequest(); @@ -61,31 +71,53 @@ public class CutyPrint { URLHandler.setupEntryPointsForThisRequest(request, entryPointsMap); // Pending to forward and process additional parameters - // as show labels or resources + // as show labels, resources, zoom or expand all request.getRequestDispatcher(forwardURL).forward( request, response); } }); - String CUTYCAPT_URL = "--url=http://" + request.getLocalName() + ":" - + request.getLocalPort() + url; - String captureString = CUTYCAPT_COMMAND + CUTYCAPT_URL; - - captureString += CUTYCAPT_PARAMETERS; + String extension = ".pdf"; + if (((parameters.get("extension") != null) && !(parameters + .get("extension").equals("")))) { + extension = parameters.get("extension"); + } + // Calculate application path and destination file relative route String absolutePath = request.getSession().getServletContext() .getRealPath("/"); String filename = "/print/" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) - + ".pdf"; - captureString += "--out=" + absolutePath + filename; + + extension; + + // Generate capture string + String captureString = CUTYCAPT_COMMAND; + + // Add capture destination callback URL + captureString += " --url=http://" + request.getLocalName() + ":" + + request.getLocalPort() + url; + + // Static width and time delay parameters (FIX) + captureString += " --min-width=2600 --delay=1000 "; + + // Relative user styles + captureString += "--user-styles=" + absolutePath + + "/planner/css/print.css"; + + // Destination complete absolute path + captureString += " --out=" + absolutePath + filename; try { // CutyCapt command execution - // If there is a not real X server environment, use framebuffer LOG.debug(captureString); Process print; Process server = null; + + // Ensure cleanup of unfinished CutyCapt processes + Process clean = null; + clean = Runtime.getRuntime().exec("killall CutyCapt"); + + // If there is a not real X server environment then use Xvfb if ((System.getenv("DISPLAY") == null) || (System.getenv("DISPLAY").equals(""))) { String[] serverEnvironment = { "PATH=$PATH" }; @@ -104,7 +136,7 @@ public class CutyPrint { server.destroy(); } Executions.getCurrent().sendRedirect(filename, "_blank"); - } catch (InterruptedException e) { + } catch (Exception e) { LOG.error(_("Could open generated PDF"), e); } @@ -113,5 +145,4 @@ public class CutyPrint { } } - } diff --git a/navalplanner-webapp/src/main/webapp/common/css/navalpro_zk.css b/navalplanner-webapp/src/main/webapp/common/css/navalpro_zk.css index 68971d4ca..b6f7a6bdb 100644 --- a/navalplanner-webapp/src/main/webapp/common/css/navalpro_zk.css +++ b/navalplanner-webapp/src/main/webapp/common/css/navalpro_zk.css @@ -20,6 +20,19 @@ margin-left: -90px; } + body .main-area { + margin-left: -90px; + } + + .toolbar-box { + display: none; + height: 0px !important; + } + + .plannerlayout_center { + margin-top: -25px; + } + /* Calculate dynamically */ body { width: 2500px; @@ -77,7 +90,6 @@ width: 300px; } - .plannerlayout #watermark, .plannerlayout #watermark .timetracker_column_even { height: 99999px !important; @@ -1165,7 +1177,7 @@ tr.z-tree-row-seld, tr.z-list-item-seld, min-width: 30px; } - .function { min-width: 90px; } + diff --git a/navalplanner-webapp/src/main/webapp/planner/css/print.css b/navalplanner-webapp/src/main/webapp/planner/css/print.css new file mode 100644 index 000000000..1be13b420 --- /dev/null +++ b/navalplanner-webapp/src/main/webapp/planner/css/print.css @@ -0,0 +1,53 @@ + +/* Print CSS used for CutyCapt capture requests */ + +body { + width: 2600px; +} + +/* ----- Height dependent styles ----- */ +body div.scheduling-graphics { + height: 0px !important; + display: none; +} + +/* Dynamically set heights */ +body div.main-layout { + height: 1800px !important; +} + +body div.plannerlayout { + height: 1790px !important; +} + +body div#timetracker { + height: 1730px !important; +} + +body div#scroll_container { + height: 1710px !important; +} + +/* Hide possible Javascript execution exceptions */ +#zk_err_1 { + display: none; +} + +/* Hide more stuff */ +a.ruta, .toolbar-box { + display: none; +} + +/* Hack for hiding breadcrumbs part in printed diagrams */ +.ruta tr td, +.ruta tr td+td, +.ruta tr td+td+td { + display:none; +} + +.ruta tr td+td+td+td+td+td { + font-size: 18px; + display: inline !important; +} + + diff --git a/navalplanner-webapp/src/main/webapp/planner/print_configuration.zul b/navalplanner-webapp/src/main/webapp/planner/print_configuration.zul new file mode 100644 index 000000000..f7ffb5071 --- /dev/null +++ b/navalplanner-webapp/src/main/webapp/planner/print_configuration.zul @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/navalplanner-webapp/src/main/webapp/print/.gitignore b/navalplanner-webapp/src/main/webapp/print/.gitignore index a13633799..ecf5e8708 100644 --- a/navalplanner-webapp/src/main/webapp/print/.gitignore +++ b/navalplanner-webapp/src/main/webapp/print/.gitignore @@ -1 +1,2 @@ *.pdf +*.png