ItEr42S15SoporteImpresionMultiplesPaxinasItEr41S18: Implemented print behaviour to open generated PDF based on scheduler view

This commit is contained in:
Lorenzo Tilve 2010-01-07 10:16:29 +01:00 committed by Javier Moran Rua
parent 275267eca3
commit 47283d59d8
13 changed files with 167 additions and 48 deletions

18
INSTALL
View file

@ -86,3 +86,21 @@ Check ``<profiles>`` section in the root ``pom.xml`` to see the profile-based
approach used in the project. The default profiles (the one assumed by the above approach used in the project. The default profiles (the one assumed by the above
instructions) are ``dev`` and ``postgresql`` (meaning "use PostgreSQL assuming a instructions) are ``dev`` and ``postgresql`` (meaning "use PostgreSQL assuming a
development environment"). development environment").
Print
-----
Printing system is based on a tool that produces several output formats rendering
the specified URLs with the WebKit engine. To be able to print local diagrams this
tool and a lightweight X server must be installed.
The capturing tool is CutyCapt [1], which has to be either compiled or installed from
an external package. Once compiled from the tarball the binary CutyCapt must be located
under /usr/local/bin/ to be available to the application.
X virtual framebuffer xvfb[2] package needs to be installed for the application running on
a non-desktop server is capable of launching an X instance to create the print capture of
the selected page.
[1] http://cutycapt.sourceforge.net/
[2] http://www.xfree86.org/4.0.1/Xvfb.1.html

View file

@ -22,11 +22,18 @@ package org.zkoss.ganttz;
import static org.zkoss.ganttz.i18n.I18nHelper._; import static org.zkoss.ganttz.i18n.I18nHelper._;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.adapters.IDisabilityConfiguration;
import org.zkoss.ganttz.adapters.PlannerConfiguration; import org.zkoss.ganttz.adapters.PlannerConfiguration;
import org.zkoss.ganttz.data.Dependency; import org.zkoss.ganttz.data.Dependency;
@ -37,7 +44,8 @@ import org.zkoss.ganttz.data.GanttDiagramGraph.IGraphChangeListener;
import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.ICommand;
import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.ICommandOnTask;
import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.extensions.IContext;
import org.zkoss.ganttz.print.Print; import org.zkoss.ganttz.servlets.CallbackServlet;
import org.zkoss.ganttz.servlets.CallbackServlet.IServletRequestHandler;
import org.zkoss.ganttz.timetracker.TimeTracker; import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.TimeTrackerComponent; import org.zkoss.ganttz.timetracker.TimeTrackerComponent;
import org.zkoss.ganttz.timetracker.TimeTrackerComponentWithoutColumns; import org.zkoss.ganttz.timetracker.TimeTrackerComponentWithoutColumns;
@ -58,6 +66,12 @@ import org.zkoss.zul.api.Button;
public class Planner extends HtmlMacroComponent { public class Planner extends HtmlMacroComponent {
// Read path and Xvfb port from properties file
private static final String CUTYCAPT_COMMAND = "/usr/local/bin/CutyCapt ";
// Calculate dynamically width and delay parameters
private static final String CUTYCAPT_PARAMETERS = " --min-width=2500 --delay=1000 ";
public static void registerNeededScripts() { public static void registerNeededScripts() {
IScriptsRegister register = getScriptsRegister(); IScriptsRegister register = getScriptsRegister();
register.register(ScriptsRequiredByPlanner.class); register.register(ScriptsRequiredByPlanner.class);
@ -387,7 +401,68 @@ public class Planner extends HtmlMacroComponent {
} }
public void print() { public void print() {
Print.print(diagramGraph);
// Pending to raise print configuration popup
HttpServletRequest request = (HttpServletRequest) Executions
.getCurrent().getNativeRequest();
String url = CallbackServlet.registerAndCreateURLFor(request,
new IServletRequestHandler() {
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String forwardURL = "/planner/index.zul";
String orderId = request.getParameter("order");
if ((orderId != null) && !(orderId.equals(""))) {
forwardURL += ";order=" + orderId;
}
// Pending to forward and process additional parameters
// as show labels or resources
request.getRequestDispatcher(forwardURL).forward(
request, response);
}
});
String CUTYCAPT_URL = "--url=http://localhost:8080" + url;
String captureString = CUTYCAPT_COMMAND + CUTYCAPT_URL;
captureString += CUTYCAPT_PARAMETERS;
String absolutePath = request.getSession().getServletContext()
.getRealPath("/");
String filename = "/print/"
+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
+ ".pdf";
captureString += "--out=" + absolutePath + filename;
try {
// CutyCapt command execution
// If there is a not real X server environment, use framebuffer
String[] serverEnvironment = { "PATH=$PATH" };
Process server = Runtime.getRuntime().exec("env - Xvfb :99",
serverEnvironment);
String[] environment = { "DISPLAY=:99.0" };
Process p = Runtime.getRuntime().exec(captureString, environment);
System.out.println(captureString);
try {
p.waitFor();
p.destroy();
server.destroy();
Executions.getCurrent().sendRedirect(filename, "_blank");
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View file

@ -110,6 +110,8 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
private boolean criticalPathEnabled = true; private boolean criticalPathEnabled = true;
// private String identifier = null;
private IDetailItemModificator firstLevelModificators = SeveralModificators private IDetailItemModificator firstLevelModificators = SeveralModificators
.empty(); .empty();

View file

@ -46,9 +46,8 @@ planner = self;
<center border="0"> <center border="0">
<borderlayout sclass="plannerlayout_center"> <borderlayout sclass="plannerlayout_center">
<west size="300px" flex="true" collapsible="true" <west flex="true" collapsible="true"
splittable="true" autoscroll="true"> splittable="true" autoscroll="true" sclass="taskheaders-border">
<borderlayout > <borderlayout >
<north border="0" height="32px" flex="true" collapsible="true" sclass="taskheadersgap"> <north border="0" height="32px" flex="true" collapsible="true" sclass="taskheadersgap">
<vbox pack="center" align="center"> <vbox pack="center" align="center">
@ -61,7 +60,7 @@ planner = self;
</tree> </tree>
</vbox> </vbox>
</north> </north>
<center border="0" sclass="leftpanelcontainer" style="overflow-x:scroll"> <center border="0" sclass="leftpanelcontainer">
<div sclass="leftpanelgap" id="insertionPointLeftPanel"></div> <div sclass="leftpanelgap" id="insertionPointLeftPanel"></div>
</center> </center>
</borderlayout> </borderlayout>
@ -78,8 +77,7 @@ planner = self;
</center> </center>
</borderlayout> </borderlayout>
</center> </center>
<south height="200px" collapsible="true" title="Graphics" <south collapsible="true" title="Graphics" sclass="scheduling-graphics">
sclass="scheduling-graphics">
<div id="insertionPointChart" /> <div id="insertionPointChart" />
</south> </south>
</borderlayout> </borderlayout>

View file

@ -28,7 +28,7 @@
${each.name} ${each.name}
</n:th> </n:th>
</n:tr> </n:tr>
<n:tr id="watermark" style="height:442px"> <n:tr id="watermark">
<n:td class="timetracker_column${((each.even and (top.zoomLevel != 'DETAIL_FOUR'))?'_even':'')} <n:td class="timetracker_column${((each.even and (top.zoomLevel != 'DETAIL_FOUR'))?'_even':'')}
${(each.bankHoliday?'bankHoliday':'')} ${(each.bankHoliday?'bankHoliday':'')}
${(each.currentPeriod?'timetracker_column_today':' ')} ${(each.currentPeriod?'timetracker_column_today':' ')}

View file

@ -248,18 +248,25 @@ function adjustScrollableDimensions() {
scroll_container.style["width"] = YAHOO.util.Selector.query('.second_level_')[0].clientWidth +"px"; scroll_container.style["width"] = YAHOO.util.Selector.query('.second_level_')[0].clientWidth +"px";
document.getElementById('timetracker').style["width"] = scroll_container.style["width"];
timetracker.style["height"] =
Math.max((window.innerHeight - TIMETRACKER_OFFSET_TOP + 26 ),
document.getElementById('listdetails_container').scrollHeight + 12 )
+"px";
timetracker.style["height"] = (window.innerHeight - TIMETRACKER_OFFSET_TOP + 5)
+ "px"; // Extra padding
scroll_container.style["height"] = (window.innerHeight scroll_container.style["height"] = (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH * 2)) - TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH * 2))
+ "px"; + "px";
// Watermark heigh also needs recalculations due to the recreation /* Watermark heigh also needs recalculations due to the recreation
document.getElementById('watermark').style["height"] = (window.innerHeight document.getElementById('watermark').style["height"] = (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH)) - TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH))
+ "px"; + "px";
// Pbs with document.getElementById('watermark').firstChild
YAHOO.util.Selector.query('.timetracker_column_even')[0].style["height"]= (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH))
+ "px"; */
// Inner divs need recalculation to adjust to new scroll displacement lenght // Inner divs need recalculation to adjust to new scroll displacement lenght
document.getElementById('ganttpanel_inner_scroller_y').style["height"] = document document.getElementById('ganttpanel_inner_scroller_y').style["height"] = document

View file

@ -19,6 +19,7 @@
*/ */
package org.navalplanner.web.planner.tabs; package org.navalplanner.web.planner.tabs;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.common.entrypoints.EntryPoint; import org.navalplanner.web.common.entrypoints.EntryPoint;
import org.navalplanner.web.common.entrypoints.EntryPoints; import org.navalplanner.web.common.entrypoints.EntryPoints;
@ -38,4 +39,7 @@ public interface IGlobalViewEntryPoints {
@EntryPoint("orders_list") @EntryPoint("orders_list")
public void goToOrdersList(); public void goToOrdersList();
@EntryPoint("order")
public void goToOrder(Order order);
} }

View file

@ -272,4 +272,10 @@ public class MultipleTabsPlannerController implements Composer,
getTabsRegistry().show(ordersTab); getTabsRegistry().show(ordersTab);
} }
@Override
public void goToOrder(Order order) {
mode.goToOrderMode(order);
getTabsRegistry().show(planningTab);
}
} }

View file

@ -17,6 +17,8 @@
<!-- Web application --> <!-- Web application -->
<intercept-url pattern="/common/img/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/common/img/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/common/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/planner/css/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/callback/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/zkau/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/zkau/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/common/layout/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <intercept-url pattern="/common/layout/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="ROLE_BASIC_USER" /> <intercept-url pattern="/**" access="ROLE_BASIC_USER" />

View file

@ -20,41 +20,51 @@
margin-left: -90px; margin-left: -90px;
} }
/* Calculate dynamically */
body {
width: 2500px;
}
body .z-border-layout { body .z-border-layout {
background-color: #FFFFFF; background-color: #FFFFFF;
} }
body .leftpanelcontainer, .rightpanellayout .z-center-body { .plannerlayout .leftpanelcontainer,
.plannerlayout .rightpanellayout .z-center-body {
overflow: hidden !important; overflow: hidden !important;
overflow-x: hidden !important;
overflow-y: hidden !important;
} }
/* Height dependent styles */ body {
width: 2500px;
}
/* ----- Height dependent styles ----- */
body div.scheduling-graphics { body div.scheduling-graphics {
height:0px !important; height:0px !important;
display: none; display: none;
} }
/* Dynamically set heights */
body div.main-layout { body div.main-layout {
height: 12800px !important; height: 1800px !important;
} }
body div.plannerlayout { body div.plannerlayout {
height: 12790px !important; height: 1790px !important;
} }
body div#timetracker, body div#timetracker {
#watermark .timetracker_column_even { height: 1730px !important;
height: 12730px !important;
} }
body div#scroll_container { body div#scroll_container {
height: 12710px !important; height: 1710px !important;
} }
} } /* --- End print media ----*/
/* ----- Predefined Height dependent styles ----- */
.scheduling-graphics { .scheduling-graphics {
height:200px; height:200px;
} }
@ -63,31 +73,23 @@
height: 560px; height: 560px;
} }
#watermark {
height: 442px;
}
#watermark {
height: 12780px !important;
}
#timetracker, #watermark, #watermark .timetracker_column_even {
height: 99999px !important;
}
#timetracker {
overflow: hidden;
}
.taskheaders-border { .taskheaders-border {
width: 300px; width: 300px;
} }
.leftpanelcontainer {
overflow-x: scroll; .plannerlayout #watermark,
} .plannerlayout #watermark .timetracker_column_even {
height: 99999px !important;
}
.plannerlayout .taskspanelgap #timetracker {
overflow-y: hidden;
}
.leftpanelcontainer {
overflow-x: scroll;
}
body { body {
font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif;
@ -101,6 +103,7 @@ body {
float: left; float: left;
clear: both; clear: both;
position: absolute; position: absolute;
border: 0;
} }
.headings { .headings {

View file

@ -54,7 +54,7 @@
</n:table> </n:table>
</n:div> </n:div>
<borderlayout class="main-layout" height="560px" width="auto"> <borderlayout class="main-layout" width="auto">
<!-- borderlayout class="main-layout" height="2000px" width="2000px"--> <!-- borderlayout class="main-layout" height="2000px" width="2000px"-->
<west class="perspectives-column" width="90px"> <west class="perspectives-column" width="90px">
<n:div> <n:div>

View file

@ -248,7 +248,7 @@ min-width:200px;
} }
#ganttpanel table td { #ganttpanel table td {
padding: 0; /* padding: 0; */
} }
/* -------------- Timetracker -------------- */ /* -------------- Timetracker -------------- */
@ -271,7 +271,8 @@ min-width:200px;
/* Watermark alternate row color */ /* Watermark alternate row color */
#watermark .timetracker_column_even { #watermark .timetracker_column_even {
background-color: #EEEEEE; background-color: #EEEEEE !important;
height: 458px;
} }
#watermark .timetracker_column_today.timetracker_column_deadline, #watermark .timetracker_column_today.timetracker_column_deadline,
@ -698,9 +699,11 @@ div.z-tree {
.listdetails { .listdetails {
position:relative; position:relative;
top:-18px;
} }
#listdetails_container {
top:-18px;
}
.listdetails .z-tree-header { .listdetails .z-tree-header {
margin-bottom:17px; margin-bottom:17px;

View file

@ -0,0 +1 @@
*.pdf