Podpora tisku. Implementace tisku dynamických sestav.

multitenant
Josef Rokos 11 years ago
parent 34c4144f46
commit 25a4d2dfb7

@ -3,6 +3,9 @@ package info.bukova.isspst;
import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Permission;
import info.bukova.isspst.data.Role; import info.bukova.isspst.data.Role;
import info.bukova.isspst.data.User; import info.bukova.isspst.data.User;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportMapping;
import info.bukova.isspst.reporting.ReportType;
import info.bukova.isspst.services.users.PermissionService; import info.bukova.isspst.services.users.PermissionService;
import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.RoleService;
import info.bukova.isspst.services.users.UserService; import info.bukova.isspst.services.users.UserService;
@ -16,7 +19,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.support.WebApplicationContextUtils;
public class DbInitListener implements ServletContextListener { public class AppInitListener implements ServletContextListener {
private RoleService roleService; private RoleService roleService;
private UserService userService; private UserService userService;
@ -29,7 +32,7 @@ public class DbInitListener implements ServletContextListener {
@Override @Override
public void contextInitialized(ServletContextEvent evt) { public void contextInitialized(ServletContextEvent evt) {
Logger logger = LoggerFactory.getLogger(DbInitListener.class); Logger logger = LoggerFactory.getLogger(AppInitListener.class);
logger.info("Initializing database"); logger.info("Initializing database");
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(evt.getServletContext()); WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(evt.getServletContext());
@ -42,6 +45,8 @@ public class DbInitListener implements ServletContextListener {
checkUsers(); checkUsers();
checkPermissions(); checkPermissions();
userService.removeAccess(); userService.removeAccess();
loadModuleReports();
} }
private void checkRoles() { private void checkRoles() {
@ -92,4 +97,18 @@ public class DbInitListener implements ServletContextListener {
} }
} }
private void loadModuleReports() {
for (Module m : Constants.MODULES) {
Report rep = new Report();
rep.setType(ReportType.DYNAMIC);
rep.setName(Constants.DYNAMIC_REPORT_NAME);
m.addReport(rep);
for (ReportMapping r : Constants.REPORTS) {
if (m.getId().equals(r.getModule())) {
m.addReport(r.getReport());
}
}
}
}
} }

@ -2,6 +2,8 @@ package info.bukova.isspst;
import info.bukova.isspst.data.Permission; import info.bukova.isspst.data.Permission;
import info.bukova.isspst.data.Role; import info.bukova.isspst.data.Role;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportMapping;
import info.bukova.isspst.services.addressbook.AdbService; import info.bukova.isspst.services.addressbook.AdbService;
import info.bukova.isspst.services.buildings.BuildingService; import info.bukova.isspst.services.buildings.BuildingService;
import info.bukova.isspst.services.users.RoleService; import info.bukova.isspst.services.users.RoleService;
@ -53,4 +55,9 @@ public class Constants {
new Module(MOD_ADDRESSBOOK, "Dodavatelé", AdbService.class), new Module(MOD_ADDRESSBOOK, "Dodavatelé", AdbService.class),
new Module(MOD_BUILDINGS, "Budovy", BuildingService.class) new Module(MOD_BUILDINGS, "Budovy", BuildingService.class)
}; };
public final static String DYNAMIC_REPORT_NAME = "Tabulková sestava";
public final static ReportMapping REPORTS[] = {
new ReportMapping(MOD_ADDRESSBOOK, new Report("Pokusná sestava", "report"))
};
} }

@ -1,10 +1,16 @@
package info.bukova.isspst; package info.bukova.isspst;
import info.bukova.isspst.reporting.Report;
import java.util.ArrayList;
import java.util.List;
public class Module { public class Module {
private String id; private String id;
private String name; private String name;
private Class<?> serviceClass; private Class<?> serviceClass;
private List<Report> reports;
public Class<?> getServiceClass() { public Class<?> getServiceClass() {
return serviceClass; return serviceClass;
@ -18,6 +24,7 @@ public class Module {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.serviceClass = serviceClass; this.serviceClass = serviceClass;
reports = new ArrayList<Report>();
} }
public String getId() { public String getId() {
@ -36,4 +43,12 @@ public class Module {
this.name = name; this.name = name;
} }
public List<Report> getReports() {
return reports;
}
public void addReport(Report report) {
this.reports.add(report);
}
} }

@ -0,0 +1,44 @@
package info.bukova.isspst.reporting;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
public class DefinitionFiller {
@Autowired
ReportDefinition definition;
@SuppressWarnings("unchecked")
private void setData(Object data) {
if (data instanceof List) {
definition.setDataSet((List<Object>)data);
} else {
definition.setSingleObject(data);
}
}
public void fillDefinition(Report report, Object data) {
definition.clear();
definition.setReport(report);
setData(data);
}
public void fillDefinition(Report report, Object data, Map<String, Object> params) {
fillDefinition(report, data);
definition.setParams(params);
}
public void fillDefinition(Report report, Object data, String[] columns) {
fillDefinition(report, data);
definition.setFieldsToPrint(Arrays.asList(columns));
}
public void fillDefinition(Report report, Object data, String[] columns, Map<String, Object> params) {
fillDefinition(report, data, params);
definition.setFieldsToPrint(Arrays.asList(columns));
}
}

@ -0,0 +1,101 @@
package info.bukova.isspst.reporting;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.util.JRProperties;
import org.apache.commons.beanutils.PropertyUtils;
import ar.com.fdvs.dj.core.DynamicJasperHelper;
import ar.com.fdvs.dj.core.layout.ClassicLayoutManager;
import ar.com.fdvs.dj.domain.DynamicReport;
import ar.com.fdvs.dj.domain.builders.ColumnBuilderException;
import ar.com.fdvs.dj.domain.builders.FastReportBuilder;
@SuppressWarnings("deprecation")
public class DynamicGenerator implements Generator {
private ReportDefinition definition;
private static Map<Class<?>,Class<?>> primitiveMap = new HashMap<Class<?>,Class<?>>();
static {
primitiveMap.put(boolean.class, Boolean.class);
primitiveMap.put(byte.class, Byte.class);
primitiveMap.put(char.class, Character.class);
primitiveMap.put(short.class, Short.class);
primitiveMap.put(int.class, Integer.class);
primitiveMap.put(long.class, Long.class);
primitiveMap.put(float.class, Float.class);
primitiveMap.put(double.class, Double.class);
}
public DynamicGenerator(ReportDefinition definition) {
this.definition = definition;
}
@Override
public byte[] generate() {
FastReportBuilder rb = new FastReportBuilder();
DynamicReport dr;
for (String col : definition.getFieldsToPrint()) {
Class<?> clazz = colClass(col);
if (clazz != null) {
try {
rb.addColumn(col, col, clazz, 30, false);
} catch (ColumnBuilderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
rb.setTitle(definition.getReportTitle());
rb.setUseFullPageWidth(true);
dr = rb.build();
JRProperties.setProperty("net.sf.jasperreports.default.pdf.encoding", "Cp1250");
JRDataSource ds = new JRBeanCollectionDataSource(definition.getDataSet());
try {
JasperReport report = DynamicJasperHelper.generateJasperReport(dr, new ClassicLayoutManager(), definition.getParams());
return JasperRunManager.runReportToPdf(report, definition.getParams(), ds);
} catch (JRException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private Class<?> colClass(String col) {
List<Object> data = definition.getDataSet();
if (data != null && data.size() > 0) {
try {
Class<?> clazz = PropertyUtils.getPropertyType(data.get(0), col);
if (clazz.isPrimitive()) {
clazz = primitiveMap.get(clazz);
}
return clazz;
} catch (IllegalAccessException e) {
return null;
} catch (InvocationTargetException e) {
return null;
} catch (NoSuchMethodException e) {
return null;
}
}
return null;
}
}

@ -0,0 +1,7 @@
package info.bukova.isspst.reporting;
public interface Generator {
byte[] generate();
}

@ -0,0 +1,15 @@
package info.bukova.isspst.reporting;
public class GeneratorFactory {
public Generator createGenerator(ReportDefinition definition) {
switch (definition.getReport().getType()) {
case DYNAMIC:
return new DynamicGenerator(definition);
default:
return null;
}
}
}

@ -0,0 +1,44 @@
package info.bukova.isspst.reporting;
public class Report {
private ReportType type;
private String name;
private String jasperFile;
public Report() {
}
public Report(String name, String jasperFile) {
this.type = ReportType.DEFINED;
this.name = name;
this.jasperFile = jasperFile;
}
public ReportType getType() {
return type;
}
public void setType(ReportType type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJasperFile() {
return jasperFile;
}
public void setJasperFile(String jasperFile) {
this.jasperFile = jasperFile;
}
}

@ -0,0 +1,63 @@
package info.bukova.isspst.reporting;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ReportController {
@Autowired
private ReportDefinition reportDefinition;
@Autowired
private GeneratorFactory factory;
@RequestMapping("report.pdf")
public void pdfReport(HttpServletResponse response) {
Generator gen = factory.createGenerator(reportDefinition);
byte[] data = gen.generate();
String contentType = "application/pdf";
ServletOutputStream os = null;
try {
os = response.getOutputStream();
} catch (IOException e1) {
e1.printStackTrace();
return;
}
// if (reportDefinition.getReport() == null || reportDefinition.getDataSet() == null) {
// writeError(os, "Definition is null");
// return;
// }
response.setContentType(contentType);
response.setContentLength(data.length);
try {
os.write(data, 0, data.length);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
// } catch (ReportException e) {
// writeError(os, e);
} finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

@ -0,0 +1,101 @@
package info.bukova.isspst.reporting;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ReportDefinition implements Serializable {
/**
*
*/
private static final long serialVersionUID = 995511957163031085L;
private Report report;
private List<Object> dataSet;
private Map<String, Object> params;
private List<String> fieldsToPrint;
private String reportTitle;
public ReportDefinition() {
params = new HashMap<String, Object>();
fieldsToPrint = new ArrayList<String>();
}
public List<Object> getDataSet() {
return dataSet;
}
public void setDataSet(List<Object> dataSet) {
this.dataSet = dataSet;
}
public void setSingleObject(Object o) {
if (this.dataSet != null) {
dataSet.clear();
} else {
dataSet = new ArrayList<Object>();
}
dataSet.add(o);
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params.clear();
this.params.putAll(params);
}
public void setParam(String key, Object value) {
this.params.put(key, value);
}
public Object getParam(String key) {
return this.params.get(key);
}
public List<String> getFieldsToPrint() {
return fieldsToPrint;
}
public void setFieldsToPrint(List<String> fieldsToPrint) {
this.fieldsToPrint = fieldsToPrint;
}
public Report getReport() {
return report;
}
public void setReport(Report report) {
this.report = report;
}
public Class<?> gatDataClass() {
if (dataSet != null && dataSet.size() > 0) {
return dataSet.get(0).getClass();
}
return null;
}
public void clear() {
report = null;
fieldsToPrint.clear();
dataSet = null;
reportTitle = "";
params.clear();
}
public String getReportTitle() {
return reportTitle;
}
public void setReportTitle(String reportTitle) {
this.reportTitle = reportTitle;
}
}

@ -0,0 +1,29 @@
package info.bukova.isspst.reporting;
public class ReportMapping {
private Report report;
private String module;
public ReportMapping(String module, Report report) {
this.module = module;
this.report = report;
}
public Report getReport() {
return report;
}
public void setReport(Report report) {
this.report = report;
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
}

@ -0,0 +1,8 @@
package info.bukova.isspst.reporting;
public enum ReportType {
DYNAMIC,
DEFINED
}

@ -1,10 +1,14 @@
package info.bukova.isspst.services; package info.bukova.isspst.services;
import static ch.lambdaj.Lambda.filter; import static ch.lambdaj.Lambda.filter;
import info.bukova.isspst.Constants;
import info.bukova.isspst.Module;
import info.bukova.isspst.dao.BaseDao; import info.bukova.isspst.dao.BaseDao;
import info.bukova.isspst.data.DataModel; import info.bukova.isspst.data.DataModel;
import info.bukova.isspst.filters.Filter; import info.bukova.isspst.filters.Filter;
import info.bukova.isspst.reporting.Report;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -127,4 +131,23 @@ public abstract class AbstractService<T extends DataModel> implements Service<T>
return null; return null;
} }
@Override
public Module getModule() {
for (Module m : Constants.MODULES) {
if (Arrays.asList(this.getClass().getInterfaces()).contains(m.getServiceClass())) {
return m;
}
}
return null;
}
public List<Report> getReports() {
if (getModule() != null) {
return getModule().getReports();
} else {
return null;
}
}
} }

@ -1,6 +1,8 @@
package info.bukova.isspst.services; package info.bukova.isspst.services;
import info.bukova.isspst.Module;
import info.bukova.isspst.filters.Filter; import info.bukova.isspst.filters.Filter;
import info.bukova.isspst.reporting.Report;
import java.util.List; import java.util.List;
@ -16,5 +18,7 @@ public interface Service<T> {
public T selectSingle(String query); public T selectSingle(String query);
public T getById(int id); public T getById(int id);
public List<T> filterList(List<T> sourceList, Filter<T> filter); public List<T> filterList(List<T> sourceList, Filter<T> filter);
public Module getModule();
public List<Report> getReports();
} }

@ -0,0 +1,40 @@
package info.bukova.isspst.ui;
import java.util.List;
public class Check<T> {
private T member;
private List<T> list;
private boolean checked;
public Check(List<T> list, T member) {
this.member = member;
this.list = list;
if (list.contains(member)) {
checked = true;
} else {
checked = false;
}
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
if (checked && !list.contains(member)) {
list.add(member);
} else {
list.remove(member);
}
this.checked = checked;
}
public T getMember() {
return member;
}
}

@ -0,0 +1,21 @@
package info.bukova.isspst.ui;
import java.util.ArrayList;
import java.util.List;
public class ListChecks<T> {
private List<Check<T>> checks;
public ListChecks(List<T> destList, List<T> sourceList) {
checks = new ArrayList<Check<T>>();
for (T member : sourceList) {
checks.add(new Check<T>(destList, member));
}
}
public List<Check<T>> getChecks() {
return checks;
}
}

@ -295,6 +295,15 @@ public class ListViewModel<T extends DataModel> {
// fillThread.start(); // fillThread.start();
// } // }
@Command
public void onPrint() {
Map<String, Object> params = new HashMap<String, Object>();
params.put("reports", service.getReports());
params.put("data", dataList);
Window win = (Window) Executions.createComponents("/app/reportDialog.zul", null, params);
win.doModal();
}
private void loadFromDbSync() { private void loadFromDbSync() {
dataList.addAll(service.getAll()); dataList.addAll(service.getAll());
fullList = dataList; fullList = dataList;

@ -0,0 +1,96 @@
package info.bukova.isspst.ui;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import info.bukova.isspst.reporting.Report;
import info.bukova.isspst.reporting.ReportDefinition;
import info.bukova.isspst.reporting.ReportType;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ExecutionArgParam;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import org.zkoss.zul.Window;
public class ReportDialogVM {
private List<Report> reports;
private Report selected;
private List<Object> data;
@WireVariable
private ReportDefinition reportDefinition;
@Init
public void init(@ExecutionArgParam("reports") List<Report> reports,
@ExecutionArgParam("data") List<Object> data) {
this.reports = reports;
this.data = data;
if (data != null && data.size() > 0 && data.get(0).getClass() != reportDefinition.gatDataClass()) {
reportDefinition.clear();
}
}
public List<Report> getReports() {
return this.reports;
}
public ReportDefinition getReportDefinition() {
return reportDefinition;
}
public ListChecks<String> getColumns() {
if (selected == null || selected.getType() != ReportType.DYNAMIC) {
return null;
}
if (data == null || data.size() == 0) {
return null;
}
BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(data.get(0).getClass());
} catch (IntrospectionException e) {
return null;
}
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
List<String> properties = new ArrayList<String>();
for (PropertyDescriptor pd : pds) {
properties.add(pd.getName());
}
ListChecks<String> columns = new ListChecks<String>(reportDefinition.getFieldsToPrint(), properties);
return columns;
}
public Report getSelected() {
return selected;
}
@NotifyChange("columns")
public void setSelected(Report selected) {
this.selected = selected;
}
@Command
public void print(@BindingParam("window") Window window) {
reportDefinition.setDataSet(data);
reportDefinition.setReport(selected);
if (window != null) {
window.detach();
}
Window reportWin = (Window) Executions.createComponents("/app/report.zul", null, null);
reportWin.doModal();
}
}

@ -0,0 +1,12 @@
package info.bukova.isspst.ui;
import org.zkoss.bind.annotation.Init;
public class ReportVM {
@Init
public void init() {
}
}

@ -85,6 +85,15 @@
<bean id="loginFail" class="info.bukova.isspst.security.LoginFailHandler"/> <bean id="loginFail" class="info.bukova.isspst.security.LoginFailHandler"/>
<!-- Reporting -->
<bean id="reportDefinition" class="info.bukova.isspst.reporting.ReportDefinition" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="definitionFiller" class="info.bukova.isspst.reporting.DefinitionFiller"/>
<bean id="genFactory" class="info.bukova.isspst.reporting.GeneratorFactory"/>
<!-- DAO --> <!-- DAO -->
<bean id="userDao" class="info.bukova.isspst.dao.jpa.UserDaoJPA"> <bean id="userDao" class="info.bukova.isspst.dao.jpa.UserDaoJPA">
<property name="sessionFactory" ref="sessionFactory"/> <property name="sessionFactory" ref="sessionFactory"/>

@ -19,7 +19,11 @@
</listener> </listener>
<listener> <listener>
<listener-class>info.bukova.isspst.DbInitListener</listener-class> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>info.bukova.isspst.AppInitListener</listener-class>
</listener> </listener>
<!-- ZK --> <!-- ZK -->
@ -113,7 +117,7 @@
<servlet-mapping> <servlet-mapping>
<servlet-name>appServlet</servlet-name> <servlet-name>appServlet</servlet-name>
<url-pattern>/api/</url-pattern> <url-pattern>/api/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<mime-mapping> <mime-mapping>

@ -22,3 +22,9 @@ ToolbarRecNew=Nový záznam
ToolbarRecEdit=Úprava aktuálního záznamu ToolbarRecEdit=Úprava aktuálního záznamu
ToolbarRecDelete=Odstranit aktuální záznam ToolbarRecDelete=Odstranit aktuální záznam
ToolbarRecFilter=Filtr záznamů ToolbarRecFilter=Filtr záznamů
ReportReport=Sestava
ReportSend=Odeslat
ReportPrint=Tisk
ReportReports=Sestavy
ReportTitle=Nadpis sestavy:

@ -0,0 +1,10 @@
<?page title="${labels.ReportReport}" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="${labels.ReportReport}" border="normal" closable="true" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.ReportVM')">
<toolbar>
<toolbarbutton image="/img/send.png" tooltiptext="${labels.ReportSend}"/>
</toolbar>
<iframe width="800px" height="680px" src="/api/report.pdf"/>
</window>
</zk>

@ -0,0 +1,32 @@
<?page title="${labels.ReportReports}" contentType="text/html;charset=UTF-8"?>
<zk>
<window id="reportDialog" title="${labels.ReportReports}" border="normal" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('info.bukova.isspst.ui.ReportDialogVM')"
closable="true" width="550px">
<hbox>
<listbox model="@load(vm.reports)" width="250px" height="350px" selectedItem="@bind(vm.selected)">
<template name="model">
<listitem>
<listcell><label value="@load(each.name)"/></listcell>
</listitem>
</template>
</listbox>
<groupbox mold="3d" closable="false" width="270px">
<caption label="${labels.ReportOptions}"></caption>
<hbox>
<label value="${labels.ReportTitle}"/> <textbox value="@bind(vm.reportDefinition.reportTitle)"/>
</hbox>
<vbox children="@load(vm.columns.checks)">
<template name="children">
<checkbox label="@load(each.member)" checked="@bind(each.checked)"/>
</template>
</vbox>
</groupbox>
</hbox>
<hbox>
<button label="${labels.ReportPrint}" onClick="@command('print', window=reportDialog)"/> <button label="${labels.ButtonStorno}" onClick="reportDialog.detach()"/>
</hbox>
</window>
</zk>

@ -5,5 +5,6 @@
<toolbarbutton image="/img/edit.png" tooltiptext="Upravit" id="btnEdit" onClick="@command('edit')" disabled="@load(empty vm.dataBean ? 'true' : 'false')"/> <toolbarbutton image="/img/edit.png" tooltiptext="Upravit" id="btnEdit" onClick="@command('edit')" disabled="@load(empty vm.dataBean ? 'true' : 'false')"/>
<toolbarbutton image="/img/delete.png" tooltiptext="Smazat" id="btnDelete" onClick="@command('delete')" disabled="@load(empty vm.dataBean ? 'true' : 'false')"/> <toolbarbutton image="/img/delete.png" tooltiptext="Smazat" id="btnDelete" onClick="@command('delete')" disabled="@load(empty vm.dataBean ? 'true' : 'false')"/>
<toolbarbutton image="/img/funnel.png" tooltiptext="Filtr" id="btnFilter" onClick="@command('filter')" /> <toolbarbutton image="/img/funnel.png" tooltiptext="Filtr" id="btnFilter" onClick="@command('filter')" />
<toolbarbutton image="/img/print.png" tooltiptext="Filtr" id="btnPrint" onClick="@command('onPrint')" />
</toolbar> </toolbar>
</zk> </zk>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Loading…
Cancel
Save