From c56faea785e88bf03fb2427feb3b2a4b977e9cdd Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Wed, 6 Feb 2013 22:25:43 +0000 Subject: [PATCH] Initial import. git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/reports@68941 82a268e6-3cf1-43bd-a215-b396298e98cf --- .classpath | 36 + .project | 59 + .settings/.jsdtscope | 15 + .../com.google.appengine.eclipse.core.prefs | 3 + .settings/com.google.gdt.eclipse.core.prefs | 6 + .settings/com.google.gwt.eclipse.core.prefs | 5 + .settings/org.eclipse.core.resources.prefs | 7 + .settings/org.eclipse.jdt.core.prefs | 9 + .settings/org.eclipse.m2e.core.prefs | 5 + .settings/org.eclipse.wst.common.component | 14 + ....eclipse.wst.common.project.facet.core.xml | 7 + ...rg.eclipse.wst.jsdt.ui.superType.container | 1 + .settings/org.maven.ide.eclipse.prefs | 9 + ReportGeneratorTest-dev.launch | 22 + ReportGeneratorTest-prod.launch | 22 + distro/INSTALL | 8 + distro/LICENSE | 6 + distro/MAINTAINERS | 5 + distro/README | 55 + distro/changelog.xml | 7 + distro/descriptor.xml | 48 + distro/profile.xml | 25 + distro/svnpath.txt | 1 + pom.xml | 309 + .../reportgenerator/client/Headerbar.java | 695 ++ .../client/Presenter/CommonCommands.java | 225 + .../client/Presenter/Presenter.java | 1168 +++ .../client/ReportConstants.java | 32 + .../client/ReportGenerator.java | 403 + .../reportgenerator/client/ReportService.java | 91 + .../client/ReportServiceAsync.java | 87 + .../user/reportgenerator/client/TitleBar.java | 202 + .../reportgenerator/client/ToolboxPanel.java | 53 + .../client/WorkspacePanel.java | 160 + .../client/components/FancyFileUpload.java | 492 ++ .../client/dialog/AddBiblioEntryDialog.java | 70 + .../client/dialog/CommentDialog.java | 86 + .../client/dialog/DeleteCitationsDialog.java | 92 + .../client/dialog/FimesReportTreePanel.java | 195 + .../client/dialog/ImageUploaderDialog.java | 210 + .../client/dialog/ImporterDialog.java | 180 + .../client/dialog/LoadingPopup.java | 45 + .../client/dialog/PagePropertiesDialog.java | 110 + .../client/dialog/TSHeader.java | 112 + .../client/dialog/TimeSeriesDialog.java | 81 + .../client/dialog/TimeSeriesFilter.java | 217 + .../client/dialog/TimeSeriesSampleDialog.java | 75 + .../client/events/AddBiblioEvent.java | 32 + .../client/events/AddBiblioEventHandler.java | 7 + .../client/events/AddCommentEvent.java | 43 + .../client/events/AddCommentEventHandler.java | 7 + .../client/events/ItemSelectionEvent.java | 34 + .../events/ItemSelectionEventHandler.java | 8 + .../client/events/RemovedCitationEvent.java | 26 + .../events/RemovedCitationEventHandler.java | 7 + .../events/RemovedUserCommentEvent.java | 30 + .../RemovedUserCommentEventHandler.java | 7 + .../client/model/ExportManifestationType.java | 31 + .../client/model/TemplateComponent.java | 534 ++ .../client/model/TemplateModel.java | 697 ++ .../client/model/TemplateSection.java | 254 + .../FimesReportTreeStructureResources.java | 45 + .../client/resources/comments.png | Bin 0 -> 557 bytes .../client/resources/image.png | Bin 0 -> 516 bytes .../client/resources/information.png | Bin 0 -> 778 bytes .../reportgenerator/client/resources/page.png | Bin 0 -> 635 bytes .../client/resources/report.png | Bin 0 -> 649 bytes .../client/resources/table.png | Bin 0 -> 566 bytes .../client/resources/text_dropcaps.png | Bin 0 -> 314 bytes .../client/resources/text_heading_1.png | Bin 0 -> 276 bytes .../client/resources/text_heading_2.png | Bin 0 -> 304 bytes .../client/resources/text_heading_3.png | Bin 0 -> 306 bytes .../client/resources/text_heading_4.png | Bin 0 -> 293 bytes .../client/targets/AttributeArea.java | 142 + .../client/targets/BasicTextArea.java | 111 + .../client/targets/Coords.java | 26 + .../client/targets/D4sRichTextarea.java | 227 + .../client/targets/DoubleColumnPanel.java | 42 + .../client/targets/DropImageListener.java | 122 + .../client/targets/DropTSListener.java | 115 + .../client/targets/DroppingArea.java | 214 + .../client/targets/GenTableCell.java | 158 + .../client/targets/GenericTable.java | 145 + .../client/targets/ImageArea.java | 158 + .../client/targets/ReportTextArea.java | 260 + .../client/targets/TSArea.java | 314 + .../client/toursteps/Intro.java | 26 + .../client/toursteps/Intro.ui.xml | 31 + .../portlet/ReportGeneratorPortlet.java | 44 + .../server/servlet/DocLibraryUtil.java | 311 + .../server/servlet/ImagesUploadServlet.java | 181 + .../server/servlet/ReportServiceImpl.java | 1751 ++++ .../server/servlet/ZipUtil.java | 130 + .../servlet/loggers/CreateReportLogEntry.java | 26 + .../loggers/GenerateReportLogEntry.java | 28 + .../servlet/loggers/OpenReportLogEntry.java | 27 + .../servlet/loggers/OpenWorkflowLogEntry.java | 28 + .../servlet/loggers/SaveWorkflowLogEntry.java | 28 + .../reportgenerator/shared/SessionInfo.java | 57 + .../reportgenerator/ReportGenerator.gwt.xml | 25 + src/main/webapp/ReportGenerator.css | 595 ++ src/main/webapp/ReportGenerator.html | 29 + .../jsp/ReportGeneratorPortlet_edit.jsp | 13 + .../jsp/ReportGeneratorPortlet_help.jsp | 13 + .../jsp/ReportGeneratorPortlet_view.jsp | 12 + src/main/webapp/WEB-INF/liferay-display.xml | 8 + .../WEB-INF/liferay-plugin-package.properties | 9 + src/main/webapp/WEB-INF/liferay-portlet.xml | 28 + src/main/webapp/WEB-INF/portlet.xml | 25 + src/main/webapp/WEB-INF/web.xml | 134 + src/main/webapp/gxt/css/gxt-all.css | 7451 +++++++++++++++++ src/main/webapp/gxt/css/gxt-gray.css | 493 ++ src/main/webapp/gxt/desktop/css/desktop.css | 638 ++ .../webapp/gxt/desktop/images/desktop.gif | Bin 0 -> 63601 bytes .../webapp/gxt/desktop/images/desktop3.jpg | Bin 0 -> 158508 bytes src/main/webapp/gxt/desktop/images/gears.gif | Bin 0 -> 996 bytes src/main/webapp/gxt/desktop/images/gears.png | Bin 0 -> 967 bytes src/main/webapp/gxt/desktop/images/grid.png | Bin 0 -> 513 bytes src/main/webapp/gxt/desktop/images/hatch.gif | Bin 0 -> 842 bytes src/main/webapp/gxt/desktop/images/hd-bg.gif | Bin 0 -> 992 bytes .../webapp/gxt/desktop/images/hd-tb-bg.gif | Bin 0 -> 808 bytes .../gxt/desktop/images/icon_padlock.png | Bin 0 -> 400 bytes .../webapp/gxt/desktop/images/icons-bg.png | Bin 0 -> 191 bytes .../webapp/gxt/desktop/images/launcher-bg.gif | Bin 0 -> 944 bytes .../gxt/desktop/images/launcher-btn.gif | Bin 0 -> 1247 bytes src/main/webapp/gxt/desktop/images/logout.gif | Bin 0 -> 920 bytes src/main/webapp/gxt/desktop/images/logout.png | Bin 0 -> 505 bytes src/main/webapp/gxt/desktop/images/member.gif | Bin 0 -> 972 bytes src/main/webapp/gxt/desktop/images/member.png | Bin 0 -> 832 bytes .../webapp/gxt/desktop/images/powered.gif | Bin 0 -> 2291 bytes .../webapp/gxt/desktop/images/powered.png | Bin 0 -> 3606 bytes src/main/webapp/gxt/desktop/images/s.gif | Bin 0 -> 43 bytes .../images/taskbar/black/item-over.gif | Bin 0 -> 166 bytes .../images/taskbar/black/scroll-left.gif | Bin 0 -> 1405 bytes .../images/taskbar/black/scroll-right.gif | Bin 0 -> 1405 bytes .../taskbar/black/start-menu-left-corners.png | Bin 0 -> 206 bytes .../taskbar/black/start-menu-left-right.png | Bin 0 -> 143 bytes .../black/start-menu-right-corners.png | Bin 0 -> 224 bytes .../images/taskbar/black/start-menu-right.png | Bin 0 -> 141 bytes .../taskbar/black/start-menu-top-bottom.png | Bin 0 -> 158 bytes .../images/taskbar/black/startbutton-icon.gif | Bin 0 -> 748 bytes .../images/taskbar/black/startbutton.gif | Bin 0 -> 2419 bytes .../images/taskbar/black/taskbar-split-h.gif | Bin 0 -> 327 bytes .../taskbar/black/taskbar-start-panel-bg.gif | Bin 0 -> 890 bytes .../images/taskbar/black/taskbutton.gif | Bin 0 -> 1894 bytes .../taskbar/black/taskbuttons-panel-bg.gif | Bin 0 -> 195 bytes .../webapp/gxt/desktop/images/winbar-bg.gif | Bin 0 -> 888 bytes .../webapp/gxt/desktop/images/winbar-btn.gif | Bin 0 -> 1316 bytes .../webapp/gxt/desktop/images/windows-bg.gif | Bin 0 -> 830 bytes .../webapp/gxt/desktop/wallpapers/desktop.jpg | Bin 0 -> 84237 bytes src/main/webapp/gxt/flash/swfobject.js | 5 + .../gxt/images/default/box/corners-blue.gif | Bin 0 -> 1010 bytes .../webapp/gxt/images/default/box/corners.gif | Bin 0 -> 1005 bytes .../webapp/gxt/images/default/box/l-blue.gif | Bin 0 -> 810 bytes src/main/webapp/gxt/images/default/box/l.gif | Bin 0 -> 810 bytes .../webapp/gxt/images/default/box/r-blue.gif | Bin 0 -> 810 bytes src/main/webapp/gxt/images/default/box/r.gif | Bin 0 -> 810 bytes .../webapp/gxt/images/default/box/tb-blue.gif | Bin 0 -> 851 bytes src/main/webapp/gxt/images/default/box/tb.gif | Bin 0 -> 839 bytes .../gxt/images/default/button/arrow.gif | Bin 0 -> 828 bytes .../gxt/images/default/button/btn-arrow.gif | Bin 0 -> 870 bytes .../gxt/images/default/button/btn-sprite.gif | Bin 0 -> 1341 bytes .../webapp/gxt/images/default/button/btn.gif | Bin 0 -> 4298 bytes .../gxt/images/default/button/group-cs.gif | Bin 0 -> 2459 bytes .../gxt/images/default/button/group-lr.gif | Bin 0 -> 861 bytes .../gxt/images/default/button/group-tb.gif | Bin 0 -> 846 bytes .../default/button/s-arrow-b-noline.gif | Bin 0 -> 898 bytes .../gxt/images/default/button/s-arrow-b.gif | Bin 0 -> 937 bytes .../gxt/images/default/button/s-arrow-bo.gif | Bin 0 -> 955 bytes .../images/default/button/s-arrow-noline.gif | Bin 0 -> 863 bytes .../gxt/images/default/button/s-arrow-o.gif | Bin 0 -> 937 bytes .../gxt/images/default/button/s-arrow.gif | Bin 0 -> 937 bytes .../webapp/gxt/images/default/dd/drop-add.gif | Bin 0 -> 1001 bytes .../webapp/gxt/images/default/dd/drop-no.gif | Bin 0 -> 949 bytes .../webapp/gxt/images/default/dd/drop-yes.gif | Bin 0 -> 1016 bytes .../gxt/images/default/editor/tb-bold.gif | Bin 0 -> 892 bytes .../images/default/editor/tb-font-color.gif | Bin 0 -> 905 bytes .../default/editor/tb-font-decrease.gif | Bin 0 -> 879 bytes .../default/editor/tb-font-highlight.gif | Bin 0 -> 941 bytes .../default/editor/tb-font-increase.gif | Bin 0 -> 906 bytes .../gxt/images/default/editor/tb-italic.gif | Bin 0 -> 862 bytes .../default/editor/tb-justify-center.gif | Bin 0 -> 848 bytes .../images/default/editor/tb-justify-left.gif | Bin 0 -> 848 bytes .../default/editor/tb-justify-right.gif | Bin 0 -> 848 bytes .../gxt/images/default/editor/tb-link.gif | Bin 0 -> 1060 bytes .../gxt/images/default/editor/tb-ol.gif | Bin 0 -> 877 bytes .../gxt/images/default/editor/tb-source.gif | Bin 0 -> 952 bytes .../gxt/images/default/editor/tb-sprite.gif | Bin 0 -> 2072 bytes .../gxt/images/default/editor/tb-ul.gif | Bin 0 -> 871 bytes .../images/default/editor/tb-underline.gif | Bin 0 -> 884 bytes .../gxt/images/default/form/checkbox.gif | Bin 0 -> 2061 bytes .../gxt/images/default/form/clear-trigger.gif | Bin 0 -> 1988 bytes .../gxt/images/default/form/date-trigger.gif | Bin 0 -> 1603 bytes .../images/default/form/error-tip-corners.gif | Bin 0 -> 4183 bytes .../gxt/images/default/form/exclamation.gif | Bin 0 -> 996 bytes .../webapp/gxt/images/default/form/radio.gif | Bin 0 -> 1746 bytes .../images/default/form/search-trigger.gif | Bin 0 -> 2182 bytes .../gxt/images/default/form/spinner.gif | Bin 0 -> 3186 bytes .../gxt/images/default/form/text-bg.gif | Bin 0 -> 819 bytes .../gxt/images/default/form/trigger-tpl.gif | Bin 0 -> 1487 bytes .../gxt/images/default/form/trigger.gif | Bin 0 -> 1688 bytes .../webapp/gxt/images/default/gradient-bg.gif | Bin 0 -> 1472 bytes .../images/default/grid/arrow-left-white.gif | Bin 0 -> 825 bytes .../images/default/grid/arrow-right-white.gif | Bin 0 -> 825 bytes .../images/default/grid/col-move-bottom.gif | Bin 0 -> 868 bytes .../gxt/images/default/grid/col-move-top.gif | Bin 0 -> 869 bytes .../gxt/images/default/grid/columns.gif | Bin 0 -> 962 bytes .../webapp/gxt/images/default/grid/dirty.gif | Bin 0 -> 832 bytes .../webapp/gxt/images/default/grid/done.gif | Bin 0 -> 133 bytes .../gxt/images/default/grid/drop-no.gif | Bin 0 -> 947 bytes .../gxt/images/default/grid/drop-yes.gif | Bin 0 -> 860 bytes .../gxt/images/default/grid/footer-bg.gif | Bin 0 -> 834 bytes .../gxt/images/default/grid/grid-blue-hd.gif | Bin 0 -> 829 bytes .../images/default/grid/grid-blue-split.gif | Bin 0 -> 817 bytes .../gxt/images/default/grid/grid-hrow.gif | Bin 0 -> 855 bytes .../gxt/images/default/grid/grid-loading.gif | Bin 0 -> 701 bytes .../gxt/images/default/grid/grid-split.gif | Bin 0 -> 817 bytes .../gxt/images/default/grid/grid-vista-hd.gif | Bin 0 -> 829 bytes .../gxt/images/default/grid/grid3-hd-btn.gif | Bin 0 -> 1298 bytes .../images/default/grid/grid3-hrow-group.gif | Bin 0 -> 811 bytes .../images/default/grid/grid3-hrow-over.gif | Bin 0 -> 823 bytes .../gxt/images/default/grid/grid3-hrow.gif | Bin 0 -> 836 bytes .../default/grid/grid3-special-col-bg.gif | Bin 0 -> 837 bytes .../default/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 843 bytes .../gxt/images/default/grid/group-by.gif | Bin 0 -> 917 bytes .../default/grid/group-expand-sprite.gif | Bin 0 -> 955 bytes .../webapp/gxt/images/default/grid/hd-pop.gif | Bin 0 -> 839 bytes .../gxt/images/default/grid/hmenu-asc.gif | Bin 0 -> 931 bytes .../gxt/images/default/grid/hmenu-desc.gif | Bin 0 -> 930 bytes .../gxt/images/default/grid/hmenu-lock.gif | Bin 0 -> 955 bytes .../gxt/images/default/grid/hmenu-lock.png | Bin 0 -> 648 bytes .../gxt/images/default/grid/hmenu-unlock.gif | Bin 0 -> 971 bytes .../gxt/images/default/grid/hmenu-unlock.png | Bin 0 -> 697 bytes .../gxt/images/default/grid/invalid_line.gif | Bin 0 -> 815 bytes .../gxt/images/default/grid/loading.gif | Bin 0 -> 771 bytes .../webapp/gxt/images/default/grid/mso-hd.gif | Bin 0 -> 875 bytes .../webapp/gxt/images/default/grid/nowait.gif | Bin 0 -> 884 bytes .../default/grid/page-first-disabled.gif | Bin 0 -> 925 bytes .../gxt/images/default/grid/page-first.gif | Bin 0 -> 925 bytes .../default/grid/page-last-disabled.gif | Bin 0 -> 923 bytes .../gxt/images/default/grid/page-last.gif | Bin 0 -> 923 bytes .../default/grid/page-next-disabled.gif | Bin 0 -> 875 bytes .../gxt/images/default/grid/page-next.gif | Bin 0 -> 875 bytes .../default/grid/page-prev-disabled.gif | Bin 0 -> 879 bytes .../gxt/images/default/grid/page-prev.gif | Bin 0 -> 879 bytes .../gxt/images/default/grid/pick-button.gif | Bin 0 -> 1036 bytes .../gxt/images/default/grid/refresh.gif | Bin 0 -> 977 bytes .../gxt/images/default/grid/refresh.png | Bin 0 -> 791 bytes .../images/default/grid/row-check-sprite.gif | Bin 0 -> 1083 bytes .../images/default/grid/row-expand-sprite.gif | Bin 0 -> 955 bytes .../gxt/images/default/grid/row-over.gif | Bin 0 -> 823 bytes .../gxt/images/default/grid/row-sel.gif | Bin 0 -> 823 bytes .../gxt/images/default/grid/sort-hd.gif | Bin 0 -> 1473 bytes .../gxt/images/default/grid/sort_asc.gif | Bin 0 -> 830 bytes .../gxt/images/default/grid/sort_desc.gif | Bin 0 -> 833 bytes .../webapp/gxt/images/default/grid/wait.gif | Bin 0 -> 1100 bytes .../gxt/images/default/layout/collapse.gif | Bin 0 -> 842 bytes .../gxt/images/default/layout/expand.gif | Bin 0 -> 842 bytes .../gxt/images/default/layout/gradient-bg.gif | Bin 0 -> 1472 bytes .../gxt/images/default/layout/mini-bottom.gif | Bin 0 -> 856 bytes .../gxt/images/default/layout/mini-left.gif | Bin 0 -> 871 bytes .../gxt/images/default/layout/mini-right.gif | Bin 0 -> 872 bytes .../gxt/images/default/layout/mini-top.gif | Bin 0 -> 856 bytes .../gxt/images/default/layout/ns-collapse.gif | Bin 0 -> 842 bytes .../gxt/images/default/layout/ns-expand.gif | Bin 0 -> 843 bytes .../gxt/images/default/layout/panel-close.gif | Bin 0 -> 829 bytes .../images/default/layout/panel-title-bg.gif | Bin 0 -> 838 bytes .../default/layout/panel-title-light-bg.gif | Bin 0 -> 835 bytes .../gxt/images/default/layout/stick.gif | Bin 0 -> 874 bytes .../gxt/images/default/layout/stuck.gif | Bin 0 -> 92 bytes .../images/default/layout/tab-close-on.gif | Bin 0 -> 880 bytes .../gxt/images/default/layout/tab-close.gif | Bin 0 -> 859 bytes .../gxt/images/default/menu/checked.gif | Bin 0 -> 959 bytes .../gxt/images/default/menu/group-checked.gif | Bin 0 -> 891 bytes .../gxt/images/default/menu/item-over.gif | Bin 0 -> 820 bytes .../gxt/images/default/menu/menu-parent.gif | Bin 0 -> 854 bytes .../webapp/gxt/images/default/menu/menu.gif | Bin 0 -> 834 bytes .../gxt/images/default/menu/unchecked.gif | Bin 0 -> 941 bytes .../images/default/panel/corners-sprite.gif | Bin 0 -> 1418 bytes .../gxt/images/default/panel/left-right.gif | Bin 0 -> 815 bytes .../gxt/images/default/panel/light-hd.gif | Bin 0 -> 827 bytes .../images/default/panel/tool-sprite-tpl.gif | Bin 0 -> 971 bytes .../gxt/images/default/panel/tool-sprites.gif | Bin 0 -> 4392 bytes .../default/panel/tools-sprites-trans.gif | Bin 0 -> 2843 bytes .../gxt/images/default/panel/top-bottom.gif | Bin 0 -> 875 bytes .../gxt/images/default/panel/top-bottom.png | Bin 0 -> 218 bytes .../default/panel/white-corners-sprite.gif | Bin 0 -> 1366 bytes .../images/default/panel/white-left-right.gif | Bin 0 -> 815 bytes .../images/default/panel/white-top-bottom.gif | Bin 0 -> 872 bytes .../images/default/progress/progress-bg.gif | Bin 0 -> 834 bytes .../webapp/gxt/images/default/qtip/bg.gif | Bin 0 -> 1091 bytes .../webapp/gxt/images/default/qtip/close.gif | Bin 0 -> 972 bytes .../images/default/qtip/tip-anchor-sprite.gif | Bin 0 -> 951 bytes .../gxt/images/default/qtip/tip-sprite.gif | Bin 0 -> 4271 bytes src/main/webapp/gxt/images/default/s.gif | Bin 0 -> 43 bytes .../webapp/gxt/images/default/shadow-c.png | Bin 0 -> 118 bytes .../webapp/gxt/images/default/shadow-lr.png | Bin 0 -> 135 bytes src/main/webapp/gxt/images/default/shadow.png | Bin 0 -> 311 bytes .../images/default/shared/blue-loading.gif | Bin 0 -> 3236 bytes .../gxt/images/default/shared/calendar.gif | Bin 0 -> 979 bytes .../gxt/images/default/shared/clear.gif | Bin 0 -> 43 bytes .../gxt/images/default/shared/glass-bg.gif | Bin 0 -> 873 bytes .../gxt/images/default/shared/hd-sprite.gif | Bin 0 -> 1099 bytes .../images/default/shared/large-loading.gif | Bin 0 -> 3236 bytes .../gxt/images/default/shared/left-btn.gif | Bin 0 -> 870 bytes .../images/default/shared/loading-balls.gif | Bin 0 -> 2118 bytes .../gxt/images/default/shared/right-btn.gif | Bin 0 -> 871 bytes .../gxt/images/default/shared/warning.gif | Bin 0 -> 960 bytes .../images/default/sizer/e-handle-dark.gif | Bin 0 -> 1062 bytes .../gxt/images/default/sizer/e-handle.gif | Bin 0 -> 1586 bytes .../images/default/sizer/ne-handle-dark.gif | Bin 0 -> 839 bytes .../gxt/images/default/sizer/ne-handle.gif | Bin 0 -> 854 bytes .../images/default/sizer/nw-handle-dark.gif | Bin 0 -> 839 bytes .../gxt/images/default/sizer/nw-handle.gif | Bin 0 -> 853 bytes .../images/default/sizer/s-handle-dark.gif | Bin 0 -> 1060 bytes .../gxt/images/default/sizer/s-handle.gif | Bin 0 -> 1318 bytes .../images/default/sizer/se-handle-dark.gif | Bin 0 -> 838 bytes .../gxt/images/default/sizer/se-handle.gif | Bin 0 -> 853 bytes .../gxt/images/default/sizer/square.gif | Bin 0 -> 864 bytes .../images/default/sizer/sw-handle-dark.gif | Bin 0 -> 839 bytes .../gxt/images/default/sizer/sw-handle.gif | Bin 0 -> 855 bytes .../gxt/images/default/slider/slider-bg.png | Bin 0 -> 300 bytes .../images/default/slider/slider-thumb.png | Bin 0 -> 933 bytes .../gxt/images/default/slider/slider-v-bg.png | Bin 0 -> 288 bytes .../images/default/slider/slider-v-thumb.png | Bin 0 -> 883 bytes .../gxt/images/default/tabs/scroll-left.gif | Bin 0 -> 1295 bytes .../gxt/images/default/tabs/scroll-right.gif | Bin 0 -> 1300 bytes .../gxt/images/default/tabs/scroller-bg.gif | Bin 0 -> 1100 bytes .../default/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 886 bytes .../tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 1386 bytes .../images/default/tabs/tab-btm-left-bg.gif | Bin 0 -> 863 bytes .../images/default/tabs/tab-btm-right-bg.gif | Bin 0 -> 1402 bytes .../gxt/images/default/tabs/tab-close.gif | Bin 0 -> 896 bytes .../gxt/images/default/tabs/tab-strip-bg.gif | Bin 0 -> 835 bytes .../gxt/images/default/tabs/tab-strip-bg.png | Bin 0 -> 259 bytes .../images/default/tabs/tab-strip-btm-bg.gif | Bin 0 -> 826 bytes .../gxt/images/default/tabs/tabs-sprite.gif | Bin 0 -> 2120 bytes .../webapp/gxt/images/default/toolbar/bg.gif | Bin 0 -> 904 bytes .../default/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../gxt/images/default/toolbar/btn-arrow.gif | Bin 0 -> 919 bytes .../images/default/toolbar/btn-over-bg.gif | Bin 0 -> 837 bytes .../gxt/images/default/toolbar/gray-bg.gif | Bin 0 -> 832 bytes .../gxt/images/default/toolbar/more.gif | Bin 0 -> 845 bytes .../gxt/images/default/toolbar/tb-bg.gif | Bin 0 -> 862 bytes .../images/default/toolbar/tb-btn-sprite.gif | Bin 0 -> 1127 bytes .../default/toolbar/tb-xl-btn-sprite.gif | Bin 0 -> 1663 bytes .../gxt/images/default/toolbar/tb-xl-sep.gif | Bin 0 -> 810 bytes .../webapp/gxt/images/default/tree/arrows.gif | Bin 0 -> 1024 bytes .../gxt/images/default/tree/drop-add.gif | Bin 0 -> 1001 bytes .../gxt/images/default/tree/drop-between.gif | Bin 0 -> 907 bytes .../gxt/images/default/tree/drop-no.gif | Bin 0 -> 949 bytes .../gxt/images/default/tree/drop-over.gif | Bin 0 -> 911 bytes .../gxt/images/default/tree/drop-under.gif | Bin 0 -> 911 bytes .../gxt/images/default/tree/drop-yes.gif | Bin 0 -> 1016 bytes .../default/tree/elbow-end-minus-nl.gif | Bin 0 -> 898 bytes .../images/default/tree/elbow-end-minus.gif | Bin 0 -> 905 bytes .../images/default/tree/elbow-end-plus-nl.gif | Bin 0 -> 900 bytes .../images/default/tree/elbow-end-plus.gif | Bin 0 -> 907 bytes .../gxt/images/default/tree/elbow-end.gif | Bin 0 -> 844 bytes .../gxt/images/default/tree/elbow-line.gif | Bin 0 -> 846 bytes .../images/default/tree/elbow-minus-nl.gif | Bin 0 -> 898 bytes .../gxt/images/default/tree/elbow-minus.gif | Bin 0 -> 908 bytes .../gxt/images/default/tree/elbow-plus-nl.gif | Bin 0 -> 900 bytes .../gxt/images/default/tree/elbow-plus.gif | Bin 0 -> 910 bytes .../webapp/gxt/images/default/tree/elbow.gif | Bin 0 -> 850 bytes .../gxt/images/default/tree/folder-open.gif | Bin 0 -> 956 bytes .../webapp/gxt/images/default/tree/folder.gif | Bin 0 -> 952 bytes .../webapp/gxt/images/default/tree/leaf.gif | Bin 0 -> 945 bytes .../gxt/images/default/tree/loading.gif | Bin 0 -> 771 bytes src/main/webapp/gxt/images/default/tree/s.gif | Bin 0 -> 43 bytes .../gxt/images/default/window/icon-error.gif | Bin 0 -> 1669 bytes .../gxt/images/default/window/icon-info.gif | Bin 0 -> 1586 bytes .../images/default/window/icon-question.gif | Bin 0 -> 1607 bytes .../images/default/window/icon-warning.gif | Bin 0 -> 1483 bytes .../images/default/window/left-corners.png | Bin 0 -> 200 bytes .../gxt/images/default/window/left-right.png | Bin 0 -> 152 bytes .../images/default/window/right-corners.png | Bin 0 -> 256 bytes .../gxt/images/default/window/top-bottom.png | Bin 0 -> 180 bytes .../gxt/images/gray/button/btn-arrow.gif | Bin 0 -> 870 bytes .../gxt/images/gray/button/btn-sprite.gif | Bin 0 -> 1222 bytes .../webapp/gxt/images/gray/button/btn.gif | Bin 0 -> 3319 bytes .../gxt/images/gray/button/group-cs.gif | Bin 0 -> 2459 bytes .../gxt/images/gray/button/group-lr.gif | Bin 0 -> 861 bytes .../gxt/images/gray/button/group-tb.gif | Bin 0 -> 846 bytes .../webapp/gxt/images/gray/form/spinner.gif | Bin 0 -> 3046 bytes .../webapp/gxt/images/gray/gradient-bg.gif | Bin 0 -> 1472 bytes .../gxt/images/gray/grid/col-move-bottom.gif | Bin 0 -> 177 bytes .../gxt/images/gray/grid/col-move-top.gif | Bin 0 -> 178 bytes .../gxt/images/gray/grid/grid-split.gif | Bin 0 -> 809 bytes .../gxt/images/gray/grid/grid3-hd-btn.gif | Bin 0 -> 482 bytes .../gxt/images/gray/grid/grid3-hrow-over.gif | Bin 0 -> 56 bytes .../gxt/images/gray/grid/grid3-hrow-over2.gif | Bin 0 -> 107 bytes .../gxt/images/gray/grid/grid3-hrow.gif | Bin 0 -> 836 bytes .../gxt/images/gray/grid/grid3-hrow2.gif | Bin 0 -> 107 bytes .../images/gray/grid/grid3-special-col-bg.gif | Bin 0 -> 158 bytes .../gray/grid/grid3-special-col-bg2.gif | Bin 0 -> 158 bytes .../gray/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 158 bytes .../gxt/images/gray/grid/group-collapse.gif | Bin 0 -> 136 bytes .../images/gray/grid/group-expand-sprite.gif | Bin 0 -> 196 bytes .../gxt/images/gray/grid/group-expand.gif | Bin 0 -> 138 bytes .../gxt/images/gray/grid/page-first.gif | Bin 0 -> 327 bytes .../webapp/gxt/images/gray/grid/page-last.gif | Bin 0 -> 325 bytes .../webapp/gxt/images/gray/grid/page-next.gif | Bin 0 -> 183 bytes .../webapp/gxt/images/gray/grid/page-prev.gif | Bin 0 -> 186 bytes .../webapp/gxt/images/gray/grid/refresh.gif | Bin 0 -> 570 bytes .../images/gray/grid/row-expand-sprite.gif | Bin 0 -> 196 bytes .../webapp/gxt/images/gray/grid/sort_asc.gif | Bin 0 -> 59 bytes .../webapp/gxt/images/gray/grid/sort_desc.gif | Bin 0 -> 59 bytes .../gxt/images/gray/panel/corners-sprite.gif | Bin 0 -> 765 bytes .../gxt/images/gray/panel/left-right.gif | Bin 0 -> 63 bytes .../webapp/gxt/images/gray/panel/light-hd.gif | Bin 0 -> 827 bytes .../gxt/images/gray/panel/tool-sprite-tpl.gif | Bin 0 -> 971 bytes .../gxt/images/gray/panel/tool-sprites.gif | Bin 0 -> 4464 bytes .../images/gray/panel/tools-sprites-trans.gif | Bin 0 -> 2640 bytes .../gxt/images/gray/panel/top-bottom.gif | Bin 0 -> 873 bytes .../gxt/images/gray/panel/top-bottom.png | Bin 0 -> 218 bytes .../gray/panel/white-corners-sprite.gif | Bin 0 -> 1365 bytes .../images/gray/panel/white-left-right.gif | Bin 0 -> 815 bytes .../images/gray/panel/white-top-bottom.gif | Bin 0 -> 868 bytes src/main/webapp/gxt/images/gray/qtip/bg.gif | Bin 0 -> 1024 bytes .../webapp/gxt/images/gray/qtip/close.gif | Bin 0 -> 972 bytes .../gxt/images/gray/qtip/tip-sprite.gif | Bin 0 -> 4033 bytes src/main/webapp/gxt/images/gray/s.gif | Bin 0 -> 43 bytes .../gxt/images/gray/tabs/scroll-left.gif | Bin 0 -> 1260 bytes .../gxt/images/gray/tabs/scroll-right.gif | Bin 0 -> 1269 bytes .../gxt/images/gray/tabs/scroller-bg.gif | Bin 0 -> 1090 bytes .../gray/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 881 bytes .../gray/tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 1383 bytes .../gxt/images/gray/tabs/tab-btm-left-bg.gif | Bin 0 -> 863 bytes .../gxt/images/gray/tabs/tab-btm-right-bg.gif | Bin 0 -> 1402 bytes .../webapp/gxt/images/gray/tabs/tab-close.gif | Bin 0 -> 896 bytes .../gxt/images/gray/tabs/tab-strip-bg.gif | Bin 0 -> 835 bytes .../gxt/images/gray/tabs/tab-strip-bg.png | Bin 0 -> 259 bytes .../gxt/images/gray/tabs/tab-strip-btm-bg.gif | Bin 0 -> 826 bytes .../gxt/images/gray/tabs/tabs-sprite.gif | Bin 0 -> 2109 bytes .../webapp/gxt/images/gray/toolbar/bg.gif | Bin 0 -> 853 bytes .../images/gray/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../gxt/images/gray/toolbar/btn-arrow.gif | Bin 0 -> 919 bytes .../gxt/images/gray/toolbar/btn-over-bg.gif | Bin 0 -> 837 bytes .../gxt/images/gray/toolbar/gray-bg.gif | Bin 0 -> 815 bytes .../webapp/gxt/images/gray/toolbar/tb-bg.gif | Bin 0 -> 862 bytes .../gxt/images/gray/toolbar/tb-btn-sprite.gif | Bin 0 -> 1021 bytes .../gxt/images/gray/window/icon-error.gif | Bin 0 -> 1669 bytes .../gxt/images/gray/window/icon-info.gif | Bin 0 -> 1586 bytes .../gxt/images/gray/window/icon-question.gif | Bin 0 -> 1607 bytes .../gxt/images/gray/window/icon-warning.gif | Bin 0 -> 1483 bytes .../gxt/images/gray/window/left-corners.png | Bin 0 -> 325 bytes .../images/gray/window/left-corners.pspimage | Bin 0 -> 4385 bytes .../gxt/images/gray/window/left-right.png | Bin 0 -> 2815 bytes .../gxt/images/gray/window/right-corners.png | Bin 0 -> 344 bytes .../gxt/images/gray/window/top-bottom.png | Bin 0 -> 2860 bytes .../webapp/gxt/images/gxt/dd/insert-bg.gif | Bin 0 -> 54 bytes .../gxt/images/gxt/grid/row-editor-bg.gif | Bin 0 -> 819 bytes .../gxt/images/gxt/grid/row-editor-btns.gif | Bin 0 -> 1087 bytes .../webapp/gxt/images/gxt/icons/bottom2.gif | Bin 0 -> 927 bytes .../webapp/gxt/images/gxt/icons/columns.gif | Bin 0 -> 962 bytes src/main/webapp/gxt/images/gxt/icons/done.gif | Bin 0 -> 133 bytes .../gxt/images/gxt/icons/doubleleft2.gif | Bin 0 -> 174 bytes .../gxt/images/gxt/icons/doubleright2.gif | Bin 0 -> 171 bytes .../webapp/gxt/images/gxt/icons/down2.gif | Bin 0 -> 920 bytes .../gxt/images/gxt/icons/folder-closed.gif | Bin 0 -> 999 bytes .../gxt/images/gxt/icons/folder-closed.png | Bin 0 -> 686 bytes .../webapp/gxt/images/gxt/icons/folder.gif | Bin 0 -> 996 bytes .../webapp/gxt/images/gxt/icons/folder.png | Bin 0 -> 711 bytes .../gxt/images/gxt/icons/grid-loading.gif | Bin 0 -> 701 bytes .../webapp/gxt/images/gxt/icons/hmenu-asc.gif | Bin 0 -> 931 bytes .../gxt/images/gxt/icons/hmenu-desc.gif | Bin 0 -> 930 bytes .../webapp/gxt/images/gxt/icons/left2.gif | Bin 0 -> 920 bytes .../webapp/gxt/images/gxt/icons/loading.gif | Bin 0 -> 771 bytes .../webapp/gxt/images/gxt/icons/nowait.gif | Bin 0 -> 884 bytes .../images/gxt/icons/page-first-disabled.gif | Bin 0 -> 925 bytes .../gxt/images/gxt/icons/page-first.gif | Bin 0 -> 925 bytes .../images/gxt/icons/page-last-disabled.gif | Bin 0 -> 923 bytes .../webapp/gxt/images/gxt/icons/page-last.gif | Bin 0 -> 923 bytes .../images/gxt/icons/page-next-disabled.gif | Bin 0 -> 875 bytes .../webapp/gxt/images/gxt/icons/page-next.gif | Bin 0 -> 875 bytes .../images/gxt/icons/page-prev-disabled.gif | Bin 0 -> 879 bytes .../webapp/gxt/images/gxt/icons/page-prev.gif | Bin 0 -> 879 bytes .../webapp/gxt/images/gxt/icons/paging.gif | Bin 0 -> 989 bytes .../webapp/gxt/images/gxt/icons/right2.gif | Bin 0 -> 925 bytes src/main/webapp/gxt/images/gxt/icons/tabs.gif | Bin 0 -> 917 bytes src/main/webapp/gxt/images/gxt/icons/top2.gif | Bin 0 -> 927 bytes src/main/webapp/gxt/images/gxt/icons/up2.gif | Bin 0 -> 920 bytes src/main/webapp/gxt/images/gxt/icons/wait.gif | Bin 0 -> 1100 bytes .../gxt/images/gxt/info/corners-sprite.gif | Bin 0 -> 1154 bytes .../webapp/gxt/images/gxt/info/top-bottom.gif | Bin 0 -> 1329 bytes .../gxt/images/gxt/menu/disabledcheck.gif | Bin 0 -> 907 bytes .../webapp/gxt/images/gxt/shared/clear.gif | Bin 0 -> 43 bytes .../gxt/images/gxt/shared/large-loading.gif | Bin 0 -> 3236 bytes .../gxt/images/gxt/shared/select-18-bg.gif | Bin 0 -> 508 bytes .../images/gxt/shared/select-19-bg-gray.gif | Bin 0 -> 1192 bytes .../gxt/images/gxt/shared/select-19-bg.gif | Bin 0 -> 2018 bytes .../gxt/images/gxt/shared/select-bg.gif | Bin 0 -> 1431 bytes .../gxt/images/gxt/shared/select-light.gif | Bin 0 -> 540 bytes .../webapp/gxt/images/gxt/table/row-over.gif | Bin 0 -> 823 bytes .../gxt/images/gxt/table/vs-column-bg.gif | Bin 0 -> 548 bytes .../webapp/gxt/images/gxt/table/vsort-asc.gif | Bin 0 -> 846 bytes .../gxt/images/gxt/table/vsort-desc.gif | Bin 0 -> 845 bytes .../webapp/gxt/images/gxt/tree/checked.gif | Bin 0 -> 533 bytes .../gxt/images/gxt/tree/joint-close.gif | Bin 0 -> 900 bytes .../webapp/gxt/images/gxt/tree/joint-open.gif | Bin 0 -> 898 bytes .../webapp/gxt/images/gxt/tree/notchecked.gif | Bin 0 -> 321 bytes .../gxt/tree/tree-table-special-col-sel.gif | Bin 0 -> 835 bytes .../gxt/tree/tree-table-special-col.gif | Bin 0 -> 96 bytes src/main/webapp/gxt/images/gxt/tree/vnode.gif | Bin 0 -> 846 bytes .../gxt/images/gxt/tree/vnode_transparent.gif | Bin 0 -> 972 bytes .../gxt/themes/access/css/xtheme-access.css | 2347 ++++++ .../themes/access/images/box/corners-blue.gif | Bin 0 -> 1010 bytes .../gxt/themes/access/images/box/corners.gif | Bin 0 -> 1005 bytes .../gxt/themes/access/images/box/l-blue.gif | Bin 0 -> 810 bytes .../webapp/gxt/themes/access/images/box/l.gif | Bin 0 -> 810 bytes .../gxt/themes/access/images/box/r-blue.gif | Bin 0 -> 810 bytes .../webapp/gxt/themes/access/images/box/r.gif | Bin 0 -> 810 bytes .../gxt/themes/access/images/box/tb-blue.gif | Bin 0 -> 843 bytes .../gxt/themes/access/images/box/tb.gif | Bin 0 -> 839 bytes .../gxt/themes/access/images/button/arrow.gif | Bin 0 -> 833 bytes .../gxt/themes/access/images/button/btn.gif | Bin 0 -> 2871 bytes .../themes/access/images/button/group-cs.gif | Bin 0 -> 2459 bytes .../themes/access/images/button/group-lr.gif | Bin 0 -> 861 bytes .../themes/access/images/button/group-tb.gif | Bin 0 -> 70 bytes .../access/images/button/s-arrow-b-noline.gif | Bin 0 -> 904 bytes .../themes/access/images/button/s-arrow-b.gif | Bin 0 -> 943 bytes .../access/images/button/s-arrow-bo.gif | Bin 0 -> 961 bytes .../access/images/button/s-arrow-noline.gif | Bin 0 -> 875 bytes .../themes/access/images/button/s-arrow-o.gif | Bin 0 -> 155 bytes .../themes/access/images/button/s-arrow.gif | Bin 0 -> 956 bytes .../themes/access/images/editor/tb-source.gif | Bin 0 -> 952 bytes .../themes/access/images/editor/tb-sprite.gif | Bin 0 -> 1994 bytes .../themes/access/images/form/checkbox.gif | Bin 0 -> 2061 bytes .../access/images/form/clear-trigger.gif | Bin 0 -> 2027 bytes .../access/images/form/date-trigger.gif | Bin 0 -> 1620 bytes .../access/images/form/error-tip-corners.gif | Bin 0 -> 4183 bytes .../themes/access/images/form/exclamation.gif | Bin 0 -> 614 bytes .../gxt/themes/access/images/form/radio.gif | Bin 0 -> 1746 bytes .../access/images/form/search-trigger.gif | Bin 0 -> 2134 bytes .../gxt/themes/access/images/form/spinner.gif | Bin 0 -> 4142 bytes .../gxt/themes/access/images/form/text-bg.gif | Bin 0 -> 66 bytes .../access/images/form/trigger-single.gif | Bin 0 -> 605 bytes .../themes/access/images/form/trigger-tpl.gif | Bin 0 -> 908 bytes .../gxt/themes/access/images/form/trigger.gif | Bin 0 -> 1451 bytes .../access/images/grid/arrow-left-white.gif | Bin 0 -> 825 bytes .../access/images/grid/arrow-right-white.gif | Bin 0 -> 825 bytes .../access/images/grid/col-move-bottom.gif | Bin 0 -> 868 bytes .../access/images/grid/col-move-top.gif | Bin 0 -> 869 bytes .../gxt/themes/access/images/grid/columns.gif | Bin 0 -> 962 bytes .../gxt/themes/access/images/grid/dirty.gif | Bin 0 -> 68 bytes .../gxt/themes/access/images/grid/done.gif | Bin 0 -> 133 bytes .../gxt/themes/access/images/grid/drop-no.gif | Bin 0 -> 947 bytes .../themes/access/images/grid/drop-yes.gif | Bin 0 -> 860 bytes .../themes/access/images/grid/footer-bg.gif | Bin 0 -> 834 bytes .../access/images/grid/grid-blue-hd.gif | Bin 0 -> 829 bytes .../access/images/grid/grid-blue-split.gif | Bin 0 -> 47 bytes .../themes/access/images/grid/grid-hrow.gif | Bin 0 -> 855 bytes .../access/images/grid/grid-loading.gif | Bin 0 -> 701 bytes .../themes/access/images/grid/grid-split.gif | Bin 0 -> 817 bytes .../access/images/grid/grid-vista-hd.gif | Bin 0 -> 829 bytes .../images/grid/grid3-hd-btn-contrast.gif | Bin 0 -> 336 bytes .../access/images/grid/grid3-hd-btn.gif | Bin 0 -> 419 bytes .../access/images/grid/grid3-hrow-over.gif | Bin 0 -> 268 bytes .../themes/access/images/grid/grid3-hrow.gif | Bin 0 -> 164 bytes .../images/grid/grid3-special-col-bg.gif | Bin 0 -> 162 bytes .../images/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 162 bytes .../themes/access/images/grid/group-by.gif | Bin 0 -> 917 bytes .../access/images/grid/group-collapse.gif | Bin 0 -> 77 bytes .../images/grid/group-expand-sprite.gif | Bin 0 -> 131 bytes .../access/images/grid/group-expand.gif | Bin 0 -> 82 bytes .../gxt/themes/access/images/grid/hd-pop.gif | Bin 0 -> 839 bytes .../themes/access/images/grid/hmenu-asc.gif | Bin 0 -> 931 bytes .../themes/access/images/grid/hmenu-desc.gif | Bin 0 -> 930 bytes .../themes/access/images/grid/hmenu-lock.gif | Bin 0 -> 955 bytes .../themes/access/images/grid/hmenu-lock.png | Bin 0 -> 648 bytes .../access/images/grid/hmenu-unlock.gif | Bin 0 -> 971 bytes .../access/images/grid/hmenu-unlock.png | Bin 0 -> 697 bytes .../access/images/grid/invalid_line.gif | Bin 0 -> 46 bytes .../gxt/themes/access/images/grid/loading.gif | Bin 0 -> 771 bytes .../gxt/themes/access/images/grid/mso-hd.gif | Bin 0 -> 875 bytes .../gxt/themes/access/images/grid/nowait.gif | Bin 0 -> 884 bytes .../images/grid/page-first-disabled.gif | Bin 0 -> 340 bytes .../themes/access/images/grid/page-first.gif | Bin 0 -> 96 bytes .../access/images/grid/page-last-disabled.gif | Bin 0 -> 340 bytes .../themes/access/images/grid/page-last.gif | Bin 0 -> 96 bytes .../access/images/grid/page-next-disabled.gif | Bin 0 -> 195 bytes .../themes/access/images/grid/page-next.gif | Bin 0 -> 82 bytes .../access/images/grid/page-prev-disabled.gif | Bin 0 -> 197 bytes .../themes/access/images/grid/page-prev.gif | Bin 0 -> 82 bytes .../themes/access/images/grid/pick-button.gif | Bin 0 -> 1036 bytes .../gxt/themes/access/images/grid/refresh.gif | Bin 0 -> 91 bytes .../access/images/grid/row-check-sel.gif | Bin 0 -> 932 bytes .../access/images/grid/row-check-sprite.gif | Bin 0 -> 1083 bytes .../themes/access/images/grid/row-check.gif | Bin 0 -> 918 bytes .../access/images/grid/row-expand-sprite.gif | Bin 0 -> 955 bytes .../themes/access/images/grid/row-over.gif | Bin 0 -> 823 bytes .../gxt/themes/access/images/grid/row-sel.gif | Bin 0 -> 823 bytes .../gxt/themes/access/images/grid/sort-hd.gif | Bin 0 -> 2075 bytes .../themes/access/images/grid/sort_asc.gif | Bin 0 -> 74 bytes .../themes/access/images/grid/sort_desc.gif | Bin 0 -> 73 bytes .../gxt/themes/access/images/grid/wait.gif | Bin 0 -> 1100 bytes .../themes/access/images/icons/bottom2.gif | Bin 0 -> 927 bytes .../access/images/icons/doubleleft2.gif | Bin 0 -> 174 bytes .../access/images/icons/doubleright2.gif | Bin 0 -> 171 bytes .../gxt/themes/access/images/icons/down2.gif | Bin 0 -> 920 bytes .../gxt/themes/access/images/icons/left2.gif | Bin 0 -> 920 bytes .../gxt/themes/access/images/icons/right2.gif | Bin 0 -> 925 bytes .../gxt/themes/access/images/icons/top2.gif | Bin 0 -> 927 bytes .../gxt/themes/access/images/icons/up2.gif | Bin 0 -> 920 bytes .../access/images/layout/mini-bottom.gif | Bin 0 -> 856 bytes .../themes/access/images/layout/mini-top.gif | Bin 0 -> 856 bytes .../gxt/themes/access/images/menu/checked.gif | Bin 0 -> 959 bytes .../access/images/menu/group-checked.gif | Bin 0 -> 856 bytes .../themes/access/images/menu/item-over.gif | Bin 0 -> 820 bytes .../themes/access/images/menu/menu-parent.gif | Bin 0 -> 73 bytes .../gxt/themes/access/images/menu/menu.gif | Bin 0 -> 826 bytes .../themes/access/images/menu/unchecked.gif | Bin 0 -> 941 bytes .../access/images/panel/corners-sprite.gif | Bin 0 -> 577 bytes .../themes/access/images/panel/left-right.gif | Bin 0 -> 52 bytes .../themes/access/images/panel/light-hd.gif | Bin 0 -> 161 bytes .../themes/access/images/panel/tool-close.gif | Bin 0 -> 104 bytes .../access/images/panel/tool-collapse.gif | Bin 0 -> 95 bytes .../access/images/panel/tool-expand.gif | Bin 0 -> 93 bytes .../themes/access/images/panel/tool-gear.gif | Bin 0 -> 106 bytes .../access/images/panel/tool-maximize.gif | Bin 0 -> 111 bytes .../access/images/panel/tool-minimize.gif | Bin 0 -> 93 bytes .../themes/access/images/panel/tool-pin.gif | Bin 0 -> 101 bytes .../access/images/panel/tool-sprite-tpl.gif | Bin 0 -> 971 bytes .../access/images/panel/tool-sprites.gif | Bin 0 -> 1981 bytes .../images/panel/tools-sprites-trans.gif | Bin 0 -> 2843 bytes .../themes/access/images/panel/top-bottom.gif | Bin 0 -> 116 bytes .../images/panel/white-corners-sprite.gif | Bin 0 -> 1366 bytes .../access/images/panel/white-left-right.gif | Bin 0 -> 52 bytes .../access/images/panel/white-top-bottom.gif | Bin 0 -> 115 bytes .../access/images/progress/progress-bg.gif | Bin 0 -> 151 bytes .../gxt/themes/access/images/qtip/close.gif | Bin 0 -> 972 bytes .../access/images/qtip/tip-anchor-sprite.gif | Bin 0 -> 951 bytes .../themes/access/images/qtip/tip-sprite.gif | Bin 0 -> 3376 bytes .../themes/access/images/shared/glass-bg.gif | Bin 0 -> 103 bytes .../themes/access/images/shared/hd-sprite.gif | Bin 0 -> 673 bytes .../themes/access/images/shared/left-btn.gif | Bin 0 -> 77 bytes .../themes/access/images/shared/right-btn.gif | Bin 0 -> 79 bytes .../access/images/sizer/e-handle-dark.gif | Bin 0 -> 248 bytes .../themes/access/images/sizer/e-handle.gif | Bin 0 -> 753 bytes .../access/images/sizer/ne-handle-dark.gif | Bin 0 -> 66 bytes .../themes/access/images/sizer/ne-handle.gif | Bin 0 -> 115 bytes .../access/images/sizer/nw-handle-dark.gif | Bin 0 -> 66 bytes .../themes/access/images/sizer/nw-handle.gif | Bin 0 -> 114 bytes .../access/images/sizer/s-handle-dark.gif | Bin 0 -> 246 bytes .../themes/access/images/sizer/s-handle.gif | Bin 0 -> 494 bytes .../access/images/sizer/se-handle-dark.gif | Bin 0 -> 65 bytes .../themes/access/images/sizer/se-handle.gif | Bin 0 -> 114 bytes .../gxt/themes/access/images/sizer/square.gif | Bin 0 -> 123 bytes .../access/images/sizer/sw-handle-dark.gif | Bin 0 -> 66 bytes .../themes/access/images/sizer/sw-handle.gif | Bin 0 -> 116 bytes .../themes/access/images/slider/slider-bg.png | Bin 0 -> 3636 bytes .../images/slider/slider-thumb-single.png | Bin 0 -> 3067 bytes .../access/images/slider/slider-thumb.png | Bin 0 -> 3436 bytes .../access/images/slider/slider-v-bg.png | Bin 0 -> 3630 bytes .../access/images/slider/slider-v-thumb.png | Bin 0 -> 3432 bytes .../themes/access/images/tabs/scroll-left.gif | Bin 0 -> 996 bytes .../access/images/tabs/scroll-right.gif | Bin 0 -> 999 bytes .../images/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 130 bytes .../images/tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 513 bytes .../access/images/tabs/tab-btm-left-bg.gif | Bin 0 -> 117 bytes .../access/images/tabs/tab-btm-right-bg.gif | Bin 0 -> 512 bytes .../themes/access/images/tabs/tab-close.gif | Bin 0 -> 76 bytes .../access/images/tabs/tab-strip-bg.gif | Bin 0 -> 827 bytes .../access/images/tabs/tab-strip-btm-bg.gif | Bin 0 -> 70 bytes .../themes/access/images/tabs/tabs-sprite.gif | Bin 0 -> 1221 bytes .../gxt/themes/access/images/toolbar/bg.gif | Bin 0 -> 82 bytes .../access/images/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../access/images/toolbar/btn-arrow.gif | Bin 0 -> 919 bytes .../access/images/toolbar/btn-over-bg.gif | Bin 0 -> 837 bytes .../themes/access/images/toolbar/gray-bg.gif | Bin 0 -> 832 bytes .../gxt/themes/access/images/toolbar/more.gif | Bin 0 -> 67 bytes .../access/images/toolbar/s-arrow-bo.gif | Bin 0 -> 186 bytes .../access/images/toolbar/tb-btn-sprite.gif | Bin 0 -> 1127 bytes .../images/toolbar/tb-xl-btn-sprite.gif | Bin 0 -> 1663 bytes .../access/images/toolbar/tb-xl-sep.gif | Bin 0 -> 810 bytes .../gxt/themes/access/images/tree/arrows.gif | Bin 0 -> 183 bytes .../themes/access/images/tree/drop-add.gif | Bin 0 -> 1001 bytes .../access/images/tree/drop-between.gif | Bin 0 -> 907 bytes .../gxt/themes/access/images/tree/drop-no.gif | Bin 0 -> 949 bytes .../themes/access/images/tree/drop-over.gif | Bin 0 -> 911 bytes .../themes/access/images/tree/drop-under.gif | Bin 0 -> 911 bytes .../themes/access/images/tree/drop-yes.gif | Bin 0 -> 1016 bytes .../access/images/tree/elbow-end-minus-nl.gif | Bin 0 -> 86 bytes .../access/images/tree/elbow-end-minus.gif | Bin 0 -> 104 bytes .../access/images/tree/elbow-end-plus-nl.gif | Bin 0 -> 89 bytes .../access/images/tree/elbow-end-plus.gif | Bin 0 -> 108 bytes .../themes/access/images/tree/elbow-end.gif | Bin 0 -> 844 bytes .../themes/access/images/tree/elbow-line.gif | Bin 0 -> 846 bytes .../access/images/tree/elbow-minus-nl.gif | Bin 0 -> 86 bytes .../themes/access/images/tree/elbow-minus.gif | Bin 0 -> 106 bytes .../access/images/tree/elbow-plus-nl.gif | Bin 0 -> 89 bytes .../themes/access/images/tree/elbow-plus.gif | Bin 0 -> 111 bytes .../gxt/themes/access/images/tree/elbow.gif | Bin 0 -> 850 bytes .../themes/access/images/tree/folder-open.gif | Bin 0 -> 342 bytes .../gxt/themes/access/images/tree/folder.gif | Bin 0 -> 340 bytes .../gxt/themes/access/images/tree/leaf.gif | Bin 0 -> 945 bytes .../gxt/themes/access/images/tree/loading.gif | Bin 0 -> 771 bytes .../gxt/themes/access/images/tree/s.gif | Bin 0 -> 43 bytes .../access/images/tree/tree-collapsed.png | Bin 0 -> 2928 bytes .../access/images/tree/tree-expanded.png | Bin 0 -> 2904 bytes .../access/images/window/icon-error.gif | Bin 0 -> 256 bytes .../themes/access/images/window/icon-info.gif | Bin 0 -> 172 bytes .../access/images/window/icon-question.gif | Bin 0 -> 217 bytes .../access/images/window/icon-warning.gif | Bin 0 -> 173 bytes .../access/images/window/left-corners.png | Bin 0 -> 3612 bytes .../access/images/window/left-right.png | Bin 0 -> 3578 bytes .../access/images/window/right-corners.png | Bin 0 -> 3612 bytes .../access/images/window/top-bottom.png | Bin 0 -> 3600 bytes .../gxt/themes/slate/css/xtheme-slate.css | 1058 +++ .../slate/images/slate/button/arrow.gif | Bin 0 -> 59 bytes .../slate/images/slate/button/btn-arrow.gif | Bin 0 -> 871 bytes .../slate/images/slate/button/btn-sprite.gif | Bin 0 -> 1394 bytes .../themes/slate/images/slate/button/btn.gif | Bin 0 -> 4687 bytes .../slate/images/slate/button/group-cs.gif | Bin 0 -> 1598 bytes .../slate/images/slate/button/group-lr.gif | Bin 0 -> 94 bytes .../slate/images/slate/button/group-tb.gif | Bin 0 -> 88 bytes .../images/slate/button/s-arrow-b-noline.gif | Bin 0 -> 82 bytes .../slate/images/slate/button/s-arrow-b.gif | Bin 0 -> 151 bytes .../slate/images/slate/button/s-arrow-bo.gif | Bin 0 -> 151 bytes .../images/slate/button/s-arrow-noline.gif | Bin 0 -> 82 bytes .../slate/images/slate/button/s-arrow-o.gif | Bin 0 -> 152 bytes .../slate/images/slate/button/s-arrow.gif | Bin 0 -> 152 bytes .../slate/images/slate/editor/tb-sprite.gif | Bin 0 -> 1994 bytes .../slate/images/slate/form/checkbox.gif | Bin 0 -> 1483 bytes .../slate/images/slate/form/clear-trigger.gif | Bin 0 -> 2091 bytes .../slate/images/slate/form/date-trigger.gif | Bin 0 -> 1612 bytes .../images/slate/form/error-tip-corners.gif | Bin 0 -> 4183 bytes .../themes/slate/images/slate/form/radio.gif | Bin 0 -> 1846 bytes .../images/slate/form/search-trigger.gif | Bin 0 -> 2345 bytes .../slate/images/slate/form/spinner.gif | Bin 0 -> 1857 bytes .../slate/images/slate/form/trigger-tpl.gif | Bin 0 -> 1506 bytes .../slate/images/slate/form/trigger.gif | Bin 0 -> 1657 bytes .../themes/slate/images/slate/gradient-bg.gif | Bin 0 -> 1472 bytes .../images/slate/grid/arrow-left-white.gif | Bin 0 -> 825 bytes .../images/slate/grid/arrow-right-white.gif | Bin 0 -> 825 bytes .../images/slate/grid/col-move-bottom.gif | Bin 0 -> 868 bytes .../slate/images/slate/grid/col-move-top.gif | Bin 0 -> 869 bytes .../slate/images/slate/grid/footer-bg.gif | Bin 0 -> 834 bytes .../slate/images/slate/grid/grid-blue-hd.gif | Bin 0 -> 829 bytes .../images/slate/grid/grid-blue-split.gif | Bin 0 -> 817 bytes .../slate/images/slate/grid/grid-hrow.gif | Bin 0 -> 855 bytes .../slate/images/slate/grid/grid-split.gif | Bin 0 -> 817 bytes .../slate/images/slate/grid/grid-vista-hd.gif | Bin 0 -> 829 bytes .../slate/images/slate/grid/grid3-hd-btn.gif | Bin 0 -> 1212 bytes .../images/slate/grid/grid3-hrow-over.gif | Bin 0 -> 826 bytes .../slate/images/slate/grid/grid3-hrow.gif | Bin 0 -> 828 bytes .../slate/grid/grid3-special-col-bg.gif | Bin 0 -> 837 bytes .../slate/grid/grid3-special-col-sel-bg.gif | Bin 0 -> 847 bytes .../images/slate/grid/group-expand-sprite.gif | Bin 0 -> 955 bytes .../themes/slate/images/slate/grid/mso-hd.gif | Bin 0 -> 875 bytes .../images/slate/grid/page-first-disabled.gif | Bin 0 -> 925 bytes .../slate/images/slate/grid/page-first.gif | Bin 0 -> 925 bytes .../images/slate/grid/page-last-disabled.gif | Bin 0 -> 923 bytes .../slate/images/slate/grid/page-last.gif | Bin 0 -> 923 bytes .../images/slate/grid/page-next-disabled.gif | Bin 0 -> 875 bytes .../slate/images/slate/grid/page-next.gif | Bin 0 -> 875 bytes .../images/slate/grid/page-prev-disabled.gif | Bin 0 -> 879 bytes .../slate/images/slate/grid/page-prev.gif | Bin 0 -> 879 bytes .../slate/images/slate/grid/refresh.gif | Bin 0 -> 980 bytes .../slate/images/slate/grid/row-over.gif | Bin 0 -> 823 bytes .../slate/images/slate/grid/row-sel.gif | Bin 0 -> 823 bytes .../slate/images/slate/grid/sort_asc.gif | Bin 0 -> 830 bytes .../slate/images/slate/grid/sort_desc.gif | Bin 0 -> 833 bytes .../slate/images/slate/menu/checked.gif | Bin 0 -> 894 bytes .../slate/images/slate/menu/group-checked.gif | Bin 0 -> 887 bytes .../images/slate/menu/item-over - Copy.gif | Bin 0 -> 833 bytes .../slate/images/slate/menu/item-over.gif | Bin 0 -> 833 bytes .../slate/images/slate/menu/menu-parent.gif | Bin 0 -> 853 bytes .../themes/slate/images/slate/menu/menu.gif | Bin 0 -> 839 bytes .../slate/images/slate/menu/unchecked.gif | Bin 0 -> 877 bytes .../images/slate/panel/corners-sprite.gif | Bin 0 -> 1384 bytes .../slate/images/slate/panel/left-right.gif | Bin 0 -> 807 bytes .../slate/images/slate/panel/light-hd.gif | Bin 0 -> 844 bytes .../images/slate/panel/tool-sprite-tpl.gif | Bin 0 -> 1197 bytes .../slate/images/slate/panel/tool-sprites.gif | Bin 0 -> 5787 bytes .../slate/panel/tools-sprites-trans.gif | Bin 0 -> 2640 bytes .../slate/images/slate/panel/top-bottom.gif | Bin 0 -> 870 bytes .../slate/images/slate/panel/top-bottom.png | Bin 0 -> 215 bytes .../slate/panel/white-corners-sprite.gif | Bin 0 -> 1365 bytes .../images/slate/panel/white-left-right.gif | Bin 0 -> 805 bytes .../images/slate/panel/white-top-bottom.gif | Bin 0 -> 864 bytes .../images/slate/progress/progress-bg.gif | Bin 0 -> 837 bytes .../gxt/themes/slate/images/slate/qtip/bg.gif | Bin 0 -> 1091 bytes .../themes/slate/images/slate/qtip/close.gif | Bin 0 -> 972 bytes .../slate/images/slate/qtip/tip-sprite.gif | Bin 0 -> 4129 bytes .../gxt/themes/slate/images/slate/s.gif | Bin 0 -> 43 bytes .../slate/images/slate/shared/glass-bg.gif | Bin 0 -> 865 bytes .../slate/images/slate/shared/hd-sprite.gif | Bin 0 -> 1099 bytes .../slate/images/slate/shared/left-btn.gif | Bin 0 -> 878 bytes .../slate/images/slate/shared/right-btn.gif | Bin 0 -> 879 bytes .../images/slate/sizer/e-handle-dark.gif | Bin 0 -> 1069 bytes .../slate/images/slate/sizer/e-handle.gif | Bin 0 -> 1599 bytes .../images/slate/sizer/ne-handle-dark.gif | Bin 0 -> 843 bytes .../slate/images/slate/sizer/ne-handle.gif | Bin 0 -> 839 bytes .../images/slate/sizer/nw-handle-dark.gif | Bin 0 -> 841 bytes .../slate/images/slate/sizer/nw-handle.gif | Bin 0 -> 839 bytes .../images/slate/sizer/s-handle-dark.gif | Bin 0 -> 1051 bytes .../slate/images/slate/sizer/s-handle.gif | Bin 0 -> 1311 bytes .../images/slate/sizer/se-handle-dark.gif | Bin 0 -> 844 bytes .../slate/images/slate/sizer/se-handle.gif | Bin 0 -> 838 bytes .../slate/images/slate/sizer/square.gif | Bin 0 -> 841 bytes .../images/slate/sizer/sw-handle-dark.gif | Bin 0 -> 844 bytes .../slate/images/slate/sizer/sw-handle.gif | Bin 0 -> 839 bytes .../slate/images/slate/slider/slider-bg.png | Bin 0 -> 1033 bytes .../images/slate/slider/slider-thumb.png | Bin 0 -> 1569 bytes .../slate/images/slate/slider/slider-v-bg.png | Bin 0 -> 1016 bytes .../images/slate/slider/slider-v-thumb.png | Bin 0 -> 1476 bytes .../slate/images/slate/tabs/scroll-left.gif | Bin 0 -> 1260 bytes .../slate/images/slate/tabs/scroll-right.gif | Bin 0 -> 1269 bytes .../slate/images/slate/tabs/scroller-bg.gif | Bin 0 -> 1090 bytes .../slate/tabs/tab-btm-inactive-left-bg.gif | Bin 0 -> 883 bytes .../slate/tabs/tab-btm-inactive-right-bg.gif | Bin 0 -> 1553 bytes .../images/slate/tabs/tab-btm-left-bg.gif | Bin 0 -> 888 bytes .../images/slate/tabs/tab-btm-right-bg.gif | Bin 0 -> 1586 bytes .../slate/images/slate/tabs/tab-close.gif | Bin 0 -> 853 bytes .../slate/images/slate/tabs/tab-strip-bg.gif | Bin 0 -> 906 bytes .../slate/images/slate/tabs/tab-strip-bg.png | Bin 0 -> 259 bytes .../images/slate/tabs/tab-strip-btm-bg.gif | Bin 0 -> 826 bytes .../slate/images/slate/tabs/tabs-sprite.gif | Bin 0 -> 2625 bytes .../themes/slate/images/slate/toolbar/bg.gif | Bin 0 -> 540 bytes .../images/slate/toolbar/btn-arrow-light.gif | Bin 0 -> 916 bytes .../slate/images/slate/toolbar/btn-arrow.gif | Bin 0 -> 908 bytes .../images/slate/toolbar/btn-over-bg.gif | Bin 0 -> 829 bytes .../slate/images/slate/toolbar/gray-bg.gif | Bin 0 -> 832 bytes .../themes/slate/images/slate/toolbar/sep.gif | Bin 0 -> 66 bytes .../slate/images/slate/toolbar/tb-bg.gif | Bin 0 -> 862 bytes .../images/slate/toolbar/tb-btn-sprite.gif | Bin 0 -> 1070 bytes .../themes/slate/images/slate/tree/arrows.gif | Bin 0 -> 1024 bytes .../slate/images/slate/window/icon-error.gif | Bin 0 -> 1669 bytes .../slate/images/slate/window/icon-info.gif | Bin 0 -> 1586 bytes .../images/slate/window/icon-question.gif | Bin 0 -> 1607 bytes .../images/slate/window/icon-warning.gif | Bin 0 -> 1483 bytes .../images/slate/window/left-corners.png | Bin 0 -> 432 bytes .../slate/images/slate/window/left-right.png | Bin 0 -> 160 bytes .../images/slate/window/right-corners.png | Bin 0 -> 459 bytes .../slate/images/slate/window/top-bottom.png | Bin 0 -> 294 bytes src/main/webapp/images/TimeSeries_bg.gif | Bin 0 -> 1268 bytes src/main/webapp/images/Title_bg.gif | Bin 0 -> 199 bytes src/main/webapp/images/arrow_enter.gif | Bin 0 -> 1622 bytes src/main/webapp/images/arrow_out.png | Bin 0 -> 594 bytes src/main/webapp/images/attribute_area.gif | Bin 0 -> 937 bytes src/main/webapp/images/biblio.jpg | Bin 0 -> 1117 bytes src/main/webapp/images/bin.gif | Bin 0 -> 1126 bytes src/main/webapp/images/body.jpg | Bin 0 -> 527 bytes src/main/webapp/images/book_load.gif | Bin 0 -> 16116 bytes src/main/webapp/images/close.gif | Bin 0 -> 1893 bytes src/main/webapp/images/close_darker.gif | Bin 0 -> 73 bytes src/main/webapp/images/comment.gif | Bin 0 -> 1599 bytes src/main/webapp/images/comment_area.gif | Bin 0 -> 932 bytes src/main/webapp/images/comment_gray.gif | Bin 0 -> 1396 bytes src/main/webapp/images/droppingImage.gif | Bin 0 -> 2374 bytes src/main/webapp/images/droppingImage_bg.gif | Bin 0 -> 408 bytes src/main/webapp/images/hborder.png | Bin 0 -> 1384 bytes src/main/webapp/images/header.jpg | Bin 0 -> 577 bytes src/main/webapp/images/heading_1.jpg | Bin 0 -> 675 bytes src/main/webapp/images/heading_1.png | Bin 0 -> 2941 bytes src/main/webapp/images/heading_2.jpg | Bin 0 -> 683 bytes src/main/webapp/images/heading_2.png | Bin 0 -> 2949 bytes src/main/webapp/images/heading_3.jpg | Bin 0 -> 662 bytes src/main/webapp/images/heading_3.png | Bin 0 -> 2951 bytes src/main/webapp/images/heading_4.png | Bin 0 -> 2953 bytes src/main/webapp/images/instruction_area.gif | Bin 0 -> 937 bytes src/main/webapp/images/loading-bar.gif | Bin 0 -> 10819 bytes src/main/webapp/images/loading2.gif | Bin 0 -> 6848 bytes src/main/webapp/images/lock_add.png | Bin 0 -> 1278 bytes src/main/webapp/images/lock_darker_add.png | Bin 0 -> 1274 bytes src/main/webapp/images/lock_darker_delete.png | Bin 0 -> 1293 bytes src/main/webapp/images/lock_delete.png | Bin 0 -> 1289 bytes src/main/webapp/images/next_big.gif | Bin 0 -> 1766 bytes src/main/webapp/images/next_p.gif | Bin 0 -> 1054 bytes src/main/webapp/images/organization_logo.jpg | Bin 0 -> 4407 bytes src/main/webapp/images/pagebreak.gif | Bin 0 -> 854 bytes src/main/webapp/images/prev_big.gif | Bin 0 -> 2262 bytes src/main/webapp/images/prev_p.gif | Bin 0 -> 652 bytes src/main/webapp/images/title.png | Bin 0 -> 3127 bytes src/main/webapp/images/title_area.png | Bin 0 -> 3127 bytes src/main/webapp/images/toc.jpg | Bin 0 -> 1602 bytes src/main/webapp/images/tour/tour1.jpg | Bin 0 -> 30338 bytes src/main/webapp/images/tour/tour2.jpg | Bin 0 -> 28314 bytes src/main/webapp/images/tour/tour4.jpg | Bin 0 -> 29889 bytes src/main/webapp/images/tour/tourBiblio.jpg | Bin 0 -> 24213 bytes src/main/webapp/images/tour/tourComment.jpg | Bin 0 -> 8426 bytes src/main/webapp/images/tour/tourExports.jpg | Bin 0 -> 19236 bytes src/main/webapp/images/tour/tourFormat.jpg | Bin 0 -> 18591 bytes .../ReportGeneratorJUnit.gwt.xml | 7 + 886 files changed, 25119 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/.jsdtscope create mode 100644 .settings/com.google.appengine.eclipse.core.prefs create mode 100644 .settings/com.google.gdt.eclipse.core.prefs create mode 100644 .settings/com.google.gwt.eclipse.core.prefs create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .settings/org.eclipse.wst.common.component create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.container create mode 100644 .settings/org.maven.ide.eclipse.prefs create mode 100644 ReportGeneratorTest-dev.launch create mode 100644 ReportGeneratorTest-prod.launch create mode 100644 distro/INSTALL create mode 100644 distro/LICENSE create mode 100644 distro/MAINTAINERS create mode 100644 distro/README create mode 100644 distro/changelog.xml create mode 100644 distro/descriptor.xml create mode 100644 distro/profile.xml create mode 100644 distro/svnpath.txt create mode 100644 pom.xml create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/Headerbar.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/CommonCommands.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/Presenter.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportConstants.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportGenerator.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportService.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportServiceAsync.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/TitleBar.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/ToolboxPanel.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/WorkspacePanel.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/components/FancyFileUpload.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/AddBiblioEntryDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/CommentDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/DeleteCitationsDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/FimesReportTreePanel.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImageUploaderDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImporterDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/LoadingPopup.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/PagePropertiesDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TSHeader.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesFilter.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesSampleDialog.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEvent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEventHandler.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/model/ExportManifestationType.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateComponent.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateModel.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateSection.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/FimesReportTreeStructureResources.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/comments.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/image.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/information.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/page.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/report.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/table.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_dropcaps.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_1.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_2.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_3.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_4.png create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/AttributeArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/BasicTextArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/Coords.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/D4sRichTextarea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DoubleColumnPanel.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropImageListener.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropTSListener.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DroppingArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenTableCell.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenericTable.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ImageArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ReportTextArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/TSArea.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.ui.xml create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/portlet/ReportGeneratorPortlet.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/DocLibraryUtil.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ImagesUploadServlet.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ReportServiceImpl.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ZipUtil.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/CreateReportLogEntry.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/GenerateReportLogEntry.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenReportLogEntry.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenWorkflowLogEntry.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/SaveWorkflowLogEntry.java create mode 100644 src/main/java/org/gcube/portlets/user/reportgenerator/shared/SessionInfo.java create mode 100644 src/main/resources/org/gcube/portlets/user/reportgenerator/ReportGenerator.gwt.xml create mode 100644 src/main/webapp/ReportGenerator.css create mode 100644 src/main/webapp/ReportGenerator.html create mode 100644 src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_edit.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_help.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_view.jsp create mode 100644 src/main/webapp/WEB-INF/liferay-display.xml create mode 100644 src/main/webapp/WEB-INF/liferay-plugin-package.properties create mode 100644 src/main/webapp/WEB-INF/liferay-portlet.xml create mode 100644 src/main/webapp/WEB-INF/portlet.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/gxt/css/gxt-all.css create mode 100644 src/main/webapp/gxt/css/gxt-gray.css create mode 100644 src/main/webapp/gxt/desktop/css/desktop.css create mode 100644 src/main/webapp/gxt/desktop/images/desktop.gif create mode 100644 src/main/webapp/gxt/desktop/images/desktop3.jpg create mode 100644 src/main/webapp/gxt/desktop/images/gears.gif create mode 100644 src/main/webapp/gxt/desktop/images/gears.png create mode 100644 src/main/webapp/gxt/desktop/images/grid.png create mode 100644 src/main/webapp/gxt/desktop/images/hatch.gif create mode 100644 src/main/webapp/gxt/desktop/images/hd-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/hd-tb-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/icon_padlock.png create mode 100644 src/main/webapp/gxt/desktop/images/icons-bg.png create mode 100644 src/main/webapp/gxt/desktop/images/launcher-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/launcher-btn.gif create mode 100644 src/main/webapp/gxt/desktop/images/logout.gif create mode 100644 src/main/webapp/gxt/desktop/images/logout.png create mode 100644 src/main/webapp/gxt/desktop/images/member.gif create mode 100644 src/main/webapp/gxt/desktop/images/member.png create mode 100644 src/main/webapp/gxt/desktop/images/powered.gif create mode 100644 src/main/webapp/gxt/desktop/images/powered.png create mode 100644 src/main/webapp/gxt/desktop/images/s.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/item-over.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/scroll-left.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/scroll-right.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-left-corners.png create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-left-right.png create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right-corners.png create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right.png create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-top-bottom.png create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/startbutton-icon.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/startbutton.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/taskbar-split-h.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/taskbar-start-panel-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/taskbutton.gif create mode 100644 src/main/webapp/gxt/desktop/images/taskbar/black/taskbuttons-panel-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/winbar-bg.gif create mode 100644 src/main/webapp/gxt/desktop/images/winbar-btn.gif create mode 100644 src/main/webapp/gxt/desktop/images/windows-bg.gif create mode 100644 src/main/webapp/gxt/desktop/wallpapers/desktop.jpg create mode 100644 src/main/webapp/gxt/flash/swfobject.js create mode 100644 src/main/webapp/gxt/images/default/box/corners-blue.gif create mode 100644 src/main/webapp/gxt/images/default/box/corners.gif create mode 100644 src/main/webapp/gxt/images/default/box/l-blue.gif create mode 100644 src/main/webapp/gxt/images/default/box/l.gif create mode 100644 src/main/webapp/gxt/images/default/box/r-blue.gif create mode 100644 src/main/webapp/gxt/images/default/box/r.gif create mode 100644 src/main/webapp/gxt/images/default/box/tb-blue.gif create mode 100644 src/main/webapp/gxt/images/default/box/tb.gif create mode 100644 src/main/webapp/gxt/images/default/button/arrow.gif create mode 100644 src/main/webapp/gxt/images/default/button/btn-arrow.gif create mode 100644 src/main/webapp/gxt/images/default/button/btn-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/button/btn.gif create mode 100644 src/main/webapp/gxt/images/default/button/group-cs.gif create mode 100644 src/main/webapp/gxt/images/default/button/group-lr.gif create mode 100644 src/main/webapp/gxt/images/default/button/group-tb.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow-b-noline.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow-b.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow-bo.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow-noline.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow-o.gif create mode 100644 src/main/webapp/gxt/images/default/button/s-arrow.gif create mode 100644 src/main/webapp/gxt/images/default/dd/drop-add.gif create mode 100644 src/main/webapp/gxt/images/default/dd/drop-no.gif create mode 100644 src/main/webapp/gxt/images/default/dd/drop-yes.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-bold.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-font-color.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-font-decrease.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-font-highlight.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-font-increase.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-italic.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-justify-center.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-justify-left.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-justify-right.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-link.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-ol.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-source.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-ul.gif create mode 100644 src/main/webapp/gxt/images/default/editor/tb-underline.gif create mode 100644 src/main/webapp/gxt/images/default/form/checkbox.gif create mode 100644 src/main/webapp/gxt/images/default/form/clear-trigger.gif create mode 100644 src/main/webapp/gxt/images/default/form/date-trigger.gif create mode 100644 src/main/webapp/gxt/images/default/form/error-tip-corners.gif create mode 100644 src/main/webapp/gxt/images/default/form/exclamation.gif create mode 100644 src/main/webapp/gxt/images/default/form/radio.gif create mode 100644 src/main/webapp/gxt/images/default/form/search-trigger.gif create mode 100644 src/main/webapp/gxt/images/default/form/spinner.gif create mode 100644 src/main/webapp/gxt/images/default/form/text-bg.gif create mode 100644 src/main/webapp/gxt/images/default/form/trigger-tpl.gif create mode 100644 src/main/webapp/gxt/images/default/form/trigger.gif create mode 100644 src/main/webapp/gxt/images/default/gradient-bg.gif create mode 100644 src/main/webapp/gxt/images/default/grid/arrow-left-white.gif create mode 100644 src/main/webapp/gxt/images/default/grid/arrow-right-white.gif create mode 100644 src/main/webapp/gxt/images/default/grid/col-move-bottom.gif create mode 100644 src/main/webapp/gxt/images/default/grid/col-move-top.gif create mode 100644 src/main/webapp/gxt/images/default/grid/columns.gif create mode 100644 src/main/webapp/gxt/images/default/grid/dirty.gif create mode 100644 src/main/webapp/gxt/images/default/grid/done.gif create mode 100644 src/main/webapp/gxt/images/default/grid/drop-no.gif create mode 100644 src/main/webapp/gxt/images/default/grid/drop-yes.gif create mode 100644 src/main/webapp/gxt/images/default/grid/footer-bg.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-blue-hd.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-blue-split.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-hrow.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-loading.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-split.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid-vista-hd.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-hd-btn.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-hrow-group.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-hrow-over.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-hrow.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-special-col-bg.gif create mode 100644 src/main/webapp/gxt/images/default/grid/grid3-special-col-sel-bg.gif create mode 100644 src/main/webapp/gxt/images/default/grid/group-by.gif create mode 100644 src/main/webapp/gxt/images/default/grid/group-expand-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hd-pop.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-asc.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-desc.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-lock.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-lock.png create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-unlock.gif create mode 100644 src/main/webapp/gxt/images/default/grid/hmenu-unlock.png create mode 100644 src/main/webapp/gxt/images/default/grid/invalid_line.gif create mode 100644 src/main/webapp/gxt/images/default/grid/loading.gif create mode 100644 src/main/webapp/gxt/images/default/grid/mso-hd.gif create mode 100644 src/main/webapp/gxt/images/default/grid/nowait.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-first-disabled.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-first.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-last-disabled.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-last.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-next-disabled.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-next.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-prev-disabled.gif create mode 100644 src/main/webapp/gxt/images/default/grid/page-prev.gif create mode 100644 src/main/webapp/gxt/images/default/grid/pick-button.gif create mode 100644 src/main/webapp/gxt/images/default/grid/refresh.gif create mode 100644 src/main/webapp/gxt/images/default/grid/refresh.png create mode 100644 src/main/webapp/gxt/images/default/grid/row-check-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/grid/row-expand-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/grid/row-over.gif create mode 100644 src/main/webapp/gxt/images/default/grid/row-sel.gif create mode 100644 src/main/webapp/gxt/images/default/grid/sort-hd.gif create mode 100644 src/main/webapp/gxt/images/default/grid/sort_asc.gif create mode 100644 src/main/webapp/gxt/images/default/grid/sort_desc.gif create mode 100644 src/main/webapp/gxt/images/default/grid/wait.gif create mode 100644 src/main/webapp/gxt/images/default/layout/collapse.gif create mode 100644 src/main/webapp/gxt/images/default/layout/expand.gif create mode 100644 src/main/webapp/gxt/images/default/layout/gradient-bg.gif create mode 100644 src/main/webapp/gxt/images/default/layout/mini-bottom.gif create mode 100644 src/main/webapp/gxt/images/default/layout/mini-left.gif create mode 100644 src/main/webapp/gxt/images/default/layout/mini-right.gif create mode 100644 src/main/webapp/gxt/images/default/layout/mini-top.gif create mode 100644 src/main/webapp/gxt/images/default/layout/ns-collapse.gif create mode 100644 src/main/webapp/gxt/images/default/layout/ns-expand.gif create mode 100644 src/main/webapp/gxt/images/default/layout/panel-close.gif create mode 100644 src/main/webapp/gxt/images/default/layout/panel-title-bg.gif create mode 100644 src/main/webapp/gxt/images/default/layout/panel-title-light-bg.gif create mode 100644 src/main/webapp/gxt/images/default/layout/stick.gif create mode 100644 src/main/webapp/gxt/images/default/layout/stuck.gif create mode 100644 src/main/webapp/gxt/images/default/layout/tab-close-on.gif create mode 100644 src/main/webapp/gxt/images/default/layout/tab-close.gif create mode 100644 src/main/webapp/gxt/images/default/menu/checked.gif create mode 100644 src/main/webapp/gxt/images/default/menu/group-checked.gif create mode 100644 src/main/webapp/gxt/images/default/menu/item-over.gif create mode 100644 src/main/webapp/gxt/images/default/menu/menu-parent.gif create mode 100644 src/main/webapp/gxt/images/default/menu/menu.gif create mode 100644 src/main/webapp/gxt/images/default/menu/unchecked.gif create mode 100644 src/main/webapp/gxt/images/default/panel/corners-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/panel/left-right.gif create mode 100644 src/main/webapp/gxt/images/default/panel/light-hd.gif create mode 100644 src/main/webapp/gxt/images/default/panel/tool-sprite-tpl.gif create mode 100644 src/main/webapp/gxt/images/default/panel/tool-sprites.gif create mode 100644 src/main/webapp/gxt/images/default/panel/tools-sprites-trans.gif create mode 100644 src/main/webapp/gxt/images/default/panel/top-bottom.gif create mode 100644 src/main/webapp/gxt/images/default/panel/top-bottom.png create mode 100644 src/main/webapp/gxt/images/default/panel/white-corners-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/panel/white-left-right.gif create mode 100644 src/main/webapp/gxt/images/default/panel/white-top-bottom.gif create mode 100644 src/main/webapp/gxt/images/default/progress/progress-bg.gif create mode 100644 src/main/webapp/gxt/images/default/qtip/bg.gif create mode 100644 src/main/webapp/gxt/images/default/qtip/close.gif create mode 100644 src/main/webapp/gxt/images/default/qtip/tip-anchor-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/qtip/tip-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/s.gif create mode 100644 src/main/webapp/gxt/images/default/shadow-c.png create mode 100644 src/main/webapp/gxt/images/default/shadow-lr.png create mode 100644 src/main/webapp/gxt/images/default/shadow.png create mode 100644 src/main/webapp/gxt/images/default/shared/blue-loading.gif create mode 100644 src/main/webapp/gxt/images/default/shared/calendar.gif create mode 100644 src/main/webapp/gxt/images/default/shared/clear.gif create mode 100644 src/main/webapp/gxt/images/default/shared/glass-bg.gif create mode 100644 src/main/webapp/gxt/images/default/shared/hd-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/shared/large-loading.gif create mode 100644 src/main/webapp/gxt/images/default/shared/left-btn.gif create mode 100644 src/main/webapp/gxt/images/default/shared/loading-balls.gif create mode 100644 src/main/webapp/gxt/images/default/shared/right-btn.gif create mode 100644 src/main/webapp/gxt/images/default/shared/warning.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/e-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/e-handle.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/ne-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/ne-handle.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/nw-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/nw-handle.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/s-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/s-handle.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/se-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/se-handle.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/square.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/sw-handle-dark.gif create mode 100644 src/main/webapp/gxt/images/default/sizer/sw-handle.gif create mode 100644 src/main/webapp/gxt/images/default/slider/slider-bg.png create mode 100644 src/main/webapp/gxt/images/default/slider/slider-thumb.png create mode 100644 src/main/webapp/gxt/images/default/slider/slider-v-bg.png create mode 100644 src/main/webapp/gxt/images/default/slider/slider-v-thumb.png create mode 100644 src/main/webapp/gxt/images/default/tabs/scroll-left.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/scroll-right.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/scroller-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-btm-inactive-left-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-btm-inactive-right-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-btm-left-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-btm-right-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-close.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-strip-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-strip-bg.png create mode 100644 src/main/webapp/gxt/images/default/tabs/tab-strip-btm-bg.gif create mode 100644 src/main/webapp/gxt/images/default/tabs/tabs-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/bg.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/btn-arrow-light.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/btn-arrow.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/btn-over-bg.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/gray-bg.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/more.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/tb-bg.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/tb-btn-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/tb-xl-btn-sprite.gif create mode 100644 src/main/webapp/gxt/images/default/toolbar/tb-xl-sep.gif create mode 100644 src/main/webapp/gxt/images/default/tree/arrows.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-add.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-between.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-no.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-over.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-under.gif create mode 100644 src/main/webapp/gxt/images/default/tree/drop-yes.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-end-minus-nl.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-end-minus.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-end-plus-nl.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-end-plus.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-end.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-line.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-minus-nl.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-minus.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-plus-nl.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow-plus.gif create mode 100644 src/main/webapp/gxt/images/default/tree/elbow.gif create mode 100644 src/main/webapp/gxt/images/default/tree/folder-open.gif create mode 100644 src/main/webapp/gxt/images/default/tree/folder.gif create mode 100644 src/main/webapp/gxt/images/default/tree/leaf.gif create mode 100644 src/main/webapp/gxt/images/default/tree/loading.gif create mode 100644 src/main/webapp/gxt/images/default/tree/s.gif create mode 100644 src/main/webapp/gxt/images/default/window/icon-error.gif create mode 100644 src/main/webapp/gxt/images/default/window/icon-info.gif create mode 100644 src/main/webapp/gxt/images/default/window/icon-question.gif create mode 100644 src/main/webapp/gxt/images/default/window/icon-warning.gif create mode 100644 src/main/webapp/gxt/images/default/window/left-corners.png create mode 100644 src/main/webapp/gxt/images/default/window/left-right.png create mode 100644 src/main/webapp/gxt/images/default/window/right-corners.png create mode 100644 src/main/webapp/gxt/images/default/window/top-bottom.png create mode 100644 src/main/webapp/gxt/images/gray/button/btn-arrow.gif create mode 100644 src/main/webapp/gxt/images/gray/button/btn-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/button/btn.gif create mode 100644 src/main/webapp/gxt/images/gray/button/group-cs.gif create mode 100644 src/main/webapp/gxt/images/gray/button/group-lr.gif create mode 100644 src/main/webapp/gxt/images/gray/button/group-tb.gif create mode 100644 src/main/webapp/gxt/images/gray/form/spinner.gif create mode 100644 src/main/webapp/gxt/images/gray/gradient-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/col-move-bottom.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/col-move-top.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid-split.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-hd-btn.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-hrow-over.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-hrow-over2.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-hrow.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-hrow2.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-special-col-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-special-col-bg2.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/grid3-special-col-sel-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/group-collapse.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/group-expand-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/group-expand.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/page-first.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/page-last.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/page-next.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/page-prev.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/refresh.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/row-expand-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/sort_asc.gif create mode 100644 src/main/webapp/gxt/images/gray/grid/sort_desc.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/corners-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/left-right.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/light-hd.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/tool-sprite-tpl.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/tool-sprites.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/tools-sprites-trans.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/top-bottom.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/top-bottom.png create mode 100644 src/main/webapp/gxt/images/gray/panel/white-corners-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/white-left-right.gif create mode 100644 src/main/webapp/gxt/images/gray/panel/white-top-bottom.gif create mode 100644 src/main/webapp/gxt/images/gray/qtip/bg.gif create mode 100644 src/main/webapp/gxt/images/gray/qtip/close.gif create mode 100644 src/main/webapp/gxt/images/gray/qtip/tip-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/s.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/scroll-left.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/scroll-right.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/scroller-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-btm-inactive-left-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-btm-inactive-right-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-btm-left-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-btm-right-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-close.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-strip-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-strip-bg.png create mode 100644 src/main/webapp/gxt/images/gray/tabs/tab-strip-btm-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/tabs/tabs-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/bg.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/btn-arrow-light.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/btn-arrow.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/btn-over-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/gray-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/tb-bg.gif create mode 100644 src/main/webapp/gxt/images/gray/toolbar/tb-btn-sprite.gif create mode 100644 src/main/webapp/gxt/images/gray/window/icon-error.gif create mode 100644 src/main/webapp/gxt/images/gray/window/icon-info.gif create mode 100644 src/main/webapp/gxt/images/gray/window/icon-question.gif create mode 100644 src/main/webapp/gxt/images/gray/window/icon-warning.gif create mode 100644 src/main/webapp/gxt/images/gray/window/left-corners.png create mode 100644 src/main/webapp/gxt/images/gray/window/left-corners.pspimage create mode 100644 src/main/webapp/gxt/images/gray/window/left-right.png create mode 100644 src/main/webapp/gxt/images/gray/window/right-corners.png create mode 100644 src/main/webapp/gxt/images/gray/window/top-bottom.png create mode 100644 src/main/webapp/gxt/images/gxt/dd/insert-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/grid/row-editor-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/grid/row-editor-btns.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/bottom2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/columns.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/done.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/doubleleft2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/doubleright2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/down2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/folder-closed.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/folder-closed.png create mode 100644 src/main/webapp/gxt/images/gxt/icons/folder.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/folder.png create mode 100644 src/main/webapp/gxt/images/gxt/icons/grid-loading.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/hmenu-asc.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/hmenu-desc.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/left2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/loading.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/nowait.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-first-disabled.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-first.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-last-disabled.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-last.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-next-disabled.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-next.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-prev-disabled.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/page-prev.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/paging.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/right2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/tabs.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/top2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/up2.gif create mode 100644 src/main/webapp/gxt/images/gxt/icons/wait.gif create mode 100644 src/main/webapp/gxt/images/gxt/info/corners-sprite.gif create mode 100644 src/main/webapp/gxt/images/gxt/info/top-bottom.gif create mode 100644 src/main/webapp/gxt/images/gxt/menu/disabledcheck.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/clear.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/large-loading.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/select-18-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/select-19-bg-gray.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/select-19-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/select-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/shared/select-light.gif create mode 100644 src/main/webapp/gxt/images/gxt/table/row-over.gif create mode 100644 src/main/webapp/gxt/images/gxt/table/vs-column-bg.gif create mode 100644 src/main/webapp/gxt/images/gxt/table/vsort-asc.gif create mode 100644 src/main/webapp/gxt/images/gxt/table/vsort-desc.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/checked.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/joint-close.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/joint-open.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/notchecked.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/tree-table-special-col-sel.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/tree-table-special-col.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/vnode.gif create mode 100644 src/main/webapp/gxt/images/gxt/tree/vnode_transparent.gif create mode 100644 src/main/webapp/gxt/themes/access/css/xtheme-access.css create mode 100644 src/main/webapp/gxt/themes/access/images/box/corners-blue.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/corners.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/l-blue.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/l.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/r-blue.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/r.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/tb-blue.gif create mode 100644 src/main/webapp/gxt/themes/access/images/box/tb.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/arrow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/btn.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/group-cs.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/group-lr.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/group-tb.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow-b-noline.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow-b.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow-bo.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow-noline.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow-o.gif create mode 100644 src/main/webapp/gxt/themes/access/images/button/s-arrow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/editor/tb-source.gif create mode 100644 src/main/webapp/gxt/themes/access/images/editor/tb-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/checkbox.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/clear-trigger.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/date-trigger.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/error-tip-corners.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/exclamation.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/radio.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/search-trigger.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/spinner.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/text-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/trigger-single.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/trigger-tpl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/form/trigger.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/arrow-left-white.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/arrow-right-white.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/col-move-bottom.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/col-move-top.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/columns.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/dirty.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/done.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/drop-no.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/drop-yes.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/footer-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-blue-hd.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-blue-split.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-hrow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-loading.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-split.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid-vista-hd.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-hd-btn-contrast.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-hd-btn.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-hrow-over.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-hrow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-special-col-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/grid3-special-col-sel-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/group-by.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/group-collapse.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/group-expand-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/group-expand.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hd-pop.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-asc.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-desc.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-lock.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-lock.png create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-unlock.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/hmenu-unlock.png create mode 100644 src/main/webapp/gxt/themes/access/images/grid/invalid_line.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/loading.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/mso-hd.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/nowait.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-first-disabled.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-first.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-last-disabled.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-last.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-next-disabled.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-next.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-prev-disabled.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/page-prev.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/pick-button.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/refresh.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-check-sel.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-check-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-check.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-expand-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-over.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/row-sel.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/sort-hd.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/sort_asc.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/sort_desc.gif create mode 100644 src/main/webapp/gxt/themes/access/images/grid/wait.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/bottom2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/doubleleft2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/doubleright2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/down2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/left2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/right2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/top2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/icons/up2.gif create mode 100644 src/main/webapp/gxt/themes/access/images/layout/mini-bottom.gif create mode 100644 src/main/webapp/gxt/themes/access/images/layout/mini-top.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/checked.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/group-checked.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/item-over.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/menu-parent.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/menu.gif create mode 100644 src/main/webapp/gxt/themes/access/images/menu/unchecked.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/corners-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/left-right.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/light-hd.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-close.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-collapse.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-expand.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-gear.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-maximize.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-minimize.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-pin.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-sprite-tpl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tool-sprites.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/tools-sprites-trans.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/top-bottom.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/white-corners-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/white-left-right.gif create mode 100644 src/main/webapp/gxt/themes/access/images/panel/white-top-bottom.gif create mode 100644 src/main/webapp/gxt/themes/access/images/progress/progress-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/qtip/close.gif create mode 100644 src/main/webapp/gxt/themes/access/images/qtip/tip-anchor-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/qtip/tip-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/shared/glass-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/shared/hd-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/shared/left-btn.gif create mode 100644 src/main/webapp/gxt/themes/access/images/shared/right-btn.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/e-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/e-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/ne-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/ne-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/nw-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/nw-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/s-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/s-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/se-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/se-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/square.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/sw-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/access/images/sizer/sw-handle.gif create mode 100644 src/main/webapp/gxt/themes/access/images/slider/slider-bg.png create mode 100644 src/main/webapp/gxt/themes/access/images/slider/slider-thumb-single.png create mode 100644 src/main/webapp/gxt/themes/access/images/slider/slider-thumb.png create mode 100644 src/main/webapp/gxt/themes/access/images/slider/slider-v-bg.png create mode 100644 src/main/webapp/gxt/themes/access/images/slider/slider-v-thumb.png create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/scroll-left.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/scroll-right.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-btm-inactive-left-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-btm-inactive-right-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-btm-left-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-btm-right-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-close.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-strip-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tab-strip-btm-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tabs/tabs-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/btn-arrow-light.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/btn-arrow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/btn-over-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/gray-bg.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/more.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/s-arrow-bo.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/tb-btn-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/tb-xl-btn-sprite.gif create mode 100644 src/main/webapp/gxt/themes/access/images/toolbar/tb-xl-sep.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/arrows.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-add.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-between.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-no.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-over.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-under.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/drop-yes.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-end-minus-nl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-end-minus.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-end-plus-nl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-end-plus.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-end.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-line.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-minus-nl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-minus.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-plus-nl.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow-plus.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/elbow.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/folder-open.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/folder.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/leaf.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/loading.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/s.gif create mode 100644 src/main/webapp/gxt/themes/access/images/tree/tree-collapsed.png create mode 100644 src/main/webapp/gxt/themes/access/images/tree/tree-expanded.png create mode 100644 src/main/webapp/gxt/themes/access/images/window/icon-error.gif create mode 100644 src/main/webapp/gxt/themes/access/images/window/icon-info.gif create mode 100644 src/main/webapp/gxt/themes/access/images/window/icon-question.gif create mode 100644 src/main/webapp/gxt/themes/access/images/window/icon-warning.gif create mode 100644 src/main/webapp/gxt/themes/access/images/window/left-corners.png create mode 100644 src/main/webapp/gxt/themes/access/images/window/left-right.png create mode 100644 src/main/webapp/gxt/themes/access/images/window/right-corners.png create mode 100644 src/main/webapp/gxt/themes/access/images/window/top-bottom.png create mode 100644 src/main/webapp/gxt/themes/slate/css/xtheme-slate.css create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/arrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/btn-arrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/btn-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/btn.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/group-cs.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/group-lr.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/group-tb.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow-b-noline.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow-b.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow-bo.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow-noline.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow-o.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/button/s-arrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/editor/tb-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/checkbox.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/clear-trigger.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/date-trigger.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/error-tip-corners.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/radio.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/search-trigger.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/spinner.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/trigger-tpl.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/form/trigger.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/gradient-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/arrow-left-white.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/arrow-right-white.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/col-move-bottom.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/col-move-top.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/footer-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid-blue-hd.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid-blue-split.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid-hrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid-split.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid-vista-hd.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid3-hd-btn.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid3-hrow-over.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid3-hrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid3-special-col-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/grid3-special-col-sel-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/group-expand-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/mso-hd.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-first-disabled.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-first.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-last-disabled.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-last.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-next-disabled.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-next.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-prev-disabled.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/page-prev.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/refresh.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/row-over.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/row-sel.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/sort_asc.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/grid/sort_desc.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/checked.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/group-checked.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/item-over - Copy.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/item-over.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/menu-parent.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/menu.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/menu/unchecked.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/corners-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/left-right.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/light-hd.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/tool-sprite-tpl.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/tool-sprites.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/tools-sprites-trans.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/top-bottom.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/top-bottom.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/white-corners-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/white-left-right.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/panel/white-top-bottom.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/progress/progress-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/qtip/bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/qtip/close.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/qtip/tip-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/s.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/shared/glass-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/shared/hd-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/shared/left-btn.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/shared/right-btn.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/e-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/e-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/ne-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/ne-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/nw-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/nw-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/s-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/s-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/se-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/se-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/square.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/sw-handle-dark.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/sizer/sw-handle.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/slider/slider-bg.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/slider/slider-thumb.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/slider/slider-v-bg.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/slider/slider-v-thumb.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/scroll-left.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/scroll-right.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/scroller-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-btm-inactive-left-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-btm-inactive-right-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-btm-left-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-btm-right-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-close.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-strip-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-strip-bg.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tab-strip-btm-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tabs/tabs-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/btn-arrow-light.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/btn-arrow.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/btn-over-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/gray-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/sep.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/tb-bg.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/toolbar/tb-btn-sprite.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/tree/arrows.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/icon-error.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/icon-info.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/icon-question.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/icon-warning.gif create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/left-corners.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/left-right.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/right-corners.png create mode 100644 src/main/webapp/gxt/themes/slate/images/slate/window/top-bottom.png create mode 100644 src/main/webapp/images/TimeSeries_bg.gif create mode 100644 src/main/webapp/images/Title_bg.gif create mode 100644 src/main/webapp/images/arrow_enter.gif create mode 100644 src/main/webapp/images/arrow_out.png create mode 100644 src/main/webapp/images/attribute_area.gif create mode 100644 src/main/webapp/images/biblio.jpg create mode 100644 src/main/webapp/images/bin.gif create mode 100644 src/main/webapp/images/body.jpg create mode 100644 src/main/webapp/images/book_load.gif create mode 100644 src/main/webapp/images/close.gif create mode 100644 src/main/webapp/images/close_darker.gif create mode 100644 src/main/webapp/images/comment.gif create mode 100644 src/main/webapp/images/comment_area.gif create mode 100644 src/main/webapp/images/comment_gray.gif create mode 100644 src/main/webapp/images/droppingImage.gif create mode 100644 src/main/webapp/images/droppingImage_bg.gif create mode 100644 src/main/webapp/images/hborder.png create mode 100644 src/main/webapp/images/header.jpg create mode 100644 src/main/webapp/images/heading_1.jpg create mode 100644 src/main/webapp/images/heading_1.png create mode 100644 src/main/webapp/images/heading_2.jpg create mode 100644 src/main/webapp/images/heading_2.png create mode 100644 src/main/webapp/images/heading_3.jpg create mode 100644 src/main/webapp/images/heading_3.png create mode 100644 src/main/webapp/images/heading_4.png create mode 100644 src/main/webapp/images/instruction_area.gif create mode 100644 src/main/webapp/images/loading-bar.gif create mode 100644 src/main/webapp/images/loading2.gif create mode 100644 src/main/webapp/images/lock_add.png create mode 100644 src/main/webapp/images/lock_darker_add.png create mode 100644 src/main/webapp/images/lock_darker_delete.png create mode 100644 src/main/webapp/images/lock_delete.png create mode 100644 src/main/webapp/images/next_big.gif create mode 100644 src/main/webapp/images/next_p.gif create mode 100644 src/main/webapp/images/organization_logo.jpg create mode 100644 src/main/webapp/images/pagebreak.gif create mode 100644 src/main/webapp/images/prev_big.gif create mode 100644 src/main/webapp/images/prev_p.gif create mode 100644 src/main/webapp/images/title.png create mode 100644 src/main/webapp/images/title_area.png create mode 100644 src/main/webapp/images/toc.jpg create mode 100644 src/main/webapp/images/tour/tour1.jpg create mode 100644 src/main/webapp/images/tour/tour2.jpg create mode 100644 src/main/webapp/images/tour/tour4.jpg create mode 100644 src/main/webapp/images/tour/tourBiblio.jpg create mode 100644 src/main/webapp/images/tour/tourComment.jpg create mode 100644 src/main/webapp/images/tour/tourExports.jpg create mode 100644 src/main/webapp/images/tour/tourFormat.jpg create mode 100644 src/test/resources/org/gcube/portlets/user/reportgenerator/ReportGeneratorJUnit.gwt.xml diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..e68d666 --- /dev/null +++ b/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..39b0165 --- /dev/null +++ b/.project @@ -0,0 +1,59 @@ + + + reports + reports project + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + com.google.gdt.eclipse.core.webAppProjectValidator + + + + + com.google.gwt.eclipse.core.gwtProjectValidator + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + com.google.gwt.eclipse.core.gwtNature + + diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope new file mode 100644 index 0000000..ba3c245 --- /dev/null +++ b/.settings/.jsdtscope @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/.settings/com.google.appengine.eclipse.core.prefs b/.settings/com.google.appengine.eclipse.core.prefs new file mode 100644 index 0000000..a60576c --- /dev/null +++ b/.settings/com.google.appengine.eclipse.core.prefs @@ -0,0 +1,3 @@ +#Thu Jun 16 10:18:26 CEST 2011 +eclipse.preferences.version=1 +filesCopiedToWebInfLib= diff --git a/.settings/com.google.gdt.eclipse.core.prefs b/.settings/com.google.gdt.eclipse.core.prefs new file mode 100644 index 0000000..c8ef83a --- /dev/null +++ b/.settings/com.google.gdt.eclipse.core.prefs @@ -0,0 +1,6 @@ +#Wed Feb 06 12:30:01 CET 2013 +eclipse.preferences.version=1 +jarsExcludedFromWebInfLib= +lastWarOutDir=/Users/massi/Documents/workspace/reports/target/reports-4.0.0-SNAPSHOT +warSrcDir=src/main/webapp +warSrcDirIsOutput=false diff --git a/.settings/com.google.gwt.eclipse.core.prefs b/.settings/com.google.gwt.eclipse.core.prefs new file mode 100644 index 0000000..c803c44 --- /dev/null +++ b/.settings/com.google.gwt.eclipse.core.prefs @@ -0,0 +1,5 @@ +#Thu Jun 16 11:14:17 CEST 2011 +eclipse.preferences.version=1 +entryPointModules= +filesCopiedToWebInfLib=gwt-servlet.jar +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgc3JjL21haW4vd2ViYXBwXV0+PC9leHRyYS1hcmdzPjx2bS1hcmdzPjwhW0NEQVRBWy1YbXg1MTJtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLmNvbXBhbnkuU29tZU1vZHVsZTwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+ diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..0a6af5e --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,7 @@ +#Wed Feb 06 12:30:01 CET 2013 +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..649e327 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +#Wed Feb 06 16:46:46 CET 2013 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..226ace2 --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,5 @@ +#Wed Feb 06 12:30:01 CET 2013 +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..3fa2417 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,14 @@ + + + + + + + + + uses + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..5e7f92e --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/.settings/org.maven.ide.eclipse.prefs b/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 0000000..c74c58e --- /dev/null +++ b/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Thu Sep 02 10:42:12 CEST 2010 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/ReportGeneratorTest-dev.launch b/ReportGeneratorTest-dev.launch new file mode 100644 index 0000000..04c6d1d --- /dev/null +++ b/ReportGeneratorTest-dev.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/ReportGeneratorTest-prod.launch b/ReportGeneratorTest-prod.launch new file mode 100644 index 0000000..b9f63f9 --- /dev/null +++ b/ReportGeneratorTest-prod.launch @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/distro/INSTALL b/distro/INSTALL new file mode 100644 index 0000000..50f1ea7 --- /dev/null +++ b/distro/INSTALL @@ -0,0 +1,8 @@ +To install the Template Creator portlet you need the following requirements: + + * The Portlet WAR. + * The Dependecies JARs as declared in the Service Profile. + +First of all you need a Portal properly configured and running. + + diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..630ba97 --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,6 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS new file mode 100644 index 0000000..ffed162 --- /dev/null +++ b/distro/MAINTAINERS @@ -0,0 +1,5 @@ +Mantainers +------- + +* Massimiliano Assante (massimiliano.assante@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..4da1049 --- /dev/null +++ b/distro/README @@ -0,0 +1,55 @@ +The gCube System - Template Creator portlet +------------------------------------------------------------ + +This work has been partially supported by the following European projects: +DILIGENT (FP6-2003-IST-2), D4Science (FP7-INFRA-2007-1.2.2), D4Science-II (FP7-INFRA-2008-1.2.2), +iMarine (FP7-INFRASTRUCTURES-2011-2), and EUBrazilOpenBio (FP7-ICT-2011-EU-Brazil). + + + +Authors +------- + +* Massimiliano Assante (massimiliano.assante@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". + + +Version and Release Date +------------------------ + +v. 1.0.0, 15/12/2008 + + +Description +----------- + + + +Download information +-------------------- + +Source code is available from SVN: +http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/ReportGenerator-portlet + + +Binaries can be downloaded from: +http://software.d4science.research-infrastructures.eu/ + + +Documentation +------------- + +Documentation is available on-line from the Projects Documentation Wiki: + +https://gcube.wiki.gcube-system.org/gcube/index.php/Common_Functionality#Report_Generation + + + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. + + + + diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..02a19d2 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,7 @@ + + +Top menu restyled +adapted to new Workspace Tree +adapted to new Home Library + + \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..4efc827 --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,48 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + INSTALL + MAINTAINERS + changelog.xml + + 755 + true + + + target/apidocs + /${artifactId}/doc/api + true + 755 + + + + + ${distroDirectory}/profile.xml + ./ + true + + + target/${build.finalName}.war + /${artifactId} + + + ${distroDirectory}/svnpath.txt + /${artifactId} + true + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..51c3b6b --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,25 @@ + + + + Service + + ${description} + PortletUser + ${artifactId} + ${version} + + + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + + target/${build.finalName}.war + + + + + diff --git a/distro/svnpath.txt b/distro/svnpath.txt new file mode 100644 index 0000000..edacb04 --- /dev/null +++ b/distro/svnpath.txt @@ -0,0 +1 @@ +${scm.url} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fb128b8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,309 @@ + + + + 4.0.0 + + maven-parent + org.gcube.tools + 1.0.0 + + + + org.gcube.portlets.user + reports + war + 4.0.0-SNAPSHOT + gCube Reports Portlet + + gCube Reports Portlet. + + + scm:svn:http://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId} + scm:https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId} + http://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/${project.artifactId} + + + + 2.4.0 + distro + + 1.6 + 1.6 + ${project.build.directory}/${project.build.finalName} + + UTF-8 + UTF-8 + + + + + + xerces + xercesImpl + 2.9.1 + provided + + + com.google.gwt + gwt-user + ${gwtVersion} + provided + + + com.google.gwt + gwt-servlet + ${gwtVersion} + provided + + + org.gcube.applicationsupportlayer + aslsocial + [0.1.0-SNAPSHOT, 1.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + gcube-widgets + [1.4.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + guided-tour-widget + [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + org.gcube.portal + custom-portal-handler + [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + com.sencha.gxt + gxt + 2.2.5 + provided + + + org.gcube.common + csv4j + 1.2.0-SNAPSHOT + provided + + + org.gcube.portlets.user + workspace-light-tree + [2.9.0-SNAPSHOT, 3.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.admin + document-workflow-library + [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + gcube-docx-generator + [1.0.0-SNAPSHOT, 2.0.0-SNAPSHOT) + + + org.gcube.portal + gcube-reporting-library + [3.0.0-SNAPSHOT, 4.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + workspace-tree-widget + [6.0.0-SNAPSHOT, 7.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + home-library + [4.3.0-SNAPSHOT, 5.0.0-SNAPSHOT) + provided + + + org.gcube.portlets.user + home-library-jcr + [1.3.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + org.gcube.applicationsupportlayer + accesslogger + [1.2.0-SNAPSHOT, 2.0.0-SNAPSHOT) + provided + + + org.apache.derby + derby + 10.8.2.2 + provided + + + com.liferay.portal + portal-service + 6.0.6 + provided + + + log4j + log4j + 1.2.16 + runtime + + + org.slf4j + slf4j-log4j12 + 1.6.4 + runtime + + + org.slf4j + slf4j-api + 1.6.4 + runtime + + + com.allen-sauer.gwt.log + gwt-log + 3.1.8 + provided + + + javax.portlet + portlet-api + 2.0 + provided + + + junit + junit + 4.7 + test + + + javax.validation + validation-api + 1.0.0.GA + test + + + javax.validation + validation-api + 1.0.0.GA + sources + test + + + + + + ${webappDirectory}/WEB-INF/classes + + + + + + org.codehaus.mojo + gwt-maven-plugin + 2.4.0 + + + + compile + + + + + + + Messages.html + ${webappDirectory} + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.1.1 + + + compile + + exploded + + + + + ${webappDirectory} + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + ${distroDirectory}/descriptor.xml + + + + + servicearchive + install + + single + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/Headerbar.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Headerbar.java new file mode 100644 index 0000000..4772ba9 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Headerbar.java @@ -0,0 +1,695 @@ +package org.gcube.portlets.user.reportgenerator.client; + + +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; +import org.gcube.portlets.user.reportgenerator.client.Presenter.CommonCommands; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.dialog.ImporterDialog; +import org.gcube.portlets.user.reportgenerator.client.dialog.PagePropertiesDialog; +import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel; +import org.gcube.portlets.user.workspace.lighttree.client.ItemType; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupEvent; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupHandler; +import org.gcube.portlets.user.workspace.lighttree.client.load.WorkspaceLightTreeLoadPopup; + +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.RunAsyncCallback; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.MenuBar; +import com.google.gwt.user.client.ui.MenuItem; +import com.google.gwt.user.client.ui.MenuItemSeparator; +import com.google.gwt.user.client.ui.RichTextArea; + + + +/** + * Headerbar class is the top bar component of the UI + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version July 2011 (3.0) + */ +public class Headerbar extends Composite{ + + private static final String ADD_BIBLIO_ENTRY = "Add citation"; + private static final String VIEW_BIBLIO = "View Bibliography"; + private static final String MANAGE_BIBLIO = "Delete citation(s)"; + private static final String EXPORT_OPENXML = "Export to OpenXML (docx)"; + private static final String EXPORT_HTML = "Export to HTML"; + private static final String EXPORT_FIMES = "Export to FiMES XML"; + + private static final String VIEW_USER_COMMENTS = "View user comments"; + + String location; + + private Presenter presenter; + + /** + * the template Model + */ + private TemplateModel templateModel; + + /** + * mainLayout Panel + */ + private CellPanel mainLayout = new HorizontalPanel(); + + + //private MenuItem optionPDF; + + private MenuItem importModel; + + private MenuItem addBiblioEntry; + + private MenuItem viewBiblio; + + private MenuItem manageBiblio; + + private MenuItem optionHTML; + + private MenuItem optionDOCX; + + private MenuItem optionFimes; + + private MenuItem viewMetadata; + + private MenuItem viewComments; + + private MenuItem discardSection; + + + + MenuBar menuBar = new MenuBar(); + + MenuItem fileMenu; + MenuItem viewMenu; + MenuItem sectionsMenu; + MenuItem biblioMenu; + MenuItem exportMenu; + MenuItemSeparator separator1; + MenuItemSeparator separator2; + MenuItemSeparator separator3; + MenuItemSeparator separator4; + + /** + * Constructor + * @param c the controller instance for this UI component + */ + public Headerbar(Presenter c) { + this.presenter = c; + this.templateModel = presenter.getModel(); + + menuBar.setAutoOpen(false); + // menuBar.setWidth("100px"); + menuBar.setAnimationEnabled(true); + fileMenu = getFileMenu(); + menuBar.addItem(fileMenu); + separator1 = menuBar.addSeparator(); + viewMenu = getViewMenu(); + menuBar.addItem(viewMenu); + separator2 = menuBar.addSeparator(); + sectionsMenu = getSectionMenu(); + menuBar.addItem(sectionsMenu); + separator3 = menuBar.addSeparator(); + biblioMenu = getBiblioMenu(); + menuBar.addItem(biblioMenu); + separator4 = menuBar.addSeparator(); + exportMenu = getExportsMenu(); + menuBar.addItem(exportMenu); + + mainLayout.setSize("100%", "24px"); + mainLayout.setStyleName("menubar"); + + mainLayout.add(menuBar); + + //design the part for the template name and the pages handling + + HorizontalPanel captionPanel = new HorizontalPanel(); + captionPanel.setWidth("100%"); + + HorizontalPanel pageHandlerPanel = new HorizontalPanel(); + pageHandlerPanel.setHeight("24"); + pageHandlerPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); + + captionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); + mainLayout.add(captionPanel); + mainLayout.add(pageHandlerPanel); + mainLayout.setCellHorizontalAlignment(menuBar, HasHorizontalAlignment.ALIGN_LEFT); + mainLayout.setCellHorizontalAlignment(captionPanel, HasHorizontalAlignment.ALIGN_LEFT); + mainLayout.setCellWidth(menuBar, "200"); + mainLayout.setCellWidth(pageHandlerPanel, "200"); + initWidget(mainLayout); + } + + public void setMenuForWorkflowDocument(boolean canUpdate) { + presenter.setMenuForWorkflowDocument(true); + menuBar.removeItem(fileMenu); + menuBar.removeItem(viewMenu); + menuBar.removeItem(sectionsMenu); + menuBar.removeItem(biblioMenu); + menuBar.removeSeparator(separator1); + menuBar.removeSeparator(separator2); + menuBar.removeItem(exportMenu); + + MenuBar workflowMenu = new MenuBar(true); + workflowMenu.setAnimationEnabled(true); + + MenuItem menu = new MenuItem("Workflow Document Options", true, workflowMenu); + menu.setWidth("400px"); + Command updateWfDocument = new Command() { + public void execute() { + presenter.updateWorkflowDocument(true); + } + }; + Command backCommand = new Command() { + public void execute() { + presenter.updateWorkflowDocument(false); + } + }; + + Command showChanges = new Command() { + public void execute() { + presenter.showLastChangesPopup(); + } + }; + + if (canUpdate) + workflowMenu.addItem("Update this document", updateWfDocument); + //workflowMenu.addItem("Show previous changes", showChanges); + workflowMenu.addSeparator(); + workflowMenu.addItem("Back to My Workflow Documents", backCommand); + + menuBar.addItem(menu); + separator1 = menuBar.addSeparator(); + viewMenu = getViewMenu(); + menuBar.addItem(viewMenu); + separator2 = menuBar.addSeparator(); + sectionsMenu = getSectionMenu(); + menuBar.addItem(sectionsMenu); + separator3 = menuBar.addSeparator(); + biblioMenu = getBiblioMenu(); + menuBar.addItem(biblioMenu); + separator4 = menuBar.addSeparator(); + exportMenu = getExportsMenu(); + menuBar.addItem(exportMenu); + ReportGenerator.get().getToolbarPanel().clear(); + ReportGenerator.get().getToolbarPanel().add(new HTML("  ", true)); + enableExports(); + } + /** + * Redirect to VRE Deployer Portlet + */ + private void loadWorkflowLibraryApp(){ + getUrl(); + location += "/../my-workflow-documents"; + Window.open(location, "_self", ""); + } + /** + * Get URL from browser + */ + public native void getUrl()/*-{ + this.@org.gcube.portlets.user.reportgenerator.client.Headerbar::location = $wnd.location.href; + }-*/; + + /** + * temporary command + * @return the command instance + */ + public Command getNullCommand() { + Command openNothing = new Command() { + + public void execute() { } + }; + + return openNothing; + } + /** + * temporary command + * @return the command instance + */ + public Command getBiblioCommand() { + Command openNothing = new Command() { + public void execute() { + MessageBox.alert("Warning ","A textarea must be selected to add an entry", null); + } + }; + return openNothing; + } + + + Command addCitationCmd = new Command() { + public void execute() { + presenter.openAddCitationDialog(); + } + }; + + Command viewBiblioCmd = new Command() { + public void execute() { + if (presenter.hasBibliography()) { + presenter.seekLastPage(); + } + else { + MessageBox.alert("Warning", "No bibliography found, to add bibliography start adding citations:
Bibliography > Add citation (from within a text area)", null); + } + } + }; + + Command manageBiblioCmd = new Command() { + public void execute() { + if (presenter.hasBibliography()) { + presenter.openManageCitationsDialog(); + } + else { + MessageBox.alert("Warning", "No bibliography found, to add bibliography start adding citations:
Bibliography > Add citation (from within a text area)", null); + } + } + }; + + /** + * + * @return + */ + private MenuItem getBiblioMenu() { + // Create the Options menu + MenuBar biblioMenu = new MenuBar(true); + MenuItem toReturn = new MenuItem("Bibliography", biblioMenu); + biblioMenu.setAnimationEnabled(true); + addBiblioEntry = new MenuItem(""+ ADD_BIBLIO_ENTRY +"", true, getBiblioCommand()); + biblioMenu.addItem(addBiblioEntry); + viewBiblio = new MenuItem(VIEW_BIBLIO, true, viewBiblioCmd); + manageBiblio = new MenuItem(MANAGE_BIBLIO, true, manageBiblioCmd); + biblioMenu.addSeparator(); + biblioMenu.addItem(manageBiblio); + biblioMenu.addItem(viewBiblio); + return toReturn; + } + /** + * + * @return + */ + private MenuItem getSectionMenu() { + // Create the Options menu + MenuBar insertsMenu = new MenuBar(true); + MenuItem toReturn = new MenuItem("Section", insertsMenu); + insertsMenu.setAnimationEnabled(true); + importModel = new MenuItem("Import from Template or Report", true, getNullCommand()); + insertsMenu.addItem(importModel); + viewMetadata = new MenuItem("View Metadata", true, getNullCommand()); + discardSection = new MenuItem("Discard current", true, getNullCommand()); + viewComments = new MenuItem(""+ VIEW_USER_COMMENTS+"", true, getNullCommand()); + insertsMenu.addItem(discardSection); + insertsMenu.addSeparator(); + insertsMenu.addItem(viewMetadata); + insertsMenu.addItem(viewComments); + return toReturn; + } + + + private MenuItem getExportsMenu() { + MenuBar exportsMenu = new MenuBar(true); + + exportsMenu.setAnimationEnabled(true); + MenuItem toReturn = new MenuItem("Export", exportsMenu); + + optionDOCX = new MenuItem(""+ EXPORT_OPENXML +"", true, getNullCommand()); + // optionPDF = new MenuItem("Export to PDF", true, getNullCommand()); + optionHTML = new MenuItem(""+ EXPORT_HTML +"", true, getNullCommand()); + optionFimes = new MenuItem(""+ EXPORT_FIMES +"", true, getNullCommand()); + + exportsMenu.addItem(optionDOCX); + exportsMenu.addItem(optionHTML); + + //optionsMenu.addItem(optionPDF); + //exportsMenu.addItem(optionFimes); + + return toReturn; + } + + private MenuItem getViewMenu() { + Command openPageProperties = new Command() { + public void execute() { + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + PagePropertiesDialog dlg = new PagePropertiesDialog(templateModel, presenter); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + }; + + Command showReportStructure = new Command() { + public void execute() { + presenter.showReportStructure(); + } + }; + + // Create the Options menu + MenuBar optionsMenu = new MenuBar(true); + + optionsMenu.setAnimationEnabled(true); + MenuItem toReturn = new MenuItem("View", optionsMenu); + + optionsMenu.addItem("View Properties", openPageProperties); + optionsMenu.addItem("View Structure", showReportStructure); + optionsMenu.addSeparator(); + + return toReturn; + } + + /** + * rewrite with setHTML to remove the gray color + */ + public void enableExports() { + + optionDOCX.setHTML(EXPORT_OPENXML); + optionDOCX.setCommand(generateDOCX); + + // optionPDF.setHTML("Export to PDF"); + // optionPDF.setCommand(generatePDF); + + optionHTML.setHTML(EXPORT_HTML); + optionHTML.setCommand(generateHTML); + + optionFimes.setHTML(EXPORT_FIMES); + optionFimes.setCommand(generateFimes); + // + importModel.setHTML("Import from Template or Report"); + importModel.setCommand(importModelOrReport); + + viewMetadata.setHTML("View Metadata"); + viewMetadata.setCommand(openMetadata); + + viewComments.setHTML(VIEW_USER_COMMENTS); + viewComments.setCommand(showUserComments); + + discardSection.setHTML("Discard current"); + discardSection.setCommand(discardSectionCom); + + } + /** + * + */ + Command showUserComments = new Command() { + public void execute() { + presenter.showSectionUserCommentsTooltips(); + } + }; + /** + * rewrite with setHTML to remove the gray color + * @param d4sArea + */ + public void enableBiblioEntry(RichTextArea d4sArea) { + addBiblioEntry.setHTML(ADD_BIBLIO_ENTRY); + addBiblioEntry.setCommand(addBiblioEntryCommand); + presenter.setAreaForBiblio(d4sArea); + } + + /** + * build the File Menu + * @return + */ + + private MenuItem getFileMenu() { + Command newTemplate = new Command() { + public void execute() { + presenter.changeTemplateName(TemplateModel.DEFAULT_NAME); + presenter.cleanAll(); + } + }; + Command openTemplate = new Command() { + public void execute() { + GWT.runAsync(WorkspaceLightTreeLoadPopup.class, new RunAsyncCallback() { + public void onSuccess() { + + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + + WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Open Template", true, true); + wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE); + wpTreepopup.setSelectableTypes(ItemType.REPORT_TEMPLATE); + + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + if (! event.isCanceled()) { + if (event.getSelectedItem() != null) { + presenter.openTemplate(event.getSelectedItem().getName(), event.getSelectedItem().getId(), true); + } + presenter.getHeader().enableExports(); + } + } + }); + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + + + + } + }; + + Command openHelp = new Command() { + + public void execute() { + if (! ReportConstants.isDeployed) { + presenter.openTemplate("", "", true); + enableExports(); + } + else { + String url = "https://gcube.wiki.gcube-system.org/gcube/index.php/Common_Functionality#Report_Management"; + int width = Window.getClientWidth(); + int height = Window.getClientHeight(); + int winWidth = (int) (Window.getClientWidth() * 0.8); + int winHeight = (int) (Window.getClientHeight() * 0.7); + int left = (width - winWidth) / 2; + int top = (height - winHeight) / 2; + Window.open(url, null,"left=" + left + "top" + top + ", width=" + winWidth + ", height=" + winHeight + ", resizable=yes, scrollbars=yes, status=yes"); + } + + } + + }; + + Command openReport = new Command() { + public void execute() { + + GWT.runAsync(WorkspaceLightTreeLoadPopup.class, new RunAsyncCallback() { + public void onSuccess() { + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + + WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Open Report", true, true); + wpTreepopup.setShowableTypes(ItemType.REPORT); + wpTreepopup.setSelectableTypes(ItemType.REPORT); + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + if (! event.isCanceled()) { + if (event.getSelectedItem() != null) { + presenter.openTemplate(event.getSelectedItem().getName(), event.getSelectedItem().getId(), false); + } + presenter.getHeader().enableExports(); + } + + } + }); + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + } + }; + + Command saveReportAs = new Command() { + public void execute() { + CommonCommands cmd = new CommonCommands(presenter); + cmd.saveReportAsDialog(); + } + }; + + + + Command saveReport = new Command() { + public void execute() { + if (templateModel.getTemplateName().endsWith("d4sR")) + presenter.saveReport(); + else { + CommonCommands cmd = new CommonCommands(presenter); + cmd.saveReportAsDialog(); + } + } + }; + + Command importFimes = new Command() { + public void execute() { + presenter.showImportPopup(); + } + }; + + + + // Create the file menu + MenuBar fileMenu = new MenuBar(true); + fileMenu.setAnimationEnabled(true); + + MenuItem toReturn = new MenuItem("File", fileMenu); + fileMenu.addItem("Open template...", openTemplate); + // fileMenu.addSeparator(); + + // fileMenu.addItem("Open saved Report", getNullCommand()); + fileMenu.addSeparator(); + fileMenu.addItem("Open Report", openReport); + fileMenu.addItem("Save", saveReport); + fileMenu.addItem("Save As ..", saveReportAs); + fileMenu.addSeparator(); +// fileMenu.addItem("Import from FiMES XML", importFimes); + fileMenu.addItem("Close Report", newTemplate); + fileMenu.addSeparator(); + fileMenu.addItem("? Open User's Guide", openHelp); + return toReturn; + } + + /** + * + * @param model . + */ + public void setModel(TemplateModel model ) { + this.templateModel = model; + } + + //************** COMMANDS ********************************//// + + Command generateFimes = new Command() { + public void execute() { + presenter.generateFiMES(templateModel); + } + }; + + Command generateDOCX = new Command() { + public void execute() { + presenter.generateManifestation(templateModel, ExportManifestationType.DOCX); + } + }; + + Command generatePDF = new Command() { + public void execute() { + Window.alert("PDF Exporting may not be fully working, you can also generate a PDF using your Word Processor application starting from the docx exported file"); + presenter.generateManifestation(templateModel, ExportManifestationType.PDF); + } + }; + + Command generateHTML = new Command() { + public void execute() { + presenter.generateManifestation(templateModel, ExportManifestationType.HTML); + } + }; + + + Command discardSectionCom = new Command() { + public void execute() { + presenter.discardCurrentSection(); + } + }; + + //************** COMMANDS ********************************//// + Command addBiblioEntryCommand = new Command() { + public void execute() { + presenter.openAddCitationDialog(); + } + }; + + /** + * + */ + Command openMetadata = new Command() { + public void execute() { + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + GCubeDialog dlg = new GCubeDialog(true); + dlg.setText("Report Metadata:"); + int pageNo = presenter.getModel().getCurrentPage(); + List metadatas = presenter.getModel().getSection(pageNo).getAllMetadata(); + int nRows = metadatas.size(); + Grid metadataGrid = new Grid(nRows, 2); + int i = 0; + for (Metadata md : metadatas) { + metadataGrid.setWidget(i, 0, new HTML("" + md.getAttribute() + ": ")); + metadataGrid.setWidget(i, 1, new HTML(md.getValue())); + i++; + } + + dlg.setWidget(metadataGrid); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + }; + + Command importModelOrReport = new Command() { + public void execute() { + if (! ReportConstants.isDeployed) { + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + ImporterDialog dlg = new ImporterDialog(null, presenter); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + else { + + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Pick the item you want to import from", true, true); + wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE, ItemType.REPORT); + + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + if (! event.isCanceled()) { + if (event.getSelectedItem() != null) { + int left = mainLayout.getAbsoluteLeft() + 50; + int top = mainLayout.getAbsoluteTop() + 25; + ImporterDialog dlg = new ImporterDialog(event.getSelectedItem(), presenter); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + presenter.getHeader().enableExports(); + } + + } + }); + + + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + } + } + }; + /** + * + * @return . + */ + public CellPanel getMainLayout() { + return mainLayout; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/CommonCommands.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/CommonCommands.java new file mode 100644 index 0000000..2047785 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/CommonCommands.java @@ -0,0 +1,225 @@ +package org.gcube.portlets.user.reportgenerator.client.Presenter; + +import org.gcube.portlets.user.reportgenerator.client.ReportConstants; +import org.gcube.portlets.user.reportgenerator.client.dialog.ImageUploaderDialog; +import org.gcube.portlets.user.reportgenerator.client.dialog.ImporterDialog; +import org.gcube.portlets.user.workspace.lighttree.client.ItemType; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupEvent; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupHandler; +import org.gcube.portlets.user.workspace.lighttree.client.load.WorkspaceLightTreeLoadPopup; +import org.gcube.portlets.user.workspace.lighttree.client.save.WorkspaceLightTreeSavePopup; + +import com.extjs.gxt.ui.client.event.ColorPaletteEvent; +import com.extjs.gxt.ui.client.event.Events; +import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.widget.ColorPalette; +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.RunAsyncCallback; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.PopupPanel; + + + +/** + * * + * /** + * CommonCommands class contains the menu commands for the UI + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version December 2012 (2.7) + */ +public class CommonCommands { + /** + * + */ + public Command openTemplate; + /** + * + */ + public Command importTemplateCommand; + /** + * + */ + public Command insertImage; + /** + * + */ + public Command saveTemplate; + /** + * + */ + public Command pickColor; + + private Presenter presenter; + + /** + * + * @param presenter . + */ + public CommonCommands(final Presenter presenter) { + this.presenter = presenter; + openTemplate = new Command() { + public void execute() { + final int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + final int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + + GWT.runAsync(WorkspaceLightTreeLoadPopup.class, new RunAsyncCallback() { + public void onSuccess() { + WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Open Template", true, true); + wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE); + wpTreepopup.setSelectableTypes(ItemType.REPORT_TEMPLATE); + + + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + if (! event.isCanceled()) { + if (event.getSelectedItem() != null) { + presenter.openTemplate(event.getSelectedItem().getName(), event.getSelectedItem().getId(), true); + } + } + + } + }); + + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + } + }; + + + insertImage = new Command() { + public void execute() { + int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + ImageUploaderDialog dlg = new ImageUploaderDialog(presenter); + dlg.setAnimationEnabled(true); + dlg.setPopupPosition(left, top); + dlg.show(); + } + }; + + pickColor = new Command() { + public void execute() { + int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 600; + int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 50; + final PopupPanel pp = new PopupPanel(true); + + ColorPalette colorPalette = new ColorPalette(); + colorPalette.addListener(Events.Select, new Listener() { + @SuppressWarnings("deprecation") + public void handleEvent(ColorPaletteEvent be) { + presenter.getCurrentSelected().getExtendedFormatter().setForeColor(be.getColor()); + pp.hide(); + } + }); + pp.add(colorPalette); + pp.setAnimationEnabled(false); + pp.setPopupPosition(left, top); + pp.show(); + } + }; + + + + importTemplateCommand = new Command() { + public void execute() { + if (! ReportConstants.isDeployed) { + int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + ImporterDialog dlg = new ImporterDialog(null, presenter); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + else { + GWT.runAsync(WorkspaceLightTreeLoadPopup.class, new RunAsyncCallback() { + public void onSuccess() { + WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Pick the item you want to import from", true, true); + wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE); + + + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + if (! event.isCanceled()) { + if (event.getSelectedItem() != null) { + int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + ImporterDialog dlg = new ImporterDialog(event.getSelectedItem(), presenter); + dlg.setPopupPosition(left, top); + dlg.setAnimationEnabled(true); + dlg.show(); + } + } + + } + }); + int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + } + } + }; + + saveTemplate = new Command() { + public void execute() { + if (presenter.getModel().getTemplateName().endsWith("d4sR")) + presenter.saveReport(); + else + saveReportAsDialog(); + } + }; + + } //end constructor + + public void saveReportAsDialog() { + final int left = presenter.getHeader().getMainLayout().getAbsoluteLeft() + 50; + final int top = presenter.getHeader().getMainLayout().getAbsoluteTop() + 25; + + GWT.runAsync(WorkspaceLightTreeSavePopup.class, new RunAsyncCallback() { + public void onSuccess() { + WorkspaceLightTreeSavePopup wpTreepopup = new WorkspaceLightTreeSavePopup("Save Template, choose folder please:", true); + wpTreepopup.setSelectableTypes( ItemType.FOLDER, ItemType.ROOT); + wpTreepopup.setShowEmptyFolders(true); + + wpTreepopup.addPopupHandler(new PopupHandler() { + public void onPopup(PopupEvent event) { + + //checking user input + String inputUser = event.getName(); + String newTemplateName = inputUser; + if (presenter.getModel().getTemplateName().compareTo(newTemplateName) != 0) { + newTemplateName = newTemplateName.trim(); + presenter.getModel().setTemplateName(newTemplateName+".d4sR"); + } + presenter.changeTemplateName(newTemplateName); + presenter.saveReport(event.getSelectedItem().getId(), newTemplateName); + } + }); + wpTreepopup.setPopupPosition(left, top); + wpTreepopup.show(); + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + + + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/Presenter.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/Presenter.java new file mode 100644 index 0000000..667184e --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/Presenter/Presenter.java @@ -0,0 +1,1168 @@ +package org.gcube.portlets.user.reportgenerator.client.Presenter; + +import java.util.HashMap; +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.client.uicomponents.richtext.RichTextToolbar; +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; +import org.gcube.portlets.user.reportgenerator.client.Headerbar; +import org.gcube.portlets.user.reportgenerator.client.ReportGenerator; +import org.gcube.portlets.user.reportgenerator.client.TitleBar; +import org.gcube.portlets.user.reportgenerator.client.ToolboxPanel; +import org.gcube.portlets.user.reportgenerator.client.WorkspacePanel; +import org.gcube.portlets.user.reportgenerator.client.dialog.AddBiblioEntryDialog; +import org.gcube.portlets.user.reportgenerator.client.dialog.DeleteCitationsDialog; +import org.gcube.portlets.user.reportgenerator.client.dialog.FimesReportTreePanel; +import org.gcube.portlets.user.reportgenerator.client.dialog.LoadingPopup; +import org.gcube.portlets.user.reportgenerator.client.events.AddBiblioEvent; +import org.gcube.portlets.user.reportgenerator.client.events.AddBiblioEventHandler; +import org.gcube.portlets.user.reportgenerator.client.events.AddCommentEvent; +import org.gcube.portlets.user.reportgenerator.client.events.AddCommentEventHandler; +import org.gcube.portlets.user.reportgenerator.client.events.ItemSelectionEvent; +import org.gcube.portlets.user.reportgenerator.client.events.ItemSelectionEventHandler; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedCitationEvent; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedCitationEventHandler; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedUserCommentEvent; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedUserCommentEventHandler; +import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateComponent; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateSection; +import org.gcube.portlets.user.reportgenerator.client.targets.AttributeArea; +import org.gcube.portlets.user.reportgenerator.client.targets.BasicTextArea; +import org.gcube.portlets.user.reportgenerator.client.targets.Coords; +import org.gcube.portlets.user.reportgenerator.client.targets.D4sRichTextarea; +import org.gcube.portlets.user.reportgenerator.client.targets.DroppingArea; +import org.gcube.portlets.user.reportgenerator.client.targets.GenericTable; +import org.gcube.portlets.user.reportgenerator.client.targets.ImageArea; +import org.gcube.portlets.user.reportgenerator.client.targets.ReportTextArea; +import org.gcube.portlets.user.reportgenerator.client.targets.TSArea; +import org.gcube.portlets.user.reportgenerator.shared.SessionInfo; + +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.extjs.gxt.ui.client.widget.layout.FitLayout; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.RichTextArea; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + + + +/** + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version July 2011 (3.0) + */ + +public class Presenter { + /** + * View part + */ + private WorkspacePanel wp; + + private Headerbar header; + + private ToolboxPanel toolBoxPanel; + +// private FimesFileUploadWindow importDlg; + + private TitleBar titleBar; + + + private String currentUser; + private String currentScope; + /** + * Model + */ + private TemplateModel model; + + private int currFocus; + + RichTextToolbar currentSelectedToolbar; + + RichTextArea areaForBiblio; + + /** + * + */ + private CommonCommands commonCommands; + + private boolean menuForWorkflowDocument = false; + /** + * eventbus events handler + */ + HandlerManager eventBus = new HandlerManager(null); + + public HandlerManager getEventBus() { + return eventBus; + } + + + private void handleEvents() { + eventBus.addHandler(AddBiblioEvent.TYPE, new AddBiblioEventHandler() { + public void onAddCitation(AddBiblioEvent event) { + addCitation(event.getCitekey(), event.getCitetext()); + String keyToAdd = " (" + event.getCitekey() +") "; + String currHTML = areaForBiblio.getHTML(); + if (currHTML.endsWith("
")) + currHTML = currHTML.substring(0, currHTML.length()-4); + areaForBiblio.setHTML(currHTML+keyToAdd); + } + }); + + eventBus.addHandler(RemovedCitationEvent.TYPE, new RemovedCitationEventHandler() { + public void onRemovedCitation(RemovedCitationEvent event) { + removeCitation(event.getCitekey()); + } + }); + +// eventBus.addHandler(ExportFinishedEvent.TYPE, new EsportFinishedEventHandler() { +// public void onFinishedExport(ExportFinishedEvent event) { +// refreshWorkspace(); +// } +// }); + + eventBus.addHandler(AddCommentEvent.TYPE, new AddCommentEventHandler() { + public void onAddComment(AddCommentEvent event) { + model.addCommentToComponent(event.getSourceComponent(), event.getComment(), event.getAreaHeight()); + } + }); + + eventBus.addHandler(RemovedUserCommentEvent.TYPE, new RemovedUserCommentEventHandler() { + public void onRemovedComment(RemovedUserCommentEvent event) { + model.removeComment(event.getSourceComponent()); + } + }); + +// eventBus.addHandler(ImportFinishedEvent.TYPE, new ImportFinishedEventHandler(){ +// public void onFinishedImport(ImportFinishedEvent event) { +// importDlg.hide(); +// openImportedFimesXML(event.getPathFile()); +// } +// +// }); + + eventBus.addHandler(ItemSelectionEvent.TYPE, new ItemSelectionEventHandler() { + public void onItemSelected(ItemSelectionEvent event) { + // TODO Auto-generated method stub + HashMap map = event.getItemSelected(); + int sectionIndex = 0, compIndex = 0; + if (map != null) { + if (map.get("item").equals("Section")) { + sectionIndex = Integer.parseInt((String) map.get("index")); + seekSection(sectionIndex+1); + } else { + compIndex = Integer.parseInt((String) map.get("index")); + sectionIndex = Integer.parseInt((String) ((HashMap) map.get("parent")).get("index")); + seekSection(sectionIndex+1); + int top = getModel().getSectionComponent(sectionIndex+1).get(compIndex).getContent().getAbsoluteTop(); + ReportGenerator.get().getScrollerPanel().setScrollPosition(top); + } + } + + } + }); + } + + + /** + * constructor + */ + public Presenter() { + model = new TemplateModel(this); + + titleBar = ReportGenerator.get().getTitleHeader(); + + handleEvents(); + + AsyncCallback callback = new AsyncCallback() { + public void onFailure(Throwable caught) {} + + public void onSuccess(final SessionInfo sessionInfo) { + currentUser = sessionInfo.getUsername(); + currentScope = sessionInfo.getScope(); + if (sessionInfo.isWorkflowDocument()) { + model.getModelService().getWorkflowDocumentFromDocumentLibrary(new AsyncCallback() { + + public void onFailure(Throwable caught) { } + + public void onSuccess(SerializableModel wfReport) { + loadModel(wfReport); + header.setMenuForWorkflowDocument(sessionInfo.isEditable()); + pollServiceForLockRenewal(); + } + }); + } + else { + model.getModelService().readTemplateFromSession(new AsyncCallback() { + public void onFailure(Throwable caught) { } + public void onSuccess(SerializableModel result) { + if (result != null) { + loadModel(result); + header.enableExports(); + } + } + }); + } + } + }; + + model.getModelService().getSessionInfo(getHost(), callback); + commonCommands = new CommonCommands(this); + //importDlg = new FimesFileUploadWindow(eventBus); + } + + + public void showImportPopup() { +// importDlg.setVisible(true); +// importDlg.show(); + } + + public void showLastChangesPopup() { + + } + + public void showSectionUserCommentsTooltips() { + TemplateSection currSection = model.getSection(model.getCurrentPage()); + for (TemplateComponent tc : currSection.getAllComponents()) { + if (tc.getContent() instanceof ReportTextArea && tc.getUserComments() != null) { + ReportTextArea rpta = (ReportTextArea) tc.getContent(); + rpta.showComment(tc.getUserComments()); + } + } + } + /** + * called when a citation is added + * @param citekey . + * @param text . + */ + public void addCitation(String citekey, String text) { + if (! hasBibliography()) { + MessageBox.alert("Warning", "Bibliography will be added as last section of this report", null); + model.insertBiblioSection(); + } + model.addCitation(citekey, text); + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + } + + public boolean removeCitation(String citekey) { + boolean toReturn = model.removeCitation(citekey); + if (toReturn) { //if has been removed from the model + if (model.getCurrentPage() == model.getTotalPages()) { //if the view is displaying the bibliography, need to refresh it + GWT.log("SEI in BIBLIO"); + seekSection(model.getTotalPages()); + } + } + return toReturn; + } + /** + * look if a section with a specific metadata (that indicate sit is a biblio section) + * exists in the current report model: + * check whether the last section has Metadata "isBiblio" = "true" or false + * @return true if bibliography is present yet false otherwise + */ + public boolean hasBibliography() { + for (Metadata metadata : model.getSection(model.getTotalPages()).getAllMetadata()) + if (metadata.getAttribute().equals(TemplateModel.BIBLIO_SECTION)) return true; + return false; + } + /** + * look if a comment with a specific metadata (that indicate sit is a comment) + * exists in the current report model: + * @return true if comment is present yet false otherwise + */ + public boolean hasComments(Widget toCheck) { + TemplateSection currSection = model.getSection(model.getCurrentPage()); + return currSection.hasComments(toCheck); + } + /** + * look if a comment with a specific metadata (that indicate sit is a comment) + * exists in the current report model: + * @return true if comment is present yet false otherwise + */ + public AddCommentEvent getComponentComments(Widget toCheck) { + TemplateSection currSection = model.getSection(model.getCurrentPage()); + return currSection.getComponentComments(toCheck); + } + /** + * + */ + private void pollServiceForLockRenewal() { + final int fourteenMinutes = 840000; + final Timer t = new Timer() { + public void run() { + model.getModelService().renewLock(new AsyncCallback() { + public void onFailure(Throwable caught) { + } + public void onSuccess(Void result) { + schedule(fourteenMinutes); + } + }); + } + }; + t.schedule(fourteenMinutes); + } + /** + * put the commands in the hashmap + */ + private HashMap getCommands() { + /** + * commands to pass to the toolbar + */ + HashMap toReturn = new HashMap(); + + Command newTemplate= new Command() { + public void execute() { + changeTemplateName(TemplateModel.DEFAULT_NAME); + cleanAll(); + } + }; + + toReturn.put("save", commonCommands.saveTemplate); + toReturn.put("newdoc", newTemplate); + toReturn.put("open_template", commonCommands.openTemplate); + toReturn.put("importing", commonCommands.importTemplateCommand); + toReturn.put("insertImage", commonCommands.insertImage); + toReturn.put("pickColor", commonCommands.pickColor); + + return toReturn; + + } + + /** + * to remove the current displayed section + */ + public void discardCurrentSection() { + if (model.getTotalPages() == 1) + Window.alert("Cannot discard section, need ad least 2"); + else { + boolean result = Window.confirm("Are you sure you want to discard section number " + model.getCurrentPage() + "?"); + if (result) { + TemplateSection removed = model.discardSection(model.getCurrentPage()); + if (removed == null) + GWT.log("REMOVED NOTHING", null); + else + GWT.log("REMOVED " + removed.getAllComponents().size(), null); + loadFirstSection(); + } + } + } + /** + * + * @param titleBar , + */ + public void setTitleBar(TitleBar titleBar) { + this.titleBar = titleBar; + } + /** + * + * @return . + */ + public String getHost() { + return GWT.getHostPageBaseURL() + "../../"; + } + + /** + * + */ + public void addTextToolBar() { + + RichTextToolbar rtbar = new RichTextToolbar(new RichTextArea(), false, getCommands() ); + SimplePanel deco = new SimplePanel(); + rtbar.setEnabled(false); + deco.add(rtbar); + deco.setSize("100%", "25"); + rtbar.setWidth("100%"); + ReportGenerator.get().getToolbarPanel().clear(); + ReportGenerator.get().getToolbarPanel().add(deco); + } + /** + * remove the user-added components from the workspace, and from the model + * + */ + public void cleanAll() { + // reset the model + model = new TemplateModel(this); + + //reset the UI + + //give the new model instance + header.setModel(model); + wp.setModel(model); + + cleanWorkspace(); + titleBar.hideNextButton(); + titleBar.hidePrevButton(); + titleBar.setTemplateName(model.getTemplateName()); + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + resizeWorkingArea(model.getPageWidth(), model.getPageHeight()); + + //persists the change in the session + model.storeInSession(); + } + + /** + * just clean the page + */ + public void cleanAllNotSession() { + // reset the model + model = new TemplateModel(this); + + //reset the UI + + //give the new model instance + header.setModel(model); + wp.setModel(model); + + cleanWorkspace(); + titleBar.hideNextButton(); + titleBar.hidePrevButton(); + titleBar.setTemplateName(model.getTemplateName()); + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + resizeWorkingArea(model.getPageWidth(), model.getPageHeight()); + } + + /** + * Save the current report + * @param folderid the id where to save the report + * + */ + public void saveReport(String folderid, String name) { + model.storeInSession(); + model.saveReport(folderid, name); + } + + + /** + * Save the current report in a given folder + * + */ + public void saveReport() { + model.storeInSession(); + model.saveReport(); + } + + /** + * Save the current report in a given folder + * + */ + public void updateWorkflowDocument(boolean update) { + model.storeInSession(); + model.updateWorkflowDocument(update); + } + + /** + * + *@param templateName . + */ + public void changeTemplateName(String templateName) { + //initialize the template + titleBar.setTemplateName(templateName); + } + + /** + * remove the user-added components from the workspace (in the current page) but not from the model + * + */ + public void cleanWorkspace() { + wp.getMainLayout().clear(); + ReportGenerator.get().getScrollerPanel().setScrollPosition(0); + } + + /** + * + * @param toChange . + */ + public void storeChangeInSession(Widget toChange) { + model.storeInSession(); + } + + /** + * + * @param area . + */ + public void disaableTextToolBar(RichTextArea area) { + + } + /** + * used when the resizing textAreas depending on the content + * @param myY a + * @param pixel a + */ + public void shiftComponentsByTextArea(int myY, int pixel) { + int section = model.getCurrentPage(); + List comps = model.getSectionComponent(section); + + if (comps != null) { + for (TemplateComponent tc : comps) { + if (tc.getType() != ComponentType.FAKE_TEXTAREA) { + if (tc.getY() > myY) { + GWT.log("FOUND " + tc.getX() + ", " + tc.getY(), null); + GWT.log("pixel " + pixel , null); + int newY = tc.getY()+pixel;// : tc.getY()-pixel; + // + tc.setY(newY); + GWT.log("moveWidget " + tc.getX() + ", " + tc.getY(), null); + moveWidget(tc.getContent(), tc.getX(),newY); + GWT.log("MOVED " + tc.getX() + ", " + tc.getY(), null); + } + } + //Window.alert("myY - tc.getY() " + myY + ", " + tc.getY()); + + } + } + + } + + /** + * + * @param toMove . + * @param left . + * @param top . + */ + public void moveWidget(Widget toMove, int left, int top) { + //wp.getMainLayout().add(toMove); + wp.moveWidget(toMove, left, top); + } + + + /** + * Import a Section in the View and in the Model + * @param toLoad the SerializableModel instance where toget the section + * @param sectionNoToimport section to import 0 -> n-1 + * @param beforeSection say where to import this section (before) + * @param asLastSection say to import this section as last section in the curren template / report + */ + public void importSection(SerializableModel toLoad, int sectionNoToimport, int beforeSection, boolean asLastSection) { + model.importSectionInModel(toLoad, sectionNoToimport, beforeSection, asLastSection); + if (asLastSection) + seekLastPage(); + else + seekSection(beforeSection); + Window.alert("Importing Complete"); + } + + /** + * in case someone imported a new section + */ + public void seekLastPage() { + while (! (model.getCurrentPage() == model.getTotalPages()) ) + nextPageButtonClicked(); + } + + /** + * in case someone imported a new section + * @param sect2Seek . + */ + public void seekSection(int sect2Seek) { + loadFirstSection(); + while (! ( model.getCurrentPage() == sect2Seek) ) + nextPageButtonClicked(); + } + + /** + * enable the format text toolbar for the given Rich Textarea passed as argument + * @param d4sArea the enabled text area + */ + public void enableTextToolBar(RichTextArea d4sArea) { + + RichTextToolbar rtbar = new RichTextToolbar(d4sArea, false, getCommands() ); + if (menuForWorkflowDocument) //disable open and save buttons from the toolbar + rtbar.enableCommands(false); + currentSelectedToolbar = rtbar; + rtbar.setEnabled(true); + ReportGenerator.get().getToolbarPanel().clear(); + SimplePanel deco = new SimplePanel(); + deco.add(rtbar); + deco.setSize("100%", "25"); + rtbar.setWidth("100%"); + ReportGenerator.get().getToolbarPanel().add(deco); + } + + /** + * enable the format text toolbar for the given Rich Textarea passed as argument + * @param d4sArea the enabled text area + */ + public void enableBiblioEntry(RichTextArea d4sArea) { + ReportGenerator.get().getHeader().enableBiblioEntry(d4sArea); + } + + /** + * generate the docx to be passed to the fimesExporter + * @param model + */ + public void generateFiMES(final TemplateModel model) { +// GWT.log("generateFiMES"); +// MessageBox.show(new MessageBoxConfig() { { +// setMsg("Processing report, please wait ..."); +// setProgressText("pre-processining phase"); +// setWidth(300); +// setWait(true); +// setWaitConfig(new WaitConfig() { +// { +// setInterval(500); +// } +// }); +// } +// }); +// final SerializableModel toSend = model.getSerializableModel(); +// +// model.getModelService().generateTempDocx(toSend, new AsyncCallback() { +// public void onFailure(Throwable caught) { +// MessageBox.hide(); +// MessageBox.alert("There were problems on Server: " + caught.getMessage()); +// } +// +// public void onSuccess(String result) { +// MessageBox.hide(); +// if (result.compareTo("ERROR") == 0) +// MessageBox.alert("There were problems on Server, conversion failed"); +// else { +// MessageBox.hide(); +// String filename = toSend.getTemplateName().replaceAll(".d4sR", ""); +// GWT.log("____>>>>>"+filename); +// final FimesExporterPopup pp = new FimesExporterPopup(eventBus, result, filename); +// GWT.log("____>>>>>pp.isFinished()="+pp.isFinished()); +// } +// } +// }); + } + /** + * + * @param model . + * @param type . + */ + public void generateManifestation(final TemplateModel model, final ExportManifestationType type) { + boolean cont = true; + if (type == ExportManifestationType.HTML && model.containsLargeTS()) { + cont = Window.confirm("Exporting Large Time Series in HTML format can take up to minutes. (about 30 secs for 500 rows)\ndo you want to continue?"); + } + + //continue after warning the user on exporting large TSs + if (cont) { + final int left = Window.getClientWidth() / 2 - 200; + final int top = Window.getClientHeight() / 2 + 100; + final LoadingPopup loading = new LoadingPopup(true); + loading.setPopupPosition(left, top); + //loading.setStyleName("none"); + + + AsyncCallback callback = new AsyncCallback() { + + public void onFailure(Throwable caught) { + //MessageBox + MessageBox.alert("", "Failed to export: " + caught.getMessage(), null); + + } + + public void onSuccess(Boolean result) { + //MessageBox.hide(); + if (result) { + refreshWorkspace(); + + + + final GCubeDialog popupPanel = new GCubeDialog(); + popupPanel.setText("Exporting result"); + String exportedName = model.getTemplateName(); + exportedName = exportedName.replaceAll(".d4sR", ""); + exportedName = exportedName.replaceAll(".d4sT", ""); + + final String urlToOpen = model.getExportedFileURL(type, exportedName); + + VerticalPanel dlgPanel = new VerticalPanel(); + dlgPanel.setSpacing(5); + dlgPanel.add(new HTML("The Report " + exportedName + " (" + type +") has been successfully saved
in your workspace root folder", true)); + CellPanel bPanel = new HorizontalPanel(); + Button close = new Button("close"); + Button preview = new Button("Open"); + bPanel.add(close); + bPanel.add(preview); + bPanel.setWidth("100%"); + + bPanel.setSpacing(5); + bPanel.setCellWidth(close, "50%"); + bPanel.setCellWidth(preview, "50%"); + bPanel.setCellHorizontalAlignment(close, HasHorizontalAlignment.ALIGN_CENTER); + bPanel.setCellHorizontalAlignment(preview, HasHorizontalAlignment.ALIGN_CENTER); + + close.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + popupPanel.hide(); + } + }); + preview.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + Window.open(urlToOpen, model.getTemplateName(), ""); + } + }); + dlgPanel.add(bPanel); + + popupPanel.setAnimationEnabled(true); + popupPanel.setPopupPosition(left, top); + popupPanel.setWidget(dlgPanel); + popupPanel.show(); + } + else { + MessageBox.alert("", "Server reported errors on exporting Format", null); + } + } + + }; + + SerializableModel toSend = model.getSerializableModel(); + model.getModelService().generateManifestation(toSend, type, callback); +//TODO: +// MessageBox.show(new MessageBoxConfig() { +// { +// setMsg("Processing report, please wait ..."); +// setProgressText("exporting ..."); +// setWidth(300); +// setWait(true); +// setWaitConfig(new WaitConfig() { +// { +// setInterval(1000); +// } +// }); +// } +// }); + } + } + + public void openAddCitationDialog() { + AddBiblioEntryDialog dlg = new AddBiblioEntryDialog(eventBus); + dlg.show(); + } + + public void openManageCitationsDialog() { + DeleteCitationsDialog dlg = new DeleteCitationsDialog(eventBus, model.getSection(model.getTotalPages())); + dlg.show(); + } + + /** + * + * @return . + */ + public Headerbar getHeader() { + return header; + } + + + /** + * + * @return . + */ + public TemplateModel getModel() { + return model; + } + + /** + * + * @return . + */ + public ToolboxPanel getToolBoxPanel() { + return toolBoxPanel; + } + + /** + * + * @return . + */ + public WorkspacePanel getWp() { + return wp; + } + + /** + * called when nextPage Button is Clicked + */ + public void nextPageButtonClicked() { + cleanWorkspace(); + //refresh the current page in the model + model.setCurrentPage(model.getCurrentPage() + 1); + + //refresh the current page in the UI + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + + //read the previous user added elements to the template page from the model and place them back in the UI + placeTemplatePageElements(model.getCurrentPage()); + + if (model.getCurrentPage() == model.getTotalPages()) + titleBar.hideNextButton(); + else + titleBar.showNextButton(); + + if (model.getCurrentPage() == 1) + titleBar.hidePrevButton(); + else + titleBar.showPrevButton(); + } + + /** + * load the template to edit in the MODEL and in the VIEW + * @param templateToOpen the name of the template to open without extension nor path + * @param templateObjectID the id in the folder of the template to open + * @param isTemplate true if you are opening a template false if you are opening a report + */ + public void openTemplate(String templateToOpen, String templateObjectID, final boolean isTemplate) { + AsyncCallback callback = new AsyncCallback() { + + public void onFailure(Throwable caught) { + Window.alert("Could not Load template, please try again later: " + caught.getMessage()); + + } + + public void onSuccess(SerializableModel toLoad) { + if (toLoad.getPageWidth() == TemplateModel.OLD_TEMPLATE_WIDTH) { + if (isTemplate) + Window.alert("OPS! we think you are trying to open a previuos version template, only gCube Templates 1.5+ are supported"); + else + Window.alert("OPS! we think you are trying to open a previuos version Report, only gCube Reports 1.5+ are supported"); + } + else + loadModel(toLoad); + } + }; + + //will asyncrously return a SerializableModel instance read from disk + model.getModelService().readModel(templateToOpen, templateObjectID, isTemplate, false, callback); + } + /** + * load the template to edit in the MODEL and in the VIEW + * @param serializedpath the temp file to open + */ + public void openImportedFimesXML(String serializedpath) { + model.getModelService().readImportedModel(serializedpath, new AsyncCallback() { + public void onFailure(Throwable caught) { + Window.alert("Could not Load report, please try again later: " + caught.getMessage()); + } + public void onSuccess(SerializableModel toLoad) { + loadModel(toLoad); + } + }); + } + + /** + * + * @param toLoad + */ + private void loadModel(SerializableModel toLoad) { + //reset the UI + cleanAllNotSession(); + + //load the serializable model in my Model + model.loadModel(toLoad, this); + + wp.setModel(model); + + titleBar.setTemplateName(model.getTemplateName()); + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + resizeWorkingArea(model.getPageWidth(), model.getPageHeight()); + + addTextToolBar(); + int currPage = model.getCurrentPage(); + //load the UI components of the current page + GWT.log("READ CURR PAGE"+currPage, null); + placeTemplatePageElements(currPage); + + //if there is more than one page place in the UI the next page button + if (currPage < model.getTotalPages()) { + titleBar.showNextButton(); + } + if (currPage > 1) + titleBar.showPrevButton(); + + } + + private void loadFirstSection() { + //reset the UI + cleanWorkspace(); + titleBar.hideNextButton(); + titleBar.hidePrevButton(); + model.setCurrentPage(1); + + + titleBar.setTemplateName(model.getTemplateName()); + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + + addTextToolBar(); + int currPage = model.getCurrentPage(); + //load the UI components of the current page + GWT.log("READ CURR PAGE"+currPage, null); + placeTemplatePageElements(currPage); + + //if there is more than one page place in the UI the next page button + if (currPage < model.getTotalPages()) { + titleBar.showNextButton(); + } + if (currPage > 1) + titleBar.showPrevButton(); + + } + + /** + * It places back the user added widgets (TemplateComponents) in the page + * + * @param section . the section number of the wanted TemplateComponent(s) + */ + + public void placeTemplatePageElements(int section) { + if (! (model.getSectionComponent(section) == null)) { + List pageElems = model.getSectionComponent(section); + + for (TemplateComponent component : pageElems) { + GWT.log("Reading component.. " + component.getType(), null); + + int uiX = component.getX(); + int uiY= component.getY(); + switch (component.getType()) { + case HEADING_1: + case HEADING_2: + case HEADING_3: + case TITLE: + if (component.isLocked()) { + HTML text = (HTML) component.getContent(); + wp.addComponentToLayout(text, component.isDoubleColLayout()); + } + else { + BasicTextArea textArea = (BasicTextArea) component.getContent(); + textArea.getMyInstance().setTop(uiY); + textArea.getMyInstance().setLeft(uiX); + wp.addComponentToLayout(textArea, component.isDoubleColLayout()); + } + + break; + case BODY: + if (component.isLocked()) { + HTML text = (HTML) component.getContent(); + wp.addComponentToLayout(text, component.isDoubleColLayout()); + } + else { + D4sRichTextarea textArea = (D4sRichTextarea) component.getContent(); + textArea.getMyInstance().setTop(uiY); + textArea.getMyInstance().setLeft(uiX); + wp.addComponentToLayout(textArea, component.isDoubleColLayout()); + } + + break; + case STATIC_IMAGE: + ImageArea imgToPlace = (ImageArea) component.getContent(); + wp.addComponentToLayout(imgToPlace, component.isDoubleColLayout()); + break; + case DYNA_IMAGE: + DroppingArea imageDropping = (DroppingArea) component.getContent(); + wp.addComponentToLayout(imageDropping, component.isDoubleColLayout()); + break; + case FAKE_TEXTAREA: + break; + case TOC: + ReportTextArea dp = (ReportTextArea) component.getContent(); + wp.addComponentToLayout(dp, component.isDoubleColLayout()); + setCurrCursorPos(uiY); + break; + case BIBLIO: + ReportTextArea dp2 = (ReportTextArea) component.getContent(); + wp.addComponentToLayout(dp2, component.isDoubleColLayout()); + setCurrCursorPos(uiY); + break; + case PAGEBREAK: + ReportTextArea dp3 = (ReportTextArea) component.getContent(); + wp.addComponentToLayout(dp3, component.isDoubleColLayout()); + setCurrCursorPos(uiY); + break; + case TIME_SERIES: + TSArea dp5 = (TSArea) component.getContent(); + wp.addComponentToLayout(dp5, component.isDoubleColLayout()); + setCurrCursorPos(uiY); + break; + case FLEX_TABLE: + GenericTable gt = (GenericTable) component.getContent(); + GWT.log("Reading TABLE rows: " + gt.getRowsNo() + " cols: " + gt.getCols()); + wp.addComponentToLayout(gt, component.isDoubleColLayout()); + break; + case ATTRIBUTE: + AttributeArea at = (AttributeArea) component.getContent(); + wp.addComponentToLayout(at, component.isDoubleColLayout()); + setCurrCursorPos(uiY); + break; + case COMMENT: + HTML text = (HTML) component.getContent(); + wp.addComponentToLayout(text, component.isDoubleColLayout()); + break; + case INSTRUCTION: + HTML instr = (HTML) component.getContent(); + wp.addComponentToLayout(instr, component.isDoubleColLayout()); + break; + } + } + } + } + + /** + * + * @param y . + */ + public void setCurrCursorPos(int y) { + this.currFocus = y; + } + public Coords getInsertionPoint() { + int y = getSelectedIndex(); + return new Coords(25, y); + } + public int getSelectedIndex() { + return currFocus; + } + /** + * called when prevPage Button is Clicked + */ + + public void prevPageButtonClicked() { + cleanWorkspace(); + //refresh the current page in the model + model.setCurrentPage(model.getCurrentPage() - 1); + + //refresh the current page in the UI + titleBar.setPageDisplayer(model.getCurrentPage(), model.getTotalPages()); + + //read the previous user added elements to the template page from the model and place them back in the UI + placeTemplatePageElements(model.getCurrentPage()); + + if (model.getCurrentPage() == model.getTotalPages()) + titleBar.hideNextButton(); + else + titleBar.showNextButton(); + + if (model.getCurrentPage() == 1) + titleBar.hidePrevButton(); + else + titleBar.showPrevButton(); + } + + /** + * Resize the template componet just the model + * + * @param toResize . + * @param newWidth . + * @param newHeight . + */ + public void resizeTemplateComponentInModel(Widget toResize, int newWidth, int newHeight) { + model.resizeModelComponent(toResize, newWidth, newHeight); + } + + /** + * @param width . + * @param height . + */ + public void resizeWorkingArea(int width, int height) { + //save the new state ---> TO MODEL + model.setPageWidth(width); + model.setPageHeight(height); + + //apply the change ---> TO VIEW + wp.resizeWorkspace(width, height); + } + /** + * + * @param header . + */ + public void setHeader(Headerbar header) { + this.header = header; + } + /** + * + * @param toolBoxPanel It's the tool box panel + */ + public void setToolBoxPanel(ToolboxPanel toolBoxPanel) { + this.toolBoxPanel = toolBoxPanel; + } + /** + * + * @param wp . + */ + public void setWp(WorkspacePanel wp) { + this.wp = wp; + } + /** + * + * @return the scope in which the application is running on + */ + public String getCurrentScope() { + return currentScope; + } + + /** + * + * @return the user username who is using the application + */ + public String getCurrentUser() { + return currentUser; + } + + /** + * + * @return . + */ + public TitleBar getTitleBar() { + return titleBar; + } + /** + * refresh the root in the workspace + */ + public void refreshWorkspace() { + toolBoxPanel.refreshRoot(); + } + /** + * + * @return the current selected rich text area + */ + public RichTextToolbar getCurrentSelected() { + return currentSelectedToolbar; + } + + public void setMenuForWorkflowDocument(boolean enable) { + menuForWorkflowDocument = enable; + } + + public boolean getMenuForWorkflowDocument() { + return menuForWorkflowDocument; + } + + public void setAreaForBiblio(RichTextArea d4sArea) { + areaForBiblio = d4sArea; + } + + + public void showReportStructure() { + FimesReportTreePanel panel = new FimesReportTreePanel(eventBus, model.getSerializableModel(), ToolboxPanel.TOOLBOX_WIDTH+"px", ToolboxPanel.TOOLBOX_HEIGHT+"px"); + final com.extjs.gxt.ui.client.widget.Window window = new com.extjs.gxt.ui.client.widget.Window(); + window.setTitle("Report Structure"); + window.setClosable(true); + window.setResizable(false); + window.setWidth(ToolboxPanel.TOOLBOX_WIDTH); + window.setHeight(ToolboxPanel.TOOLBOX_HEIGHT); + window.setPlain(true); + window.setLayout(new FitLayout()); + window.add(panel); + panel.getElement().getStyle().setBackgroundColor("#FFF"); + window.setPosition(0, this.getToolBoxPanel().getAbsoluteTop()); + window.show(); + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportConstants.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportConstants.java new file mode 100644 index 0000000..c648288 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportConstants.java @@ -0,0 +1,32 @@ +package org.gcube.portlets.user.reportgenerator.client; + +import com.google.gwt.core.client.GWT; +/** + * Simply a class containing Static Constants + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version november 2008 (0.1) + */ +public class ReportConstants { + + /** + * tell if you running in eclipse or not + */ + public static final boolean isDeployed = true; + + /** + * + */ + public static final String LOADING_BAR = GWT.getModuleBaseURL() + "../images/loading-bar.gif"; + + /** + * + */ + public static final String IMAGE_NEXT_PAGE = GWT.getModuleBaseURL() + "../images/next_p.gif"; + /** + * + */ + public static final String IMAGE_PREV_PAGE = GWT.getModuleBaseURL() + "../images/prev_p.gif"; + + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportGenerator.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportGenerator.java new file mode 100644 index 0000000..e6e9fbf --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportGenerator.java @@ -0,0 +1,403 @@ +package org.gcube.portlets.user.reportgenerator.client; + +import org.gcube.portlets.user.guidedtour.client.GCUBEGuidedTour; +import org.gcube.portlets.user.guidedtour.client.steps.GCUBETemplate1Text1Image; +import org.gcube.portlets.user.guidedtour.client.steps.GCUBETemplate2Text2Image; +import org.gcube.portlets.user.guidedtour.client.steps.TourStep; +import org.gcube.portlets.user.guidedtour.client.types.ThemeColor; +import org.gcube.portlets.user.guidedtour.client.types.VerticalAlignment; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.toursteps.Intro; +import org.gcube.portlets.user.workspace.client.AppControllerExplorer; +import org.gcube.portlets.user.workspace.client.rpc.GWTWorkspaceServiceAsync; +import org.gcube.portlets.user.workspace.lighttree.client.ItemType; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupEvent; +import org.gcube.portlets.user.workspace.lighttree.client.event.PopupHandler; +import org.gcube.portlets.user.workspace.lighttree.client.load.WorkspaceLightTreeLoadPopup; + +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.RunAsyncCallback; +import com.google.gwt.event.logical.shared.ResizeEvent; +import com.google.gwt.event.logical.shared.ResizeHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.VerticalPanel; + + + +/** + * Entry point classes define onModuleLoad(). + * + * + * ReportGen class is the Entry point class, defines the main layout of the UI + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version June 2011 (3.0) + */ +public class ReportGenerator implements EntryPoint { + + /** + * + */ + public static final int HEADER_HEIGHT = 25; + /** + * + */ + public static final int PAGE_LEFT = 5; + /** + * + */ + public static final int TOOLBOX_LEFT = 15; + /** + * + */ + public static final int TEMPLATE_LEFT = 230; + /** + * + */ + public static final int TEMPLATE_TOP = HEADER_HEIGHT + 60; + /** + * + */ + public static ReportGenerator singleton = null; + /** + * + * @return . + */ + public static ReportGenerator get() { + return singleton; + } + /** + * the controller + */ + private Presenter presenter; + + private VerticalPanel mainLayout = new VerticalPanel(); + + private ToolboxPanel toolBoxPanel; + + private Headerbar header; + + private TitleBar titlebar; + + private WorkspacePanel workSpacePanel; + + private VerticalPanel eastPanel = new VerticalPanel(); + + private VerticalPanel toolbarPanel = new VerticalPanel(); + + private ScrollPanel bottomScrollerPanel = new ScrollPanel(); + + private AppControllerExplorer treeController; + + private HTML divHidden = new HTML(); + /** + * This is the entry point method. + */ + public void onModuleLoad() { + singleton = this; + presenter = new Presenter(); + treeController = new AppControllerExplorer(); + mainLayout.setWidth("100%"); + mainLayout.setHeight("100%"); + // + workSpacePanel = new WorkspacePanel(presenter); + titlebar = new TitleBar(presenter); + header = new Headerbar(presenter); + toolBoxPanel = new ToolboxPanel(treeController); + + presenter.setHeader(header); + presenter.setTitleBar(titlebar); + presenter.setWp(workSpacePanel); + presenter.setToolBoxPanel(toolBoxPanel); + + mainLayout.add(titlebar); + mainLayout.add(header); + mainLayout.add(toolbarPanel); + + toolbarPanel.setWidth("100%"); + toolbarPanel.setHeight("40"); + + + CellPanel cellPanel = new HorizontalPanel(); + cellPanel.setStyleName("cella"); + cellPanel.add(toolBoxPanel); + cellPanel.add(bottomScrollerPanel); + + cellPanel.setCellWidth(toolBoxPanel, "230"); + + mainLayout.add(cellPanel); + + divHidden.setStyleName("d4sFrame"); + divHidden.setWidth("500"); + divHidden.setStyleName("d4sRichTextArea"); + divHidden.addStyleName("setVisibilityOff"); + divHidden.addStyleName("hasRichTextToolbar"); + + eastPanel.add(workSpacePanel); + eastPanel.add(divHidden); + bottomScrollerPanel.add(eastPanel); + presenter.addTextToolBar(); + + // Add image and button to the RootPanel + RootPanel.get("ReportGeneratorDIV").add(mainLayout); + + int scrollerWidth = Window.getClientWidth()- TEMPLATE_LEFT - 30; + bottomScrollerPanel.setPixelSize(scrollerWidth, 1000); + + if ( Window.getClientWidth() < 1070 ) { + int scrollerWidth2 = Window.getClientWidth()- TEMPLATE_LEFT; + bottomScrollerPanel.setPixelSize(scrollerWidth2, 1000); + } + + Window.addResizeHandler(new ResizeHandler() { + public void onResize(ResizeEvent event) { + int scrollerHeight = event.getHeight() - bottomScrollerPanel.getAbsoluteTop(); + if (scrollerHeight < toolBoxPanel.getTreePanelHeight()) + scrollerHeight = toolBoxPanel.getTreePanelHeight(); + int scrollerWidth = Window.getClientWidth()- TEMPLATE_LEFT - 30; + bottomScrollerPanel.setPixelSize(scrollerWidth , 1000); + + + if ( Window.getClientWidth() < 1060 ) { + int scrollerWidth2 = Window.getClientWidth()- TEMPLATE_LEFT; + bottomScrollerPanel.setPixelSize(scrollerWidth2, 1000); + } + } + + }); + + showGuidedTour() ; + + } + private void showGuidedTour() { + + GWT.runAsync(GCUBEGuidedTour.class, new RunAsyncCallback() { + public void onSuccess() { + TourStep step1 = new GCUBETemplate1Text1Image(true) { + + @Override + public String setStepTitle() { + return "gCube Reporting"; + } + + @Override + public String setStepImage() { + return "images/tour/tour1.jpg"; + } + + @Override + public String setStepBody() { + return new Intro().getHTML(); + } + }; + + TourStep step2 = new GCUBETemplate1Text1Image(false) { + + @Override + public String setStepTitle() { + return "Structure View"; + } + + @Override + public String setStepImage() { + return "images/tour/tour2.jpg"; + } + @Override + public String setStepBody() { + return "
" + + "
" + + "Use the Report Structure View to see your report structure. (View > Structure)" + + "
" + + "
" + + "Use the Report Structure View to navigate through your report." + + "
" + + "
"; + } + }; + TourStep step3 = new GCUBETemplate2Text2Image(false) { + + @Override + public String setStepTitle() { + return "User Comments"; + } + + @Override + public String setStepImage() { + return "images/tour/tourComment.jpg"; + } + + @Override + public String setStepBody() { + return "
" + + "
" + + "Use comments to collaborate with your colleagues." + + "
" + + "
"; + } + + @Override + public String setStepOtherImage() { + return "images/tour/tourFormat.jpg"; + } + + @Override + public String setStepOtherBody() { + return "
" + + "
" + + "Format text as you would in a word processor using the Formatting Bar." + + "
" + + "
"; + } + }; + TourStep step4 = new GCUBETemplate1Text1Image(false) { + + @Override + public String setStepTitle() { + return "Bibliography"; + } + + @Override + public String setStepImage() { + return "images/tour/tourBiblio.jpg"; + } + + @Override + public String setStepBody() { + return "
" + + "
" + + "Use the Bibliography to add references" + + "
" + + "
"; + } + }; + + TourStep step5 = new GCUBETemplate1Text1Image(false) { + + @Override + public String setStepTitle() { + return "Export"; + } + + @Override + public String setStepImage() { + return "images/tour/tourExports.jpg"; + } + + @Override + public String setStepBody() { + return "
" + + "
" + + "Generate different export formats such as OpenXML (docx) or HTML." + + "
" + + "
"; + } + }; + //step1.setTextVerticalAlignment(VerticalAlignment.ALIGN_MIDDLE); + step2.setTextVerticalAlignment(VerticalAlignment.ALIGN_MIDDLE); + step3.setTextVerticalAlignment(VerticalAlignment.ALIGN_MIDDLE); + step4.setTextVerticalAlignment(VerticalAlignment.ALIGN_MIDDLE); + step5.setTextVerticalAlignment(VerticalAlignment.ALIGN_MIDDLE); + String guideUrl = "https://gcube.wiki.gcube-system.org/gcube/index.php/Common_Functionality#Report_Generation"; + GCUBEGuidedTour gt = new GCUBEGuidedTour("gCube Reports Generator", ReportGenerator.class.getName(), guideUrl, 780, 450, false); + gt.addStep(step1); + gt.addStep(step2); + gt.addStep(step3); + gt.addStep(step4); + gt.addStep(step5); + gt.openTour(); + } + + public void onFailure(Throwable reason) { + Window.alert("There are networks problem, please check your connection."); + } + }); + + } + + /** + * + * @return . + */ + public VerticalPanel getMainLayout() { + return mainLayout; + } + + /** + * + * @return . + */ + public Headerbar getHeader() { + return header; + } + /** + * + * @return . + */ + public WorkspacePanel getWorkSpacePanel() { + return workSpacePanel; + } + + /** + * + * @return . + */ + public ToolboxPanel getToolBoxPanel() { + return toolBoxPanel; + } + + public GWTWorkspaceServiceAsync getWSTreeService() { + return treeController.getRpcWorkspaceService(); + } + + + /** + * + * @return . + */ + public VerticalPanel getToolbarPanel() { + return toolbarPanel; + } + + /** + * + * @param toolbarPanel . + */ + public void setToolbarPanel(VerticalPanel toolbarPanel) { + this.toolbarPanel = toolbarPanel; + } + + /** + * + * @return . + */ + public TitleBar getTitleHeader() { + return titlebar; + } + + /** + * + * @return . + */ + public HTML getDivHidden() { + return divHidden; + } + + /** + * + * @param divHidden . + */ + public void setDivHidden(HTML divHidden) { + this.divHidden = divHidden; + } + + public ScrollPanel getScrollerPanel() { + return bottomScrollerPanel; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportService.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportService.java new file mode 100644 index 0000000..62a748e --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportService.java @@ -0,0 +1,91 @@ +package org.gcube.portlets.user.reportgenerator.client; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType; +import org.gcube.portlets.user.reportgenerator.shared.SessionInfo; + +import com.google.gwt.user.client.rpc.RemoteService; +/** + * Service interface for server communication + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version november 2008 (0.1) + */ + +public interface ReportService extends RemoteService{ + /** + * return the first ten records of the timeseries having id as param + * @param sTS . + * @return . + */ + SerializableTable getSampleTimeSeries(SerializableTimeSeries sTS); + /** + * + * @return . + */ + String[] getUserTemplateNames(); + /** + * @param templateName . + * @param templateObjectID . + * @param isTemplate says if you're opening a template or a report + * @param isImporting says if your importing or youre loading a template in the UI + * @return . + */ + SerializableModel readModel(String templateName, String templateObjectID, boolean isTemplate, boolean isImporting); + + + /** + * + * @param model . + * @param type . + * @return . + */ + boolean generateManifestation(SerializableModel model, ExportManifestationType type); + + /** + * each portlet instance runs in a scope + * each portlet instance is used by a unique username from within the portal + * @param currentHost . + * @return a SessionInfo bean containing the username the scope andis opening a workflow document or not + */ + SessionInfo getSessionInfo(String currentHost); + + /** + * + * @param model . + */ + void storeTemplateInSession(SerializableModel model); + + + /** + * + * @return the model previously stored in the session + */ + SerializableModel readTemplateFromSession(); + + /** + * the report model is taken from the session + * @param folderid the basket id where to save the report + */ + void saveReport(String folderid, String newname); + + /** + * the report model is taken from the session, the id also + */ + void saveReport(); + + SerializableModel getWorkflowDocumentFromDocumentLibrary(); + + void updateWorkflowDocument(boolean update); + + void renewLock(); + + String generateTempDocx(SerializableModel model); + /** + * + * @param tempPath + * @return + */ + SerializableModel readImportedModel(String tempPath); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportServiceAsync.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportServiceAsync.java new file mode 100644 index 0000000..6643e4d --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ReportServiceAsync.java @@ -0,0 +1,87 @@ +package org.gcube.portlets.user.reportgenerator.client; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType; +import org.gcube.portlets.user.reportgenerator.shared.SessionInfo; + +import com.google.gwt.user.client.rpc.AsyncCallback; +/** + * * Service interface for server Async communication + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version november 2011 (3.0) + */ + +public interface ReportServiceAsync { + /** + * return the first ten records of the timeseries having id as param + * @param sTS . + * @param callback . + */ + void getSampleTimeSeries(SerializableTimeSeries sTS, AsyncCallback callback); + /** + * + * @param callback . + */ + void getUserTemplateNames(AsyncCallback callback); + + /** + * + * @param templateName . + * @param templateObjectID . + * @param isTemplate says if you're opening a template or a report + * @param isImporting says if your importing or youre loading a template in the UI + * @param callback . + */ + void readModel(String templateName, String templateObjectID, boolean isTemplate, boolean isImporting, AsyncCallback callback); + + + + /** + * @param model . + * @param type . + * @param callback . + */ + void generateManifestation(SerializableModel model, ExportManifestationType type, AsyncCallback callback); + + /** + * + * @param model . + * @param callback . + */ + void storeTemplateInSession(SerializableModel model, AsyncCallback callback); + /** + * + * call for the model previously stored in the session + * @param callback . + */ + void readTemplateFromSession( AsyncCallback callback); + + /** + * @param callback . + * @param folderid . + */ + void saveReport(String folderid, String newname, AsyncCallback callback); + + /** + * + * @param callback . + */ + void saveReport(AsyncCallback callback); + /** + * + * @param currentHost + * @param callback + */ + void getSessionInfo(String currentHost, AsyncCallback callback); + void getWorkflowDocumentFromDocumentLibrary( + AsyncCallback callback); + void updateWorkflowDocument(boolean update, AsyncCallback callback); + void renewLock(AsyncCallback callback); + void generateTempDocx(SerializableModel model, + AsyncCallback callback); + void readImportedModel(String tempPath, + AsyncCallback callback); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/TitleBar.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/TitleBar.java new file mode 100644 index 0000000..c6617e3 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/TitleBar.java @@ -0,0 +1,202 @@ +package org.gcube.portlets.user.reportgenerator.client; + +import java.util.Date; + +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.i18n.client.DateTimeFormat; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasAlignment; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; + + /** + * TitleBar class is the top top bar component of the UI + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version July 2011 (3.0) + */ + public class TitleBar extends Composite{ + + + private Presenter presenter; + + /** + * the template Model + */ + private TemplateModel templateModel; + + /** + * mainLayout Panel + */ + private CellPanel mainLayout = new HorizontalPanel(); + + /** + * contains the current template name + */ + private HTML templateNameBox = new HTML(); + + /** + * contains the last edit date and the the last edit person username + */ + private HTML editedOn = new HTML(); + /** + * contains the page displayer + */ + private HTML pageDisplayer = new HTML(); + + + private HTML prevButton = new HTML(" ", true); + private HTML nextButton = new HTML("    ", true); + + + /** + * Constructor + * @param c the controller instance for this UI component + */ + public TitleBar(Presenter c) { + this.presenter = c; + this.templateModel = presenter.getModel(); + + + //initialize the template + setTemplateName(templateModel.getTemplateName()); + + setPageDisplayer(1, 1); + + + mainLayout.setSize("90%", "24px"); +// mainLayout.setStyleName("newresultset-header"); + + + + //design the part for the template name and the pages handling + + HorizontalPanel captionPanel = new HorizontalPanel(); + HorizontalPanel innerCaptionPanel = new HorizontalPanel(); + captionPanel.setWidth("100%"); + + //hide the buttons at the beginning + nextButton.addStyleName("setVisibilityOff"); + prevButton.addStyleName("setVisibilityOff"); + + HorizontalPanel pageHandlerPanel = new HorizontalPanel(); + pageHandlerPanel.setHeight("24"); + pageHandlerPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); + + pageHandlerPanel.add(prevButton); + pageHandlerPanel.add(pageDisplayer); + pageHandlerPanel.add(nextButton); + pageHandlerPanel.setWidth("100%"); + + templateNameBox.setStyleName("menubar-font"); + + captionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); + innerCaptionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); + innerCaptionPanel.setVerticalAlignment(HasAlignment.ALIGN_BOTTOM); + innerCaptionPanel.add(templateNameBox); + innerCaptionPanel.add(editedOn); + captionPanel.add(innerCaptionPanel); + mainLayout.add(captionPanel); + mainLayout.add(pageHandlerPanel); + editedOn.setStyleName("docEditedBy"); + mainLayout.setCellHorizontalAlignment(captionPanel, HasHorizontalAlignment.ALIGN_LEFT); + + mainLayout.setCellWidth(pageHandlerPanel, "200"); + initWidget(mainLayout); + + nextButton.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { presenter.nextPageButtonClicked(); + } + }); + + prevButton.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { presenter.prevPageButtonClicked(); } + }); + } + + /** + * changes the pages label in the UI : e.g. Page x of y + * @param currentPage . + * @param totalPages . + */ + public void setPageDisplayer(int currentPage, int totalPages) { + pageDisplayer.setHTML("Section "+ currentPage + " of " + totalPages); + } + + /** + * changes the template name label in the UI + * @param name . + */ + public void setTemplateName(String name) { + templateNameBox.setHTML("  " + name); + } + + /** + * changes the template name label in the UI + * @param username . + * @param date . + */ + public void setEditedOnBy(Date date, String username) { + String dt = DateTimeFormat.getShortDateFormat().format(date); + + editedOn.setHTML("  edited on " + dt + "  by " + username); + } + /** + * Shows the previous botton in the UI + */ + public void showPrevButton() { + prevButton.removeStyleName("setVisibilityOff"); + prevButton.addStyleName("setVisibilityOn"); + } + /** + * Shows the next botton in the UI + */ + public void showNextButton() { + nextButton.removeStyleName("setVisibilityOff"); + nextButton.addStyleName("setVisibilityOn"); + } + + /** + * Hide the previous botton in the UI + */ + public void hidePrevButton() { + prevButton.removeStyleName("setVisibilityOn"); + prevButton.addStyleName("setVisibilityOff"); + } + /** + * Hide the next botton in the UI + */ + public void hideNextButton() { + nextButton.removeStyleName("setVisibilityOn"); + nextButton.addStyleName("setVisibilityOff"); + } + /** + * temporary command + * @return the command instance + */ + public Command getNullCommand() { + Command openNothing = new Command() { + + public void execute() { + Window.alert("Feature not supported yet"); + + } + }; + + return openNothing; + } + + + } + + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/ToolboxPanel.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ToolboxPanel.java new file mode 100644 index 0000000..2837cd9 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/ToolboxPanel.java @@ -0,0 +1,53 @@ +package org.gcube.portlets.user.reportgenerator.client; + +// +//import org.gcube.portlets.user.workspace.client.tree.WorkspaceTreePanel; +//import org.gcube.portlets.user.workspace.client.workspace.GWTWorkspace; + +import org.gcube.portlets.user.workspace.client.AppControllerExplorer; +import org.gcube.portlets.user.workspace.client.view.tree.AsyncTreePanel; + +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.SimplePanel; + +/** + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * + * @version April 2012 (1.1) + */ + +public class ToolboxPanel extends SimplePanel { + private AppControllerExplorer appController; + /** + * + */ + public static final int TOOLBOX_WIDTH = 235; + /** + * + */ + public static final int TOOLBOX_HEIGHT= 800; + + /** + * constructor + */ + public ToolboxPanel(AppControllerExplorer appController) { + this.appController = appController; + AsyncTreePanel tp = appController.getTree(TOOLBOX_WIDTH, TOOLBOX_HEIGHT); + add(tp); + } + + /** + * refresh the root + */ + public void refreshRoot() { + appController.refreshRoot(); + } + /** + * lalala + * @return the toolbox height + */ + public int getTreePanelHeight() { + return TOOLBOX_HEIGHT; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/WorkspacePanel.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/WorkspacePanel.java new file mode 100644 index 0000000..1f38199 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/WorkspacePanel.java @@ -0,0 +1,160 @@ +package org.gcube.portlets.user.reportgenerator.client; + + + +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel; +import org.gcube.portlets.user.reportgenerator.client.targets.DoubleColumnPanel; + +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.Widget; + + +/** + * WorkspacePanel class is the UI Component for displaying the template + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ + +public class WorkspacePanel extends Composite { + /** + * the model + */ + private TemplateModel templateModel; + + /** + * the controller + */ + private Presenter presenter; + /** + * + */ + public static WorkspacePanel singleton = null; + + + /** + * used to place two compoenents on the same Y + */ + private boolean waitForNextOne = false; + + /** + * elements arrive one by one, to place two on the same Y this bufferedWidget is used; + */ + private Widget bufferedWidget; + /** + * + * @return . + */ + public static WorkspacePanel get() { + return singleton; + } + + /** + * the panel for the layout of the working space + */ + private FlowPanel mainLayout = new FlowPanel(); + + /** + * + * @param c the controller instance + */ + public WorkspacePanel(Presenter c) { + singleton = this; + presenter = c; + + templateModel = presenter.getModel(); + + mainLayout.setSize(""+templateModel.getPageWidth(), ""+templateModel.getPageHeight()); + + //mainLayout.setStyleName("wpFlow"); + //mainLayout.addStyleName("position-relative"); + + + initWidget(mainLayout); + + + } + + /** + * + * @param w . + * @param isDoubleColumnLayout . + */ + public void addComponentToLayout(Widget w, boolean isDoubleColumnLayout) { + waitForNextOne = isDoubleColumnLayout; + + if (! waitForNextOne) { + mainLayout.add(w); + bufferedWidget = null; + } + else { + if (bufferedWidget == null) + bufferedWidget = w; + else { + DoubleColumnPanel toAdd = new DoubleColumnPanel(bufferedWidget, w); + mainLayout.add(toAdd); + bufferedWidget = null; + } + } + //mainLayout.add(w, x, y); + } + + /** + * + * @param w the widget to remove + * @return true if the romove is successfull + */ + public boolean removeComponentFromLayout(Widget w) { + return mainLayout.remove(w); + } + + /** + * + * @param model . + */ + public void setModel(TemplateModel model ) { + this.templateModel = model; + } + + /** + * resizes the workspace panel + * @param width . + * @param height . + */ + public void resizeWorkspace(int width, int height) { + mainLayout.setPixelSize(width, height); + } + + /** + * + * @param toMove . + * @param left . + * @param top . + */ + public void moveWidget(Widget toMove, int left, int top) { + // mainLayout.setWidgetPosition(toMove, left, top); +// GWT.log("MOVED? " + top, null); + } + + /** + * + * @param toResize the widget to resize + * @param newWidth . + * @param newHeight . + */ + public void resizeWidget(Widget toResize, int newWidth, int newHeight) { + toResize.setPixelSize(newWidth, newHeight); + } + + /** + * + * @return . + */ + public FlowPanel getMainLayout() { + return mainLayout; + } + +} + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/components/FancyFileUpload.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/components/FancyFileUpload.java new file mode 100644 index 0000000..115f9fa --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/components/FancyFileUpload.java @@ -0,0 +1,492 @@ +package org.gcube.portlets.user.reportgenerator.client.components; + +import org.gcube.portlets.user.reportgenerator.client.dialog.ImageUploaderDialog; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ChangeListener; +import com.google.gwt.user.client.ui.ChangeListenerCollection; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FileUpload; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.FormHandler; +import com.google.gwt.user.client.ui.FormPanel; +import com.google.gwt.user.client.ui.FormSubmitCompleteEvent; +import com.google.gwt.user.client.ui.FormSubmitEvent; +import com.google.gwt.user.client.ui.HasText; +import com.google.gwt.user.client.ui.HasWordWrap; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.SourcesChangeEvents; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * FancyFileUpload class is use to upload images from client in the UI + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ +public class FancyFileUpload extends Composite implements HasText, HasWordWrap, SourcesChangeEvents{ + + /** + * State definitions + */ + public final int EMPTY_STATE = 1; + /** + * + */ + public final int PENDING_STATE = 2; + /** + * + */ + public final int UPLOADING_STATE = 3; + /** + * + */ + public final int UPLOADED_STATE = 4; + /** + * + */ + public final int DELETED_STATE = 5; + /** + * + */ + public final int FAILED_STATE = 6; + + /** + * Initial State of the widget. + */ + private int widgetState = EMPTY_STATE; + + /** + * Default delay to check an empty FileUpload widget for + * arrival of a filename. + * + */ + private int searchUpdateDelay = 500; + + /** + * Default delay for pending state, when delay over the form is +submitted. + */ + private int pendingUpdateDelay = 5000; + + /** + * the panel where this widget is in + */ + private ImageUploaderDialog theOwner; + + + /** + * OK message expected from file upload servlet to indicate successful +upload. + */ + //private String retursOKMessage = "
OK
"; + + private FormPanel uploadForm = new FormPanel(); + private VerticalPanel mainPanel = new VerticalPanel(); + + /** + * Internal timer for checking fileupload text for a value. + */ + private Timer t; + + /** + * Internal timer for checking if pending delay is over. + */ + private Timer p; + + /** + * Widget representing file to be uploaded. + */ + private UploadDisplay uploadItem; + + /** + * FileName to be uploaded + */ + String fileName = ""; + + + /** + * Class used for the display of filename to be uploaded, + * and handling the update of the display states. + * + * + */ + protected class UploadDisplay extends Composite{ + + /** + * FileUpload Widget + */ + FileUpload uploadFileWidget = new FileUpload(); + + /** + * Label to display after file widget is filled with a filename + */ + Label uploadFileName = new Label(); + + + /** + * Panel to hold the widget + */ + FlowPanel mainPanel = new FlowPanel(); + + /** + * Panel to hold pending, loading, loaded or failed state details. + */ + HorizontalPanel pendingPanel = new HorizontalPanel(); + + /** + * Constructor + * + */ + public UploadDisplay(){ + + mainPanel.add(uploadFileWidget); + pendingPanel.add(uploadFileName); + uploadFileName.setStyleName("HTMLObjectStyle-font"); + uploadFileName.setWordWrap(true); + uploadFileWidget.setWidth("100%"); + + mainPanel.add(pendingPanel); + pendingPanel.setVisible(false); + initWidget(mainPanel); + } + + /** + * Set the widget into pending mode by altering style + * of pending panel and displaying it. Hide the FileUpload + * widget and finally set the state to Pending. + * + */ + private void setPending(){ + uploadFileName.setText("Please wait, fetching image from your file system.. ");//uploadFileWidget.getFilename()); + uploadFileWidget.setVisible(false); + pendingPanel.setVisible(true); + pendingPanel.setStyleName("fancyfileupload-pending"); + widgetState = PENDING_STATE; + } + + /** + * Set the widget into Loading mode by changing the style name + * and updating the widget State to Uploading. + * + */ + private void setLoading(){ + pendingPanel.setStyleName("fancyfileupload-loading"); + widgetState = UPLOADING_STATE; + } + + /** + * Set the widget to Loaded mode by changing the style name + * and updating the widget State to Loaded. + * + */ + private void setLoaded(){ + pendingPanel.setStyleName("fancyfileupload-loaded"); + uploadFileName.setText("Image Successfully uploaded"); + widgetState = UPLOADED_STATE; + } + + + /** + * Set the widget to Failed mode by changing the style name + * and updating the widget State to Failed. + * Additionally, hide the pending panel and display the FileUpload + * widget. + * + */ + private void setFailed(){ + widgetState = FAILED_STATE; + uploadFileName.setText("Operation Failed"); + } + + } + + /** + * Perform the uploading of a file by changing state of display widget + * and then calling form.submit() method. + * + */ + private void uploadFiles(){ + fileName = uploadItem.uploadFileWidget.getFilename(); + + uploadItem.setLoading(); + uploadForm.submit(); + + } + + + /** + * Put the widget into a Pending state, set the Pending delay timer + * to call the upload file method when ran out. + * + */ + private void pendingUpload(){ + // Fire an onChange event to anyone who is listening + uploadItem.setPending(); + p = new Timer(){ + public void run() { + uploadFiles(); + } + }; + p.schedule(pendingUpdateDelay); + } + + /** + * Method to check if FileUpload Widget has a filename within it. + * If so, cancel the timer that was set to call this method and then + * call the pendingUpload() method. + * If not, do nothing. + * + */ + private void checkForFileName(){ +// GWT.log(uploadItem.uploadFileWidget.getFilename()+" :"+fileName,null); +// if (!uploadItem.uploadFileWidget.getFilename().equals("")){ +// if (!uploadItem.uploadFileWidget.getFilename().equals(fileName)){ +// t.cancel(); +// pendingUpload(); +// } +// } + } + + /** + * This method sets up a repeating schedule to call the +checkforfilename + * method to see if the FileUpload widget has any text in it. + * + */ + private void startWaiting(){ + t = null; + t = new Timer(){ + public void run() { + checkForFileName(); + } + }; + t.scheduleRepeating(searchUpdateDelay); + } + + /** + * + * @param owner the caller + * @param templateName . + */ + public FancyFileUpload(ImageUploaderDialog owner, String templateName){ + + this.theOwner = owner; + // Set Form details + // Set the action to call on submit + + uploadForm.setAction(GWT.getModuleBaseURL() + "ImagesUploadServlet?currTemplateName=" + templateName); + + + // Set the form encoding to multipart to indicate a file upload + uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART); + // Set the method to Post + uploadForm.setMethod(FormPanel.METHOD_POST); + uploadForm.setWidget(mainPanel); + + // Create a new upload display widget + uploadItem = new UploadDisplay(); + // Set the name of the upload file form element + uploadItem.uploadFileWidget.setName("uploadFormElement"); + // Add the new widget to the panel. + mainPanel.add(uploadItem); + HorizontalPanel wrapper = new HorizontalPanel(); + wrapper.setSpacing(4); + // Add a 'submit' button. + wrapper.add(new Button("Submit", new ClickListener() { + public void onClick(Widget sender) { + String fName = uploadItem.uploadFileWidget.getFilename(); + + + int slashPosition = fName.lastIndexOf("/"); + + String fileNameToCheck = "" ; + + if (slashPosition == -1) //it is windows + slashPosition = fName.lastIndexOf("\\"); + + if (slashPosition != -1) + fileNameToCheck = fName.substring(slashPosition+1, fName.length()); + + if (fName.equals("")) { + Window.alert("The text box must not be empty"); + } + else if (fileNameToCheck.indexOf(" ") > -1) { + Window.alert("File name cannot contain empty spaces"); + + } + else { + t.cancel(); + pendingUpload(); + } + } + })); + + // Add a 'close' button. + wrapper.add(new Button("Cancel", new ClickListener() { + public void onClick(Widget sender) { + theOwner.hide(); + } + })); + mainPanel.add(wrapper); + + // Start the waiting for a name to appear in the file upload widget. + startWaiting(); + // Initialise the widget. + initWidget(uploadForm); + + // Add an event handler to the form. + uploadForm.addFormHandler(new FormHandler() { + public void onSubmitComplete(FormSubmitCompleteEvent event) { + // Fire an onChange Event + fireChangeEvent(); + // Cancel all timers to be absolutely sure nothing is going on. + t.cancel(); + p.cancel(); + // Ensure that the form encoding is set correctly. + uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART); + // Check the result to see if an OK message is returned from the server. + + if(event.getResults().toString().contains("OK") || event.getResults().toString().startsWith("OK")) { + uploadItem.setLoaded(); + String fName = uploadItem.uploadFileWidget.getFilename(); + + String nameToPass = ""; + if (fName.lastIndexOf("/") == -1) //windows + nameToPass = fName.substring(fName.lastIndexOf("\\")+1); + else + nameToPass = fName.substring(fName.lastIndexOf("/")+1); + + theOwner.insertImage(nameToPass); + theOwner.hide(); + + } else { + // If no, set the widget to failed state. + uploadItem.setFailed(); + Window.alert("There were some errors during File Uploading processing,Please try again"); + } + } + + public void onSubmit(FormSubmitEvent event) { + //No validation in this version. + } + }); + } + + /** + * Fire a change event to anyone listening to us. + * + */ + private void fireChangeEvent(){ + if (changeListeners != null) + changeListeners.fireChange(this); + } + + /** + * Get the text from the widget - which in reality will be retrieving any + * value set in the Label element of the display widget. + * @return . + */ + public String getText() { + return uploadItem.uploadFileName.getText(); + } + + /** + * Cannot set the text of a File Upload Widget, so raise an exception. + * @param text . + */ + public void setText(String text) { + throw new RuntimeException("Cannot set text of a FileUpload Widget"); + } + + /** + * Retrieve the status of the upload widget. + * @return Status of upload widget. + * + */ + public int getUploadState(){ + return widgetState; + } + + /** + * Set the delay for checking for a filename to appear in the FileUpload widget + * Might be useful if there are performance issues. + * @param newDelay . + */ + public void setCheckForFileNameDelay(int newDelay){ + searchUpdateDelay = newDelay; + } + + /** + * Set the delay value indicating how long a file will remain in +pending mode + * prior to the upload action taking place. + * @param newDelay . + */ + public void setPendingDelay(int newDelay){ + pendingUpdateDelay = newDelay; + } + + /** + * Return the delay value set for checking a file. + * @return . + */ + public int getCheckForFileNameDelay(){ + return searchUpdateDelay; + } + + /** + * Return value set for pending delay. + * @return . + */ + public int getPendingDelay(){ + return pendingUpdateDelay; + } + + /** + * Return if the label in the display widget is wordwrapped or not. + * @return . + */ + public boolean getWordWrap() { + return uploadItem.uploadFileName.getWordWrap(); + } + + /** + * Set the word wrap value of the label in the display widget. + * @param wrap . + */ + public void setWordWrap(boolean wrap) { + uploadItem.uploadFileName.setWordWrap(wrap); + } + + /** + * + */ + private ChangeListenerCollection changeListeners; + + /** + * Add a change listener + * @param listener , + */ + public void addChangeListener(ChangeListener listener) { + if (changeListeners == null) + changeListeners = new ChangeListenerCollection(); + changeListeners.add(listener); + } + + /** + * Remove a change listener + * @param listener . + */ + public void removeChangeListener(ChangeListener listener) { + if (changeListeners != null) + changeListeners.remove(listener); + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/AddBiblioEntryDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/AddBiblioEntryDialog.java new file mode 100644 index 0000000..b39f9bd --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/AddBiblioEntryDialog.java @@ -0,0 +1,70 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.user.reportgenerator.client.events.AddBiblioEvent; + +import com.extjs.gxt.ui.client.event.ComponentEvent; +import com.extjs.gxt.ui.client.widget.Dialog; +import com.extjs.gxt.ui.client.widget.Window; +import com.extjs.gxt.ui.client.widget.button.Button; +import com.extjs.gxt.ui.client.widget.form.FormPanel; +import com.extjs.gxt.ui.client.widget.form.TextArea; +import com.extjs.gxt.ui.client.widget.form.TextField; +import com.extjs.gxt.ui.client.widget.layout.FitLayout; +import com.extjs.gxt.ui.client.widget.layout.FormData; +import com.google.gwt.event.shared.HandlerManager; +/** + * The AddBiblioEntryDialog class + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class AddBiblioEntryDialog extends Window { + + public AddBiblioEntryDialog(final HandlerManager eventBus) { + setHeading("Add Citation"); + setClosable(true); + setWidth(400); + setHeight(250); + setPlain(true); + setLayout(new FitLayout()); + + final TextField citekey = new TextField(); + citekey.setFieldLabel("Cite key"); + citekey.setAllowBlank(false); + final TextArea textArea = new TextArea(); + textArea.setFieldLabel("Citation"); + textArea.setAllowBlank(false); + textArea.setHeight(130); + Button addButton = new Button("Add") { + @Override + protected void onClick(final ComponentEvent ce) { + if (citekey.isValid()) { + eventBus.fireEvent(new AddBiblioEvent(citekey.getValue(), textArea.getValue())); + close(); + } + } + }; + + Button cancelButton = new Button("Cancel") { + @Override + protected void onClick(final ComponentEvent ce) { + close(); + } + }; + + addButton(addButton); + addButton(cancelButton); + + FormData formData = new FormData("-10"); + FormPanel formPanel = new FormPanel(); + formPanel.setAutoWidth(true); + formPanel.getHeader().setStyleName("x-hide-panel-header"); + formPanel.setHeaderVisible(false); + formPanel.setLabelWidth(55); + formPanel.setWidth(400); + formPanel.setHeight(250); + formPanel.add(citekey, formData); + formPanel.add(textArea, formData); + add(formPanel); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/CommentDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/CommentDialog.java new file mode 100644 index 0000000..33eed62 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/CommentDialog.java @@ -0,0 +1,86 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.d4sreporting.common.client.ImageConstants; +import org.gcube.portlets.user.reportgenerator.client.events.AddCommentEvent; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedUserCommentEvent; +import org.gcube.portlets.user.reportgenerator.client.targets.ReportTextArea; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.TextArea; +import com.google.gwt.user.client.ui.VerticalPanel; + +public class CommentDialog extends DialogBox { + private static final int PANEL_WIDTH = 200; + + VerticalPanel mainPanel = new VerticalPanel(); + AbsolutePanel header = new AbsolutePanel(); + TextArea area; + + public CommentDialog(final HandlerManager eventBus, final ReportTextArea source, final String username, final String previousComment, int areaHeight) { + super(true); + setStyleName("comment-popup"); + area = new TextArea(); + if (previousComment != null && !(previousComment.compareTo("") == 0)) { + area.setText(previousComment); + } else { + area.setText(" - " + username+":\n"); + } + if (areaHeight > 0) { + area.setPixelSize(PANEL_WIDTH, areaHeight); + } else { + area.setPixelSize(PANEL_WIDTH, 85); + } + setSize(PANEL_WIDTH+"px", "100px"); + header.setPixelSize(PANEL_WIDTH, 15); + final Image enterImage = new Image(ImageConstants.IMAGE_ARROW_ENTER); + final Image closeImage = new Image(ImageConstants.IMAGE_CLOSE_15x15); + final Image binImage = new Image(ImageConstants.IMAGE_BIN); + closeImage.setStyleName("selectable"); + binImage.setStyleName("selectable"); + enterImage.setStyleName("selectable"); + header.add(enterImage, PANEL_WIDTH-46, -2); + header.add(binImage, PANEL_WIDTH-27, 0); + header.add(closeImage, PANEL_WIDTH-12, 3); + binImage.setTitle("Discard this comment"); + closeImage.setTitle("Close and save"); + enterImage.setTitle("Add another comment"); + + area.setStyleName("comment-popup-textarea"); + + header.setStyleName("comment-popup-header"); + mainPanel.add(header); + mainPanel.add(area); + add(mainPanel); + + enterImage.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + area.setText(area.getText() + "\n______\n"+username+":\n"); + area.setPixelSize(PANEL_WIDTH, area.getOffsetHeight()+70); + } + }); + + closeImage.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + eventBus.fireEvent(new AddCommentEvent(source, area.getText(), area.getOffsetHeight())); + source.addCommentView(); + hide(); + } + }); + + binImage.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + eventBus.fireEvent(new RemovedUserCommentEvent(source)); + source.removeCommentView(); + hide(); + } + }); + + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/DeleteCitationsDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/DeleteCitationsDialog.java new file mode 100644 index 0000000..97bb365 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/DeleteCitationsDialog.java @@ -0,0 +1,92 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import java.util.ArrayList; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.shared.SerializableComponent; +import org.gcube.portlets.user.reportgenerator.client.events.RemovedCitationEvent; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateComponent; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateSection; + +import com.extjs.gxt.ui.client.event.ComponentEvent; +import com.extjs.gxt.ui.client.widget.Component; +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.extjs.gxt.ui.client.widget.TabItem; +import com.extjs.gxt.ui.client.widget.TabPanel; +import com.extjs.gxt.ui.client.widget.Window; +import com.extjs.gxt.ui.client.widget.layout.FitLayout; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.user.client.ui.HTML; +import com.extjs.gxt.ui.client.widget.button.Button; +/** + * The ManageBiblioDialog class + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class DeleteCitationsDialog extends Window { + + TabPanel tabPanel = new TabPanel(); +// + public DeleteCitationsDialog(final HandlerManager eventBus, TemplateSection bibliosection) { + setTitle("Delete Citations"); + setClosable(true); + setWidth(400); + setHeight(250); + setPlain(true); + setLayout(new FitLayout()); + + Button deleteButton = new Button("Delete") { + @Override + protected void onClick(final ComponentEvent ce) { + if (tabPanel.getItemCount() > 1) { + eventBus.fireEvent(new RemovedCitationEvent(tabPanel.getSelectedItem().getTitle())); + tabPanel.remove(tabPanel.getSelectedItem()); + } + else { + MessageBox.alert("","You cannot have a Bibliography with no citations, if you want to remove it use Section > Discard current", null); + } + } + }; +// + Button cancelButton = new Button("Close") { + @Override + protected void onClick(final ComponentEvent ce) { + close(); + } + }; + + addButton(deleteButton); + addButton(cancelButton); +// + ArrayList citations = new ArrayList(); + for (TemplateComponent tc : bibliosection.getAllComponents()) { + if (tc.getType() == ComponentType.BODY) { + SerializableComponent sc = tc.getSerializable(); + citations.add(sc.getPossibleContent().toString()); + } + } + + + for (String cite : citations) { + TabItem tabI = new TabItem(); + HTML html = new HTML(cite.split(" ")[0], true); + String citekey = html.getText(); + if (citekey.endsWith(".")) //remove dot + citekey = citekey.substring(0, citekey.length()-1); + + tabI.setTitle(citekey); + String citation = cite.split(" ")[1]; + tabI.setText(citekey); + tabI.add(new HTML(citation)); + tabI.setClosable(false); + tabPanel.add(tabI); + + //TODO: + + } + add(tabPanel); + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/FimesReportTreePanel.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/FimesReportTreePanel.java new file mode 100644 index 0000000..693f27d --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/FimesReportTreePanel.java @@ -0,0 +1,195 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import java.util.HashMap; +import java.util.List; +import java.util.Vector; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableComponent; +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.d4sreporting.common.shared.SerializableSection; +import org.gcube.portlets.user.reportgenerator.client.events.ItemSelectionEvent; +import org.gcube.portlets.user.reportgenerator.client.resources.FimesReportTreeStructureResources; + +import com.google.gwt.event.logical.shared.SelectionEvent; +import com.google.gwt.event.logical.shared.SelectionHandler; +import com.google.gwt.event.shared.HandlerManager; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.Tree; +import com.google.gwt.user.client.ui.TreeItem; +import com.google.gwt.user.client.ui.Widget; + + +public class FimesReportTreePanel extends ScrollPanel{ + + public FimesReportTreePanel(final HandlerManager eventBus, final SerializableModel report, + final String height, final String width) { + + this.setWidth(width); + this.setHeight(height); + + Tree t = new Tree(); + t.setAnimationEnabled(true); + t.addItem(loadReportRootTree(report)); + t.addSelectionHandler(new SelectionHandler() { + + @SuppressWarnings("unchecked") + public void onSelection(SelectionEvent event) { + // TODO Auto-generated method stub + TreeItem item = event.getSelectedItem(); + HashMap map = (HashMap)item.getUserObject(); + eventBus.fireEvent(new ItemSelectionEvent(map)); + } + }); + + this.add(t); + } + + private TreeItem loadReportRootTree(final SerializableModel report) { + // Add root node + ImageResource image = FimesReportTreeStructureResources.INSTANCE.root(); + HorizontalPanel node = createNodeWidget(image, report.getTemplateName(),"gwt-label-rootTree"); + TreeItem root = new TreeItem(node); + + Vector sections = report.getSections(); + for(int i = 1; i <= sections.size(); i++) { + SerializableSection s = sections.get(i - 1); + // Add section item + image = FimesReportTreeStructureResources.INSTANCE.section(); + node = createNodeWidget(image, "Section" + i,"gwt-label-sectionTree"); + + TreeItem sectionItem = addChildItemToParentItem(root, "Section", Integer.toString(i -1), node); + addItemsComponent(sectionItem, s); + + } + + return root; + } + + private void addItemsComponent(final TreeItem sectionItem,final SerializableSection sectionModel) { + + List components = sectionModel.getComponents(); + for(int i = 0; i < components.size(); i++) { + SerializableComponent c = components.get(i); + + HorizontalPanel node = null; + switch (c.getType()) { + case TITLE: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.heading1(); + node = createNodeWidget(image, (String)c.getPossibleContent(),"gwt-label-componentTree"); + break; + } + case HEADING_1: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.heading1(); + node = createNodeWidget(image, (String)c.getPossibleContent(),"gwt-label-componentTree"); + break; + } + case HEADING_2: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.heading2(); + node = createNodeWidget(image, (String)c.getPossibleContent(),"gwt-label-componentTree"); + break; + } + case HEADING_3: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.heading3(); + node = createNodeWidget(image, (String)c.getPossibleContent(),"gwt-label-componentTree"); + break; + } + case HEADING_4: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.heading4(); + node = createNodeWidget(image, (String)c.getPossibleContent(),"gwt-label-componentTree"); + break; + } + case INSTRUCTION: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.instructions(); + node = createNodeWidget(image, "Instruction","gwt-label-componentTree"); + break; + } + case COMMENT: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.comments(); + node = createNodeWidget(image, "Comment","gwt-label-componentTree"); + break; + } + case BODY: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.text(); + node = createNodeWidget(image, "Text","gwt-label-componentTree"); + break; + } + case DYNA_IMAGE: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.image(); + node = createNodeWidget(image, "Image","gwt-label-componentTree"); + break; + } + case FLEX_TABLE: { + ImageResource image = FimesReportTreeStructureResources.INSTANCE.table(); + node = createNodeWidget(image, "Table","gwt-label-componentTree"); + break; + } + case ATTRIBUTE: { + // TODO + ImageResource image = FimesReportTreeStructureResources.INSTANCE.comments(); + node = createNodeWidget(image, "Attribute","gwt-label-componentTree"); + break; + } + case TOC: + // TODO + // componentItem = new TreeItem("TOC"); + break; + case PAGEBREAK: + // TODO + // componentItem = new TreeItem("Pagebreak"); + break; + case TIME_SERIES: + // TODO + //componentItem = new TreeItem("Time_Series"); + break; + } + + if (node != null) + addChildItemToParentItem(sectionItem, "Component", + Integer.toString(i), node); + + } + } + + private TreeItem addChildItemToParentItem(final TreeItem root, final String typeItem, + final String indexList, final Widget content) { + + TreeItem item = new TreeItem(content); + // Create userObjet + HashMap map = new HashMap(); + map.put("item",typeItem ); + map.put("index", indexList); + map.put("parent", root.getUserObject()); + item.setUserObject(map); + root.addItem(item); + return item; + } + + /** + * Generates HTML for a tree item with an attached icon. + * @param imageResource the image resource to use + * @param title the title of the item + * @return the resultant HTML + */ + private HorizontalPanel createNodeWidget(ImageResource imageResource, String title, + String cssStyle) { + HorizontalPanel node = new HorizontalPanel(); + + node.setSpacing(0); + Image image = new Image(imageResource); + image.setPixelSize(image.getWidth() + 5, image.getHeight()); + node.add(image); + + String shortTitle = title; + if (shortTitle.length() > 25) + shortTitle = shortTitle.substring(0,25) + "..."; + + Label text = new Label(shortTitle); + text.setStyleName(cssStyle); + node.add(text); + return node; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImageUploaderDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImageUploaderDialog.java new file mode 100644 index 0000000..838b304 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImageUploaderDialog.java @@ -0,0 +1,210 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.components.FancyFileUpload; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ChangeListener; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.RadioButton; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * ImageUploaderDialog class is the Dialog for uploading images + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ +public class ImageUploaderDialog extends DialogBox { + + private int width; + private int height; + + private Presenter presenter; + + + private String currTemplateName = ""; + + private HorizontalPanel topLabel = new HorizontalPanel(); + + private EventListener listener = new EventListener(); + private RadioButton local = new RadioButton(""); + private RadioButton web = new RadioButton(""); + + /** + * the container panel + */ + private VerticalPanel mainLayout = new VerticalPanel(); + private VerticalPanel dialogPanel = new VerticalPanel(); + + + + /** + * Creates the dialog + * @param presenter my controller + */ + public ImageUploaderDialog(Presenter presenter) { + + + // Create a dialog box and set the caption text + this.width = 400; + this.height = 200; + this.presenter = presenter; + setText("Insert Image"); + + local.setHTML(" From this computer"); + topLabel.add(local); + local.setChecked(true); + + web.setHTML(" From the web (URL)"); + topLabel.add(web); + web.addClickListener(listener); + local.addClickListener(listener); + + currTemplateName = presenter.getModel().getTemplateName(); + + + + dialogPanel.add(getFromLocalPanel()); + dialogPanel.setPixelSize(this.width, this.height); + + mainLayout.add(topLabel); + mainLayout.add(dialogPanel); + setWidget(mainLayout); + + } + + private VerticalPanel getFromLocalPanel() { + VerticalPanel toReturn = new VerticalPanel(); + FancyFileUpload uploader = new FancyFileUpload(this, currTemplateName); + HTML theLabel = new HTML("Browse your computer for the image file to upload:"); + toReturn.add(theLabel); + toReturn.add(uploader); + toReturn.setSpacing(4); + toReturn.setStyleName("uploadDialog"); + toReturn.setPixelSize(this.width, this.height); + + return toReturn; + } + + private VerticalPanel getFromURLPanel() { + VerticalPanel toReturn = new VerticalPanel(); + + toReturn.setSpacing(5); + + HTML theLabel = new HTML("Enter image web address:"); + final TextBox urlTextbox = new TextBox(); + urlTextbox.setWidth("90%"); + + final HTML previewBox = new HTML("

Image preview will be displayed here.

*Remember: Using others' images on the web without their permission may be bad manners, or worse, copyright infringement.

", true); + previewBox.setStyleName("imagePreviewBox"); + + toReturn.add(theLabel); + toReturn.add(urlTextbox); + toReturn.add(previewBox); + + urlTextbox.addChangeListener(new ChangeListener() { + + public void onChange(Widget sender) { + previewBox.setHTML(""); + previewBox.removeStyleName("imagePreviewBox"); + } + + }); + + HorizontalPanel buttonsPanel = new HorizontalPanel(); + + + + buttonsPanel.add(new Button("Insert", new ClickListener() { + public void onClick(Widget sender) { + hide(); + presenter.getCurrentSelected().getExtendedFormatter().insertImage(urlTextbox.getText()); + presenter.getModel().storeInSession(); + } + })); + + buttonsPanel.add(new Button("Cancel", new ClickListener() { + public void onClick(Widget sender) { + hide(); + } + })); + + buttonsPanel.setSpacing(5); + toReturn.add(buttonsPanel); + + return toReturn; + } + + /** + * + * @param imageName . + */ + public void insertImage(String imageName) { + String imgURL = getImageURL(imageName, "CURRENT_OPEN"); + presenter.getCurrentSelected().getExtendedFormatter().insertImage(imgURL); + presenter.getModel().storeInSession(); + } + + + + + + + /** + * use an inner EventListener class to avoid exposing event methods on the dialog class itself. + */ + + private class EventListener implements ClickListener { + + public void onClick(Widget sender) { + if (sender == web && web.isChecked()) { + dialogPanel.clear(); + dialogPanel.add(getFromURLPanel()); + } else if (sender == local && local.isChecked()) { + dialogPanel.clear(); + dialogPanel.add(getFromLocalPanel()); + } + + } + + } + + /** + * return a URL which is lookable for on the web + * @param imageName . + * @param templateName . + * @return . + */ + public String getImageURL(String imageName, String templateName) { + String currentUser = presenter.getCurrentUser(); + String currentScope = presenter.getCurrentScope(); + /** + * Images will be stored under webapps/usersArea... + * GWT.getModuleBaseURL() returns * e.g. http://dlib28.isti.cnr.it/templatecreator/html/ + * need to get just http://dlib28.isti.cnr.it/ + */ + //remove "/html/" and get e.g. http://dlib28.isti.cnr.it/templatecreator + String host = GWT.getModuleBaseURL().substring(0, GWT.getModuleBaseURL().length()-6); + + //loog for last slash + int lastSlash = host.lastIndexOf("/"); + + //get what i need : e.g. http://dlib28.isti.cnr.it/ or host = "http://localhost:8080/"; + host = host.substring(0, lastSlash +1 ); + //host = "http://localhost:8080/"; + + String imgURL = host + "usersArea/" + currentScope + "/templates/" + + currentUser + "/" + "CURRENT_OPEN" + "/images/" + imageName; + + return imgURL; + } +} + + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImporterDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImporterDialog.java new file mode 100644 index 0000000..9152090 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/ImporterDialog.java @@ -0,0 +1,180 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.user.reportgenerator.client.ReportConstants; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.workspace.lighttree.client.Item; +import org.gcube.portlets.user.workspace.lighttree.client.ItemType; + +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * ImporterDialog class is is the Dialog for importing template or report sections + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2009 (1.4) + */ +public class ImporterDialog extends DialogBox { + + /** + * this layout panel + */ + private VerticalPanel dialogPanel = new VerticalPanel(); + Image loading = new Image(ReportConstants.LOADING_BAR); + + VerticalPanel toReplace = new VerticalPanel(); + SerializableModel toimportFrom = null; + ListBox listbox = new ListBox(); + + ListBox listboxCurr = new ListBox(); + CheckBox lastSection = new CheckBox(); + + Presenter presenter; + + /** + * + * @param item the item to import + * @param presenter the c + */ + public ImporterDialog(Item item, final Presenter presenter) { + this.presenter = presenter; + + dialogPanel.setSpacing(4); + setText("Import from Template or Report"); + toReplace.setWidth("100%"); + + HTML templateNameLabel = new HTML("Importing Template, please hold ..."); + toReplace.add(templateNameLabel); + toReplace.add(loading); + + + HorizontalPanel buttonsPanel = new HorizontalPanel(); + HorizontalPanel buttonsContainer = new HorizontalPanel(); + + // Add a cancel button at the bottom of the dialog + Button cancelButton = new Button("Close",new ClickListener() { + public void onClick(Widget sender) { hide(); } + }); + + Button applyButton = new Button("Import",new ClickListener() { + public void onClick(Widget sender) { + boolean result = false; + if (lastSection.isChecked()) + result = Window.confirm("You are about to import section " + (listbox.getSelectedIndex()+1) + " as last section in the current document"); + else + result = Window.confirm("You are about to import section " + (listbox.getSelectedIndex()+1) + " before section " + (listboxCurr.getSelectedIndex()+1) + " of the current document"); + + if (result) + presenter.importSection(toimportFrom, listbox.getSelectedIndex()+1, listboxCurr.getSelectedIndex()+1, lastSection.isChecked()); + hide(); + } + }); + + buttonsPanel.setWidth("100%"); + buttonsPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); + buttonsContainer.setSpacing(10); + buttonsContainer.add(applyButton); + buttonsContainer.add(cancelButton); + buttonsPanel.add(buttonsContainer); + + dialogPanel.add(toReplace); + + + dialogPanel.add(buttonsPanel); + dialogPanel.setPixelSize(350, 275); + setWidget(dialogPanel); + + + AsyncCallback callback = new AsyncCallback() { + + public void onFailure(Throwable caught) { + Window.alert("Could not Import template, please try again later: " + caught.getMessage()); + } + public void onSuccess(SerializableModel toLoad) { + importFinished(toLoad); + } + }; + + //then is not deployed mode + if (item == null) { + presenter.getModel().getModelService().readModel("", "", true, true, callback); + } + else { + boolean isTemplate = (item.getType() == ItemType.REPORT_TEMPLATE) ? true : false; + //will asyncrously return a SerializableModel instance read from disk + presenter.getModel().getModelService().readModel(item.getName(), item.getId(), isTemplate, true, callback); + } + } + + + private void importFinished(SerializableModel toLoad) { + HTML label = new HTML("Importing Complete..."); + + Grid grid = new Grid(4, 2); + grid.setWidget(0, 0, new HTML("Name: ")); + grid.setWidget(0, 1, new HTML(toLoad.getTemplateName())); + grid.setWidget(1, 0, new HTML("Author: ")); + grid.setWidget(1, 1, new HTML(toLoad.getAuthor())); + grid.setWidget(2, 0, new HTML("Last Edit: ")); + grid.setWidget(2, 1, new HTML(""+toLoad.getLastEdit())); + grid.setWidget(3, 0, new HTML("Total Sections: ")); + grid.setWidget(3, 1, new HTML(""+toLoad.getTotalPages())); + + toReplace.clear(); + toReplace.add(label); + toReplace.add(grid); + toReplace.add(new HTML("
")); + + + for (int i = 1; i <= toLoad.getTotalPages(); i++) { + listbox.addItem("Section " + i, ""+(i-1)); + } + Grid grid2 = new Grid(1, 2); + grid2.setWidget(0, 0, new HTML("Choose the section to import:   ")); + grid2.setWidget(0, 1, listbox); + grid2.setCellPadding(5); + + + for (int i = 1; i <= presenter.getModel().getTotalPages(); i++) { + listboxCurr.addItem("Section " + i, ""+(i-1)); + } + + + lastSection.addClickListener(new ClickListener() { + + public void onClick(Widget sender) { + CheckBox cb = (CheckBox) sender; + listboxCurr.setEnabled(! cb.isChecked()); + } + + }); + + Grid grid3 = new Grid(2, 2); + grid3.setWidget(0, 0, new HTML("Import Section before:   ")); + grid3.setWidget(0, 1, listboxCurr); + grid3.setWidget(1, 0, new HTML("As last section:   ")); + grid3.setWidget(1, 1, lastSection); + grid3.setCellPadding(5); + + toReplace.add(grid2); + toReplace.add(new HTML("
")); + toReplace.add(grid3); + toimportFrom = toLoad; + + } +} + + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/LoadingPopup.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/LoadingPopup.java new file mode 100644 index 0000000..c1a0fa2 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/LoadingPopup.java @@ -0,0 +1,45 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Widget; + + +/** + * @author massimiliano.assante@isti.cnr.it + * + */ +public class LoadingPopup extends DialogBox implements ClickHandler { + + /** + * @param autoHide auto hide + */ + public LoadingPopup(boolean autoHide) { + super(false); + HTML msg = new HTML(setToDisplay(), true); + setWidget(msg); + } + + + /** + * @return inner html + */ + protected static String setToDisplay() { + return + "
"+ + ""+ + ""+ + "
"+ + ""+ + "
" ; + } + + public void onClick(ClickEvent event) { + hide(); + + } +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/PagePropertiesDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/PagePropertiesDialog.java new file mode 100644 index 0000000..03c448e --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/PagePropertiesDialog.java @@ -0,0 +1,110 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + + + +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.CellPanel; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * OpenTemplateDialog class is is the Dialog for showing template properties + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ +public class PagePropertiesDialog extends GCubeDialog { + + /** + * this layout panel + */ + private VerticalPanel dialogPanel = new VerticalPanel(); + + private TextBox templateNameLabelBox = new TextBox(); + + + /** + * + * @param templateModel . + * @param presenter . + */ + public PagePropertiesDialog(final TemplateModel templateModel, final Presenter presenter) { + setText("Report Properties"); + dialogPanel.setSpacing(4); + + HTML spacer = new HTML("
"); + spacer.setHeight("30"); + + /* + * template name part + */ + HTML templateNameLabel = new HTML("Template Name: "); + + + templateNameLabelBox.setText(templateModel.getTemplateName()); + templateNameLabelBox.setReadOnly(true); + + templateNameLabelBox.setWidth("200"); + CellPanel templateNamaPanel = new HorizontalPanel(); + templateNamaPanel.add(templateNameLabel); + templateNamaPanel.add(templateNameLabelBox); + templateNamaPanel.setCellWidth(templateNameLabel, "120"); + + + + dialogPanel.add(templateNamaPanel); + + dialogPanel.add(new HTML("
")); + + List metadatas = presenter.getModel().getMetadata(); + int nRows = metadatas.size(); + Grid metadataGrid = new Grid(nRows, 2); + int i = 0; + for (Metadata md : metadatas) { + metadataGrid.setWidget(i, 0, new HTML("" + md.getAttribute() + ": ")); + metadataGrid.setWidget(i, 1, new HTML(md.getValue())); + i++; + } + + dialogPanel.add(templateNamaPanel); + + dialogPanel.add(new HTML("
")); + + dialogPanel.add(metadataGrid); + + HorizontalPanel buttonsPanel = new HorizontalPanel(); + HorizontalPanel buttonsContainer = new HorizontalPanel(); + + // Add a cancel button at the bottom of the dialog + Button cancelButton = new Button("Close",new ClickHandler() { + public void onClick(ClickEvent event) { + hide(); + } + }); + + buttonsPanel.setWidth("100%"); + buttonsPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); + buttonsContainer.setSpacing(10); + buttonsContainer.add(cancelButton); + buttonsPanel.add(buttonsContainer); + + + dialogPanel.add(buttonsPanel); + dialogPanel.setPixelSize(350, 275); + setWidget(dialogPanel); + + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TSHeader.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TSHeader.java new file mode 100644 index 0000000..d2d9661 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TSHeader.java @@ -0,0 +1,112 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Widget; + + +/** + * + * @author massi + * + */ +public class TSHeader extends HorizontalPanel { + + private CheckBox myCB; + private HTML myHeader; + private int myColNo; + private FlexTable myTable; + TimeSeriesFilter caller; + TSHeader myinstance; + + /** + * @param tsf - + * @param myTable . + * @param cb . + * @param myColNo . + * @param myHeader . + */ + public TSHeader(TimeSeriesFilter tsf, FlexTable myTable, CheckBox cb, int myColNo, HTML myHeader) { + super(); + myinstance = this; + caller = tsf; + this.myTable = myTable; + this.myCB = cb; + + this.myColNo = myColNo; + this.myHeader = myHeader; + setVerticalAlignment(ALIGN_MIDDLE); + myHeader.setStyleName("timeSeries_header_font"); + add(myHeader); + add(myCB); + + myCB.addClickListener(cbListener); + } + + private void removeEmptyHeaders( FlexTable myTable) { + + for (int i = 0; i < myTable.getCellCount(0); i++) { + if (myTable.getWidget(0, i) == null) { + myTable.removeCell(0, i); + myTable.removeCell(1, i); + } + } + + } + + ClickListener cbListener = new ClickListener() { + public void onClick(Widget sender) { + caller.removeHeader(myinstance); + myTable.remove(sender.getParent()); + removeEmptyHeaders(myTable); + } + }; + /** + * + * @return . + */ + public CheckBox getMyCB() { + return myCB; + } + /** + * + * @param myCB . + */ + public void setMyCB(CheckBox myCB) { + this.myCB = myCB; + } + /** + * + * @return . + * */ + public HTML getMyHeader() { + return myHeader; + } + /** + * + * @param myHeader . + */ + public void setMyHeader(HTML myHeader) { + this.myHeader = myHeader; + } + /** + * + * @return . + */ + public int getMyColNo() { + return myColNo; + } + + /** + * + * @param myColNo . + */ + public void setMyColNo(int myColNo) { + this.myColNo = myColNo; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesDialog.java new file mode 100644 index 0000000..03e4133 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesDialog.java @@ -0,0 +1,81 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableTSinfo; + +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * + * @author massi + * + */ +public class TimeSeriesDialog extends DialogBox { + + /** + * + * @param droppedTS . + */ + public TimeSeriesDialog(SerializableTSinfo droppedTS) { + setText(droppedTS.getTitle() + " Details"); + String name = droppedTS.getTitle(); + String description = droppedTS.getTimeSeriesDescription(); + String creator = droppedTS.getCreator(); + String date = droppedTS.getTimeSeriesCreationDate(); + long rowsNo = droppedTS.getDimension(); + String publisher = droppedTS.getPublisher(); + String rights = droppedTS.getRights(); + + Grid metadata = new Grid(7, 2); + metadata.setWidget(0, 0, new HTML("Name:", true)); + metadata.setWidget(0, 1, new HTML(name)); + metadata.setWidget(1, 0, new HTML("Creation Date: ", true)); + metadata.setWidget(1, 1, new HTML(date)); + metadata.setWidget(2, 0, new HTML("Total rows number: ", true)); + metadata.setWidget(2, 1, new HTML(""+rowsNo)); + metadata.setWidget(3, 0, new HTML("Description:", true)); + metadata.setWidget(3, 1, new HTML(description)); + metadata.setWidget(4, 0, new HTML("Creator: ", true)); + metadata.setWidget(4, 1, new HTML(creator)); + metadata.setWidget(5, 0, new HTML("publisher: ", true)); + metadata.setWidget(5, 1, new HTML(""+publisher)); + metadata.setWidget(5, 0, new HTML("rights: ", true)); + metadata.setWidget(5, 1, new HTML(""+rights)); + + ScrollPanel scroller = new ScrollPanel(); + VerticalPanel main_panel = null; + main_panel = new VerticalPanel(); + main_panel.addStyleName("bgBlank p8 font_family font_12"); + + scroller.add(metadata); + + // PopupPanel is a SimplePanel, so you have to set it's widget property to + // whatever you want its contents to be. + Button close = new Button("Close"); + close.addClickListener(new ClickListener() { + public void onClick(Widget arg0) { + hide(); + } + }); + main_panel.add(scroller); + main_panel.add(new HTML("
")); + main_panel.add(close); + scroller.setPixelSize(350, 200); + main_panel.setPixelSize(350, 200); + setWidget(main_panel); + } + + /** + * + */ + public void show() { + super.show(); + center(); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesFilter.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesFilter.java new file mode 100644 index 0000000..b77c444 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesFilter.java @@ -0,0 +1,217 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import java.util.LinkedList; +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.client.CommonConstants; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTSFilter; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTSinfo; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.targets.TSArea; + +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ChangeListener; +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.TextBox; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * + * @author massi + * + */ +public class TimeSeriesFilter extends DialogBox { + ScrollPanel scroller = new ScrollPanel(); + TextBox from = new TextBox(); + TextBox to = new TextBox(); + FlexTable flexTable = new FlexTable(); + + List compoundHeaders = new LinkedList(); + /** + * + * @param sts a ts + * @param caller . + */ + public TimeSeriesFilter(final TSArea caller, final SerializableTimeSeries sts) { + + final SerializableTSinfo droppedTS = sts.getTsMetadata(); + + setText(droppedTS.getTitle() + " Filter"); + String name = droppedTS.getTitle(); + long rowsNo = droppedTS.getDimension(); + + + Grid metadata = new Grid(2, 2); + metadata.setWidget(0, 0, new HTML("Name:", true)); + metadata.setWidget(0, 1, new HTML(name)); + metadata.setWidget(1, 0, new HTML("Total rows : ", true)); + metadata.setWidget(1, 1, new HTML(""+rowsNo)); + + + final VerticalPanel main_panel = new VerticalPanel(); + main_panel.addStyleName("bgBlank p8 font_family font_12"); + + main_panel.add(metadata); + + List headersString = droppedTS.getHeaderLabels(); + + /** + */ + for (int i = 0; i < headersString.size(); i++) { + CheckBox toAdd = new CheckBox(); + toAdd.setChecked(true); + compoundHeaders.add(new TSHeader(this, flexTable, toAdd, i, new HTML(headersString.get(i) ))); + } + + + main_panel.add(new HTML("Selected fields: (click to remove)")); + + flexTable = getTableHeader(compoundHeaders); + main_panel.add(flexTable); + + main_panel.add(new HTML("Select rows interval:")); + + from.setText("1"); + to.setText("10"); + to.setMaxLength(6); + from.setMaxLength(6); + from.addChangeListener(textBoxListener); + to.addChangeListener(textBoxListener); + + + Grid rowsInterval = new Grid(1, 4); + rowsInterval.setWidget(0, 0, new HTML("From row:")); + rowsInterval.setWidget(0, 1, from); + rowsInterval.setWidget(0, 2, new HTML("  To row:")); + rowsInterval.setWidget(0, 3, to); + + main_panel.add(rowsInterval); + + main_panel.add(new HTML("
")); + HorizontalPanel buttonspanel = new HorizontalPanel(); + buttonspanel.setHeight("50"); + buttonspanel.setSpacing(3); + + + + + // PopupPanel is a SimplePanel, so you have to set it's widget property to + // whatever you want its contents to be. + Button close = new Button("Close"); + close.addClickListener(new ClickListener() { + public void onClick(Widget arg0) { + hide(); + } + }); + + Button apply = new Button("Apply"); + apply.addClickListener(new ClickListener() { + public void onClick(Widget arg0) { + List selectedCols = compoundHeaders; + + List colsToShow = new LinkedList(); + + for (TSHeader head : selectedCols) { + colsToShow.add(new Integer(head.getMyColNo())); + } + int fromInt = Integer.parseInt(from.getText()); + int toInt = Integer.parseInt(to.getText()); + + SerializableTSFilter toSet = new SerializableTSFilter(colsToShow, null, null, fromInt, toInt); + caller.setNewFilter(toSet); + caller.refreshHeaders(); + hide(); + } + }); + +// Button reset = new Button("Reset"); +// close.addClickListener(new ClickListener() { +// public void onClick(Widget arg0) { +// hide(); +// show(); +// } +// }); + + //buttonspanel.add(reset); + buttonspanel.add(close); + buttonspanel.add(apply); + main_panel.add(buttonspanel); + + scroller.setPixelSize(550, 280); + main_panel.setPixelSize(550, 260); + + scroller.add(main_panel); + setWidget(scroller); + } + + + /** + * + * @param toRemove . + * @return . + */ + public boolean removeHeader(TSHeader toRemove) { + return compoundHeaders.remove(toRemove); + } + + + /** + * display the header of the ts + * @param droppedTS + * @return + */ + private FlexTable getTableHeader(List headers) { + flexTable.clear(); + int n = headers.size(); + + for (int i = 0; i < n ; i++) { + flexTable.getCellFormatter().setStyleName(0, i, "timeSeries_header"); + flexTable.setWidget(0, i, headers.get(i)); + flexTable.getCellFormatter().setStyleName(1, i, "timeSeries_td"); + flexTable.setWidget(1, i, new HTML("...")); + } + + return flexTable; + } + + ChangeListener textBoxListener = new ChangeListener() { + + public void onChange(Widget sender) { + TextBox tb = (TextBox) sender; + String text = tb.getText(); + String checkedText = text; + text = text.replaceAll(CommonConstants.ACCEPTED_CHARS_JUST_NUM, ""); + if (! text.equals(checkedText) ) { + Window.alert("Only numbers are accepted"); + tb.setText(text); + } + int start = Integer.parseInt(from.getText()); + int end = Integer.parseInt(to.getText()); + + if (start >= end) { + Window.alert("From must be greater than to"); + to.setText(""+(start+10)); + } + + } + + + }; + /** + * + */ + public void show() { + super.show(); + center(); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesSampleDialog.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesSampleDialog.java new file mode 100644 index 0000000..dd61af7 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/dialog/TimeSeriesSampleDialog.java @@ -0,0 +1,75 @@ +package org.gcube.portlets.user.reportgenerator.client.dialog; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.ClickListener; +import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.ScrollPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * + * @author massi + * + */ +public class TimeSeriesSampleDialog extends DialogBox { + /** + * + * @param table . + */ + public TimeSeriesSampleDialog(SerializableTable table) { + super(true); + setText("TS Sample"); + FlexTable flexTable = new FlexTable(); + + VerticalPanel main_panel = null; + main_panel = new VerticalPanel(); + main_panel.addStyleName("bgBlank p8 font_family font_12"); + + for (int i = 0; i < table.getRowCount(); i++) { + for (int j= 0; j < table.getColsNo(); j++){ + if (i == 0) { + flexTable.getCellFormatter().setStyleName(i, j, "timeSeries_header"); + flexTable.setWidget(i, j, new HTML(table.getValue(i, j).getContent())); + } + else { + flexTable.getCellFormatter().setStyleName(i, j, "timeSeries_td"); + flexTable.setWidget(i, j, new HTML(table.getValue(i, j).getContent())); + } + } + } + + main_panel.add(flexTable); + + // PopupPanel is a SimplePanel, so you have to set it's widget property to + // whatever you want its contents to be. + Button close = new Button("Close"); + close.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + hide(); + } + }); + + main_panel.add(new HTML("
")); + main_panel.add(close); + ScrollPanel scroller = new ScrollPanel(); + main_panel.setPixelSize(550, 340); + scroller.setPixelSize(550, 360); + scroller.add(main_panel); + setWidget(scroller); + } + + /** + * + */ + public void show() { + super.show(); + center(); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEvent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEvent.java new file mode 100644 index 0000000..a583ecb --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEvent.java @@ -0,0 +1,32 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.GwtEvent; + +public class AddBiblioEvent extends GwtEvent{ + public static Type TYPE = new Type(); + private final String citekey; + private final String citetext; + + public AddBiblioEvent(String key, String text) { + citekey = key; + citetext = text; + } + + public String getCitekey() { + return citekey; + } + + public String getCitetext() { + return citetext; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(AddBiblioEventHandler handler) { + handler.onAddCitation(this); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEventHandler.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEventHandler.java new file mode 100644 index 0000000..4eeedf9 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddBiblioEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface AddBiblioEventHandler extends EventHandler { + void onAddCitation(AddBiblioEvent event); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEvent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEvent.java new file mode 100644 index 0000000..4bd9faf --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEvent.java @@ -0,0 +1,43 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import org.gcube.portlets.user.reportgenerator.client.targets.ReportTextArea; + +import com.google.gwt.event.shared.GwtEvent; + +public class AddCommentEvent extends GwtEvent{ + public static Type TYPE = new Type(); + private final ReportTextArea source; + private final String comment; + private final int areaHeight; + + + + public AddCommentEvent(ReportTextArea sourceComponent, String comment, int areaHeight) { + super(); + this.source = sourceComponent; + this.comment = comment; + this.areaHeight = areaHeight; + } + + public int getAreaHeight() { + return areaHeight; + } + + public ReportTextArea getSourceComponent() { + return source; + } + + public String getComment() { + return comment; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(AddCommentEventHandler handler) { + handler.onAddComment(this); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEventHandler.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEventHandler.java new file mode 100644 index 0000000..b2d1d08 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/AddCommentEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface AddCommentEventHandler extends EventHandler { + void onAddComment(AddCommentEvent event); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEvent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEvent.java new file mode 100644 index 0000000..67ecc70 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEvent.java @@ -0,0 +1,34 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import java.util.HashMap; + +import com.google.gwt.event.shared.GwtEvent; + + +public class ItemSelectionEvent extends GwtEvent{ + + private HashMap map; + + public static Type TYPE = new Type(); + public ItemSelectionEvent(HashMap map) { + this.map = map; + } + + public HashMap getItemSelected() { + return this.map; + } + + @Override + protected void dispatch(ItemSelectionEventHandler handler) { + // TODO Auto-generated method stub + handler.onItemSelected(this); + } + + @Override + public Type getAssociatedType() { + // TODO Auto-generated method stub + return TYPE; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEventHandler.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEventHandler.java new file mode 100644 index 0000000..eff99bf --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/ItemSelectionEventHandler.java @@ -0,0 +1,8 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface ItemSelectionEventHandler extends EventHandler { + + void onItemSelected(ItemSelectionEvent event); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEvent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEvent.java new file mode 100644 index 0000000..07f2a95 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEvent.java @@ -0,0 +1,26 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.GwtEvent; + +public class RemovedCitationEvent extends GwtEvent{ + public static Type TYPE = new Type(); + private final String citekey; + + public RemovedCitationEvent(String citekey) { + this.citekey = citekey; + } + + public String getCitekey() { + return citekey; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(RemovedCitationEventHandler handler) { + handler.onRemovedCitation(this); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEventHandler.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEventHandler.java new file mode 100644 index 0000000..304ce9a --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedCitationEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface RemovedCitationEventHandler extends EventHandler { + void onRemovedCitation(RemovedCitationEvent event); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEvent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEvent.java new file mode 100644 index 0000000..7c7bb34 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEvent.java @@ -0,0 +1,30 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import org.gcube.portlets.user.reportgenerator.client.targets.ReportTextArea; + +import com.google.gwt.event.shared.GwtEvent; + +public class RemovedUserCommentEvent extends GwtEvent{ + public static Type TYPE = new Type(); + private final ReportTextArea source; + + + public RemovedUserCommentEvent(ReportTextArea source) { + super(); + this.source = source; + } + + public ReportTextArea getSourceComponent() { + return source; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(RemovedUserCommentEventHandler handler) { + handler.onRemovedComment(this); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEventHandler.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEventHandler.java new file mode 100644 index 0000000..8da9c57 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/events/RemovedUserCommentEventHandler.java @@ -0,0 +1,7 @@ +package org.gcube.portlets.user.reportgenerator.client.events; + +import com.google.gwt.event.shared.EventHandler; + +public interface RemovedUserCommentEventHandler extends EventHandler { + void onRemovedComment(RemovedUserCommentEvent event); +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/ExportManifestationType.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/ExportManifestationType.java new file mode 100644 index 0000000..cfbdda3 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/ExportManifestationType.java @@ -0,0 +1,31 @@ +package org.gcube.portlets.user.reportgenerator.client.model; + + +/** + * + * @author massi + * + */ +public enum ExportManifestationType { + /** + * DOCX + */ + DOCX, + /** + * PDF + */ + PDF, + /** + * XML + */ + XML, + /** + * HTML + */ + HTML, + /** + * FiMES FAO Schema + */ + FIMES; + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateComponent.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateComponent.java new file mode 100644 index 0000000..5ffb28c --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateComponent.java @@ -0,0 +1,534 @@ +package org.gcube.portlets.user.reportgenerator.client.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.d4sreporting.common.shared.SerializableAttribute; +import org.gcube.portlets.d4sreporting.common.shared.SerializableAttributeArea; +import org.gcube.portlets.d4sreporting.common.shared.SerializableComponent; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.targets.AttributeArea; +import org.gcube.portlets.user.reportgenerator.client.targets.BasicTextArea; +import org.gcube.portlets.user.reportgenerator.client.targets.D4sRichTextarea; +import org.gcube.portlets.user.reportgenerator.client.targets.DropImageListener; +import org.gcube.portlets.user.reportgenerator.client.targets.DropTSListener; +import org.gcube.portlets.user.reportgenerator.client.targets.DroppingArea; +import org.gcube.portlets.user.reportgenerator.client.targets.GenericTable; +import org.gcube.portlets.user.reportgenerator.client.targets.ImageArea; +import org.gcube.portlets.user.reportgenerator.client.targets.ReportTextArea; +import org.gcube.portlets.user.reportgenerator.client.targets.TSArea; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.Widget; + + + +/** + * + * This class represent all the possible template components IN THE MODEL + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class TemplateComponent { + + /** + * + */ + public final static String DEFAULT_IMAGE_PATH= GWT.getModuleBaseURL() + "../images/organization_logo.jpg"; + + private int x; + private int y; + private int width; + private int height; + private TemplateModel myModel; + private int templatePage; + private String idInBasket = null; + + + private ComponentType type; + + private boolean locked; + + private boolean doubleColLayout; + + /** + * holds the metadata(s) for the sections + */ + private List metadata; + /** + * the paramName for assigning it a value when exporting to pdf, valid only for Dynamic Content + */ + private String paramName; + + //what is in the template component may vary depending on its type + private Widget content; + + + /** + * Creates a empty TemplateComponent + */ + public TemplateComponent() { + super(); + } + + + + /** + * Creates a TemplateComponent with the given charactheristics in double column + * + * @param myModel . + * @param x . + * @param y . + * @param width . + * @param height . + * @param templatePage . + * @param content the inserted widget + * @param type the type of the inserted widget + * @param paramName for assigning it a value when exporting to pdf, valid only for Dynamic Content + * @param doubleColLayout to specify that its layout is double columned + */ + public TemplateComponent(TemplateModel myModel, int x, int y, int width, int height, int templatePage, ComponentType type, String paramName, Widget content, boolean doubleColLayout) { + this.myModel = myModel; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.templatePage = templatePage; + this.content = content; + this.type = type; + this.paramName = paramName; + this.doubleColLayout = doubleColLayout; + this.metadata = new LinkedList(); + } + + /** + * + * Creates a TemplateComponent with the given charactheristics and single column + * + * @param myModel . + * @param x . + * @param y . + * @param width . + * @param height . + * @param templatePage . + * @param content the inserted widget + * @param type the type of the inserted widget + * @param paramName for assigning it a value when exporting to pdf, valid only for Dynamic Content + */ + public TemplateComponent(TemplateModel myModel, int x, int y, int width, int height, int templatePage, ComponentType type, String paramName, Widget content) { + this.myModel = myModel; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.templatePage = templatePage; + this.content = content; + this.type = type; + this.paramName = paramName; + this.doubleColLayout = false; + this.metadata = new LinkedList(); + } + + /** + * create a template component which is displayable (create an actual Widget in the content field) + * @param myModel the model + * @param sc the serialiazble to convert + * @param presenter . + */ + public TemplateComponent(TemplateModel myModel, SerializableComponent sc, Presenter presenter) { + this.myModel = myModel; + // + //Coords start = new Coords(x, y); + int width = sc.getWidth(); + int height = sc.getHeight(); + this.x = sc.getX(); + this.y = sc.getY(); + this.width = sc.getWidth(); + this.height = sc.getHeight(); + this.templatePage = sc.getTemplatePage(); + this.type = sc.getType(); + this.paramName = sc.getParamName(); + this.doubleColLayout = sc.isDoubleColLayout(); + this.locked = sc.isLocked(); + this.metadata = sc.getMetadata(); + + switch (sc.getType()) { + case DYNA_IMAGE: + DroppingArea dp; + String possibelContent = ((String) sc.getPossibleContent()); + if (possibelContent.startsWith("http")) { + dp = new DroppingArea(presenter, width, height,possibelContent); + + dp.showImage(new Image(possibelContent)); + } + else if (possibelContent.startsWith("/")) + dp = new DroppingArea(presenter, width, height, ""); + else if (sc.getPossibleContent().equals(DEFAULT_IMAGE_PATH)) { + dp = new DroppingArea(presenter, width, height, ""); + } else { + dp = new DroppingArea(presenter, width, height, possibelContent); + } + dp.setPixelSize(width, height); + + + @SuppressWarnings("unused") + DropImageListener dropListener = new DropImageListener(dp); + + this.content = dp; + break; + case STATIC_IMAGE: + String imagePath = (String) sc.getPossibleContent(); + + ImageArea img = new ImageArea(presenter, imagePath, myModel.getTemplateName(), true, width, height); + img.setPixelSize(width, height); + this.content = img; + break; + case HEADING_1: + case HEADING_2: + case HEADING_3: + case TITLE: + if (sc.isLocked()) { + HTML area = new HTML(); + area.setStyleName(getStyle(sc.getType())); + area.getElement().getStyle().setMarginLeft(25, Unit.PX); + area.getElement().getStyle().setMarginTop(15, Unit.PX); + area.setPixelSize(width, height); + area.setText((String) sc.getPossibleContent()); + this.content = area; + } + else { + BasicTextArea bToAdd = new BasicTextArea(sc.getType(), presenter, sc.getX(), sc.getY(), width, height, getUserComments() != null); + bToAdd.setText((String) sc.getPossibleContent()); + this.content = bToAdd; + } + break; + case BODY: + if (sc.isLocked()) { + HTML area = new HTML(); + area.setStyleName("d4sFrame"); + area.addStyleName("fixedTextArea"); + area.addStyleName("hasRichTextToolbar"); + area.setPixelSize(width, height); + area.setHTML((String) sc.getPossibleContent()); + this.content = area; + } + else { + D4sRichTextarea ta = new D4sRichTextarea(sc.getType(), presenter, sc.getX(), sc.getY(),width, height, getUserComments() != null); + ta.setHTML((String) sc.getPossibleContent()); + //ta.setStyleName("cw-RichText"); + ta.setPixelSize(width, height); + this.content = ta; + } + this.setLocked(sc.isLocked()); + break; + case TOC: + ReportTextArea dp2 = new ReportTextArea(sc.getType(), presenter, sc.getX(), sc.getY(), width, height, getUserComments() != null); + dp2.addStyleName("tocArea"); + this.content = dp2; + break; + case BIBLIO: + ReportTextArea dp3 = new ReportTextArea(sc.getType(), presenter, sc.getX(), sc.getY(), width, height, getUserComments() != null); + dp3.addStyleName("biblioArea"); + this.content = dp3; + break; + case PAGEBREAK: + ReportTextArea dp4 = new ReportTextArea(sc.getType(), presenter, sc.getX(), sc.getY(), width, height, getUserComments() != null); + dp4.addStyleName("pagebreak"); + this.content = dp4; + break; + case FLEX_TABLE: + SerializableTable st = (SerializableTable) sc.getPossibleContent(); + GenericTable table = new GenericTable(st, presenter, sc.getX(), sc.getY(), TemplateModel.TEMPLATE_WIDTH - 50, 200); + this.content = table; + break; + case ATTRIBUTE: + AttributeArea ta = null; + if (sc.getPossibleContent() instanceof SerializableAttributeArea) { + SerializableAttributeArea sata = (SerializableAttributeArea) sc.getPossibleContent(); + ta = new AttributeArea(presenter, sc.getX(), sc.getY(), width, height, sata); + } + else { + ta = new AttributeArea(presenter, sc.getX(), sc.getY(), width, height, sc.getPossibleContent().toString()); + } + this.content = ta; + break; + case COMMENT: + HTML comment = new HTML(); + comment.setStyleName("commentArea"); + comment.setHTML((String) sc.getPossibleContent()); + this.content = comment; + break; + case INSTRUCTION: + HTML instr = new HTML(); + instr.setStyleName("instructionArea"); + instr.setHTML((String) sc.getPossibleContent()); + this.content = instr; + break; + case TIME_SERIES: + TSArea tsa; + SerializableTimeSeries sts = null; + try { + sts = ((SerializableTimeSeries) sc.getPossibleContent()); + } catch (ClassCastException e) { + + } + //need to reset the filter when loading a TS + sts.setFilter(null); + tsa = new TSArea(presenter, width, 155, sts); + + tsa.setPixelSize(width, 155); + + + @SuppressWarnings("unused") + DropTSListener dropTSListener = new DropTSListener(tsa); + + this.content = tsa; + break; + } + } + /** + * + * @param type + * @return + */ + private String getStyle(ComponentType type) { + switch (type) { + case TITLE: + return "titleArea"; + case HEADING_1: + return "headgin1Area"; + case HEADING_2: + return "headgin2Area"; + case HEADING_3: + return "headgin3Area"; + default: + return ""; + } + } + /** + * return a template Component which is serializable + * @return . + */ + public SerializableComponent getSerializable() { + Serializable content = ""; + String id = ""; + switch (this.getType()) { + case DYNA_IMAGE: + DroppingArea da = (DroppingArea) this.content; + content = da.getDroppedImage().getUrl(); + id = da.getIdInBasket(); + idInBasket = id; + if (((String) content).compareTo("") == 0) + content = DEFAULT_IMAGE_PATH; + break; + case STATIC_IMAGE: + ImageArea tmp = ((ImageArea) this.content); + String imageName = tmp.getImageName(); + content = tmp.getUrl(); + break; + case BODY: + if (this.isLocked()) { + content = ((HTML) this.content).getHTML(); + } + else { + content = ((D4sRichTextarea) this.content).getHTML(); + } + break; + case HEADING_1: + case HEADING_2: + case HEADING_3: + case TITLE: + if (this.isLocked()) { + content = ((HTML) this.content).getText(); + } + else + content = ((BasicTextArea) this.content).getText(); + break; + case TIME_SERIES: + GWT.log("Found Time Series", null); + TSArea tsa = (TSArea) this.content; + content = tsa.getSts(); + break; + case FLEX_TABLE: + GenericTable gt = (GenericTable) this.content; + SerializableTable st = gt.getSerializable(); + content = st; + break; + case ATTRIBUTE: + AttributeArea att = (AttributeArea) this.content; + ArrayList values = new ArrayList(); + for (CheckBox box : att.getBoxes()) { + values.add(new SerializableAttribute(box.getText().trim(), box.getValue())); + } + SerializableAttributeArea sat= new SerializableAttributeArea(att.getAttrName().trim(), values); + content = sat; + break; + case COMMENT: + content = ((HTML) this.content).getHTML(); + break; + case INSTRUCTION: + content = ((HTML) this.content).getHTML(); + break; + } + return new SerializableComponent(x, y, width, height, templatePage, type, idInBasket, "param empty", content, this.doubleColLayout, isLocked(), metadata); + } + + + + /** + * @return . + */ + public int getHeight() {return height;} + /** + * @param height . + */ + public void setHeight(int height) { this.height = height; } + /** + * @return . + */ + public ComponentType getType() {return type;} + /** + * @param type . + */ + public void setType(ComponentType type) { this.type = type;} + /** + * @return . + */ + public int getWidth() { return width;} + /** + * @param width . + */ + public void setWidth(int width) {this.width = width;} + /** + * @return . + */ + public int getX() { return x;} + /** + * @param x . + */ + public void setX(int x) {this.x = x;} + /** + * @return . + */ + public int getY() {return y;} + /** + * @param y . + */ + public void setY(int y) {this.y = y;} + /** + * @return . + */ + public int getTemplatePage() { return templatePage; } + /** + * @param templatePage . + */ + public void setTemplatePage(int templatePage) { this.templatePage = templatePage;} + /** + * @return . + */ + public Widget getContent() {return content; } + /** + * @param content . + */ + public void setContent(Widget content) { + this.content = content; + } + + /** + * + * @return . + */ + public String getParamName() { + return paramName; + } + /** + * + * @param paramName . + */ + public void setParamName(String paramName) { + this.paramName = paramName; + } + + /** + * + * @return . + */ + public boolean isLocked() { + return locked; + } + /** + * + * @param locked . + */ + public void setLocked(boolean locked) { + this.locked = locked; + } + /** + * + * @param attr . + * @param value . + */ + public void addMetadata(String attr, String value) { + if (attr != null && value != null) { + metadata.add(new Metadata(attr, value)); + } + else + throw new NullPointerException(); + } + + /** + * + * @return . + */ + public List getAllMetadata() { + if (metadata == null) { + new LinkedList(); + } + return metadata; + } + /** + * + * @return + */ + public String getUserComments() { + if (metadata == null) return null; + for (Metadata md : metadata) { + if (md.getAttribute().equals(TemplateModel.USER_COMMENT)) + return md.getValue(); + } + return null; + } + /** + * + * @return . + */ + public String getIdInBasket() { + return idInBasket; + } + /** + * + * @param idInBasket . + */ + public void setIdInBasket(String idInBasket) { + this.idInBasket = idInBasket; + } + /** + * + * @return . + */ + public boolean isDoubleColLayout() { + return doubleColLayout; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateModel.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateModel.java new file mode 100644 index 0000000..d598c59 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateModel.java @@ -0,0 +1,697 @@ +package org.gcube.portlets.user.reportgenerator.client.model; + +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; +import java.util.Map.Entry; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.d4sreporting.common.shared.SerializableComponent; +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.d4sreporting.common.shared.SerializableSection; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.ReportService; +import org.gcube.portlets.user.reportgenerator.client.ReportServiceAsync; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.rpc.ServiceDefTarget; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Widget; + + +/** + * The TemplateModel class represents the current Template state, the model in the the MVC pattern + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class TemplateModel { + + private ReportServiceAsync modelService = (ReportServiceAsync) GWT.create(ReportService.class); + private ServiceDefTarget endpoint = (ServiceDefTarget) modelService; + /** + * default w and h + */ + + public static final int OLD_TEMPLATE_WIDTH = 950; + /** + * + */ + public static final int TEMPLATE_WIDTH = 750; + /** + * TEMPLATE_HEIGHT + */ + public static final int TEMPLATE_HEIGHT= 1000; + /** + * DEFAULT_NAME + */ + public static final String DEFAULT_NAME = "No template loaded"; + public static final String BIBLIO_SECTION = "isBibliography"; + public static final String USER_COMMENT = "isComment"; + public static final String USER_COMMENT_HEIGHT = "isCommentHeight"; + + /** + * The name of the template + */ + private String templateName; + /** + * + */ + private int pageWidth; + + /** + * + */ + private int pageHeight; + + /** + * + */ + private int currentPage; + + /** + * Total number of template pages + */ + private int totalPages; + + /** + * Template left margin + */ + private int marginLeft; + /** + * Template right margin + */ + private int marginRight; + /** + * Template top margin + */ + private int marginTop; + /** + * Template bottom margin + */ + private int marginBottom; + + /** + * columnWidth is the actual page width without margins, when columns is equal to 1 (which is always true in my case, since UI doesn't allow multi columns) + */ + private int columnWidth; + + /** + * each object of this Hahsmap its a TemplateSection containing all the TemplateComponent of a template section + * + * object: a TemplateSection of Component containing all the TemplateComponent of the section + */ + + private HashMap sections; + /** + * holds the metadata(s) for the model + */ + private List metadata; + + /** + * The name of the author + */ + private String author; + /** + * The name of the author + */ + private String lastEditBy; + /** + * The name of the author + */ + private Date dateCreated; + /** + * The name of the author + */ + private Date lastEdit; + + private Presenter presenter; + /** + * Constructs a Default Template Model + * @param presenter . + */ + + public TemplateModel(Presenter presenter) { + super(); + this.templateName = DEFAULT_NAME; + this.pageWidth = TEMPLATE_WIDTH; + this.pageHeight = TEMPLATE_HEIGHT; + this.currentPage = 1; + this.totalPages = 1; + this.marginLeft = 25; + this.marginRight = 25; + this.marginTop = 20; + this.marginBottom = 20; + this.columnWidth = pageWidth - (marginLeft + marginRight); + this.author = ""; + this.lastEdit = null; + this.lastEditBy = ""; + this.dateCreated = null; + + this.sections = new HashMap(); + this.metadata = new LinkedList(); + + this.presenter = presenter; + String moduleRelativeURL = GWT.getModuleBaseURL() + "ReportServiceImpl"; + endpoint.setServiceEntryPoint(moduleRelativeURL); + } + + /** + * @param pageNo . + * @return . + */ + public List getSectionComponent(int pageNo) { + List toReturn = new LinkedList(); + + toReturn = sections.get(""+pageNo).getAllComponents(); + + return toReturn; + } + /** + * look for the model in the current page and edits its size + * @param toResize . + * @param newWidth . + * @param newHeight . + */ + public void addCommentToComponent(Widget component, String comment2Add, int visibleHeight) { + String tcPage = ""+currentPage; + TemplateSection singleSection = sections.get(tcPage); + singleSection.addCommentToComponent(component, comment2Add, visibleHeight); + storeInSession(); + } + + public void removeComment(Widget toRemove) { + String tcPage = ""+currentPage; + TemplateSection singleSection = sections.get(tcPage); + singleSection.discardComments(toRemove); + storeInSession(); + } + /** + * + */ + public void insertBiblioSection() { + totalPages++; + + TemplateSection singleSection = new TemplateSection(); + singleSection.addMetadata(BIBLIO_SECTION, "true"); + + SerializableComponent references = new SerializableComponent(0, 0,TEMPLATE_WIDTH - 50, 35, + totalPages, ComponentType.HEADING_2, "", "REFERENCES", false, true, singleSection.getAllMetadata()); + TemplateComponent referencesTC = new TemplateComponent(this, references, presenter); + + singleSection.addComponent(referencesTC); + sections.put(""+totalPages, singleSection); + storeInSession(); + } + /** + * + * @param citeKey - + * @param citeText - + */ + public void addCitation(String citeKey, String citeText) { + String citation ="" + citeKey + ". " + citeText; + TemplateSection singleSection = getSection(totalPages); + SerializableComponent entry = new SerializableComponent(0, 0,TEMPLATE_WIDTH - 50, 35, + totalPages, ComponentType.HEADING_2, "", "Bibliographic Entry", false, true, singleSection.getAllMetadata()); + TemplateComponent entryTC = new TemplateComponent(this, entry, presenter); + singleSection.addComponent(entryTC); + SerializableComponent entryText = new SerializableComponent(0, 0,TEMPLATE_WIDTH - 50, 35, + totalPages, ComponentType.BODY, "", citation, false, false, singleSection.getAllMetadata()); + TemplateComponent entryTextTC = new TemplateComponent(this, entryText, presenter); + singleSection.addComponent(entryTextTC); + storeInSession(); + } + /** + * remove a Citation from the model + * @param citeKey . + */ + public boolean removeCitation(String citeKey) { + TemplateSection singleSection = getSection(totalPages); + List components = singleSection.getAllComponents(); + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getType() == ComponentType.BODY) { + SerializableComponent sc = tc.getSerializable(); + HTML citationHTML = new HTML(sc.getPossibleContent().toString(), true); ///to clean the HTML + String citation = citationHTML.getText(); + if (citation.startsWith(citeKey)) { + if (singleSection.removeComponent(tc)) { //removes also the previous heading 2 + TemplateComponent h2 = components.get(i-1); + singleSection.removeComponent(h2); + storeInSession(); + return true; + } + + } + } + } + return false; + } + /** + * @param pageNo . + * @return . + */ + public TemplateSection getSection(int pageNo) { + return sections.get(""+pageNo); + } + /** + * generally used when reaing a model form disk + * @param toLoad the SerializableModel instance to load in the model + * @param presenter . + */ + public void loadModel(SerializableModel toLoad, Presenter presenter) { + //loading template from disk + + this.author = toLoad.getAuthor(); + this.dateCreated = toLoad.getDateCreated(); + this.lastEdit = toLoad.getLastEdit(); + this.lastEditBy = toLoad.getLastEditBy(); + this.templateName = toLoad.getTemplateName(); + this.pageWidth = toLoad.getPageWidth(); + this.pageHeight = toLoad.getPageHeight(); + this.currentPage = toLoad.getCurrPage(); + this.totalPages = toLoad.getTotalPages(); + this.marginLeft = toLoad.getMarginLeft(); + this.marginRight = toLoad.getMarginRight(); + this.marginTop = toLoad.getMarginTop(); + this.marginBottom = toLoad.getMarginBottom(); + this.metadata = toLoad.getMetadata(); + this.columnWidth = pageWidth - (marginLeft + marginRight); + + + + //the sections to be transferred + Vector sectionsSerialized = toLoad.getSections(); + + //reset current sections container + this.sections = new HashMap(); + + //page Number, this model uses a HashMap for each page, the key is the page number + int pageNo = 1; + for (SerializableSection serialazableSection : sectionsSerialized) { //for each section + + List myTemplateSection = new Vector(); + for (SerializableComponent sc : serialazableSection.getComponents()) { //for each page component + myTemplateSection.add(new TemplateComponent(this, sc, presenter)); + } + //TODO: load also metadata + GWT.log("Section Metadata:"+serialazableSection.getMetadata().size(), null); + this.sections.put(""+pageNo, new TemplateSection(myTemplateSection, serialazableSection.getMetadata())); + pageNo++; + } + + } + + + /** + * generally used when reaing a model form disk + * @param toLoad the SerializableModel instance where toget the section + * @param sectionNoToimport section to import 0 -> n-1 + * @param beforeSection say where to import this section (before) + * @param asLastSection say to import this section as last section in the curren template / report + */ + public void importSectionInModel(SerializableModel toLoad, int sectionNoToimport, int beforeSection, boolean asLastSection) { + + int pageNo = totalPages+1; + + //the section to be imported -1 beacuse it stays in a vector + SerializableSection toImport = toLoad.getSections().get(sectionNoToimport-1); + List myTemplateSection = new Vector(); + for (SerializableComponent sc : toImport.getComponents()) { //for each page component + myTemplateSection.add(new TemplateComponent(this, sc, presenter)); + } + //TODO: load also metadata + GWT.log("Section Metadata:"+toImport.getMetadata().size(), null); + if (asLastSection) + this.sections.put(""+pageNo, new TemplateSection(myTemplateSection, toImport.getMetadata())); + else { + //insertin gnew section + HashMap newSections = new HashMap(); + boolean isAdded = false; + for (int i = 1; i <= totalPages+1; i++) { + if (beforeSection == i) { + newSections.put(""+i, new TemplateSection(myTemplateSection, toImport.getMetadata())); + isAdded = true; + } + else { + int insertIn = (isAdded) ? (i-1): i; + newSections.put(""+i, sections.get(""+insertIn)); + GWT.log("Inserting " + insertIn + " into section " + i + " isAdded =" + (isAdded) , null); + } + } + this.sections = newSections; + GWT.log("NEW SECTION SIZE"+sections.size(), null); + } + + totalPages++; + } + + /** + * + * @param sectNo the section to discard + * @return the removed element + */ + public TemplateSection discardSection(int sectNo) { + + TemplateSection toRemove = sections.remove(""+sectNo); + for (int i = sectNo+1; i <= totalPages; i++) { + sections.put(""+(i-1), sections.get(""+i)); + } + totalPages--; + return toRemove; + } + + /** + * + * @return a serialized version od the model + */ + public SerializableModel getSerializableModel() { + Vector serializedsections = new Vector(); + + for (int i = 1; i <= sections.size(); i++) { + //the pages + String pageNo = ""+i; + if (sections.get(pageNo) != null) { + + TemplateSection singleSection = sections.get(pageNo); + List templateElements = singleSection.getAllComponents(); + List serialazableComponents = new LinkedList(); + //construct the serialized section + SerializableSection aSection = new SerializableSection(); + //copy the components + for (TemplateComponent tc : templateElements) + serialazableComponents.add(tc.getSerializable()); + + aSection.setComponents(serialazableComponents); + aSection.setMetadata(singleSection.getAllMetadata()); + + //add the serialized section + serializedsections.add(aSection); + } + + + } + SerializableModel toReturn = + new SerializableModel("UniqueID", author, dateCreated, lastEdit, lastEditBy, templateName, columnWidth, currentPage, marginBottom, marginLeft, marginRight, marginTop, + pageHeight, pageWidth, serializedsections, totalPages, metadata); + + return toReturn; + } + + + + + /** + * + * @param folderid . + * @param name . + */ + public void saveReport (String folderid, String name) { + modelService.saveReport(folderid, name, new AsyncCallback() { + public void onFailure(Throwable caught) { + Window.alert("Report Not Saved: " + caught.getMessage()); + } + public void onSuccess(Void result) { + Window.alert("Report Saved Successfully"); + presenter.refreshWorkspace(); + } + }); + + } + + /** + * + * + */ + public void saveReport () { + modelService.saveReport(new AsyncCallback() { + public void onFailure(Throwable caught) { + MessageBox.alert("Warning","Report Not Saved: " + caught.getMessage(), null); + } + public void onSuccess(Void result) { + MessageBox.alert("Warning","Report Saved Successfully", null); + presenter.refreshWorkspace(); + } + }); + } + + + /** + * look for the model in the current page and edits its size + * @param toResize . + * @param newWidth . + * @param newHeight . + */ + public void resizeModelComponent(Widget toResize, int newWidth, int newHeight) { + GWT.log("LOOKING CORRESPONDANCE", null); + + String tcPage = ""+currentPage; + TemplateSection singleSection = sections.get(tcPage); + singleSection.resizeModelComponent(toResize, newWidth, newHeight); + + storeInSession(); + } + + + + /** + * + * @param type a + * @param templateName a + * return a URL which is lookable for on the web + * + * @return . + */ + public String getExportedFileURL(ExportManifestationType type, String templateName) { + /** + * PDFs will be stored under webapps/usersArea... + */ + // get e.g. http://dlib28.isti.cnr.it:9090/ + String host = Window.Location.getProtocol()+"//"+Window.Location.getHost()+"/"; + String exportedURL = ""; + + switch (type) { + case DOCX: + exportedURL = host + "usersArea/" + presenter.getCurrentScope() + "/templates/" + + presenter.getCurrentUser() + "/EXPORTS/" + templateName + ".docx"; + break; + case PDF: + exportedURL = host + "usersArea/" + presenter.getCurrentScope() + "/templates/" + + presenter.getCurrentUser() + "/EXPORTS/" + templateName + ".pdf"; + break; + case HTML: + exportedURL = host + "usersArea/" + presenter.getCurrentScope() + "/templates/" + + presenter.getCurrentUser() + "/EXPORTS/" + templateName + ".html"; + + } + return exportedURL; + } + + /** + * stores the current model in the session + */ + public void storeInSession() { + AsyncCallback callback = new AsyncCallback() { + public void onFailure(Throwable caught) { } + public void onSuccess(Object result) { } + }; + + SerializableModel modelToSend = getSerializableModel(); + + GWT.log("Storing in session: currpage = " + modelToSend.getCurrPage(), null); + + modelService.storeTemplateInSession(modelToSend, callback); + } + + //****** GETTERS n SETTERS + /** + * @return . + */ + public int getCurrentPage() {return currentPage;} + /** + * @param currentPage . + */ + public void setCurrentPage(int currentPage) { + this.currentPage = currentPage; + storeInSession(); + } + /** + * @return . + */ + public int getMarginBottom() {return marginBottom;} + /** + * @param marginBottom . + */ + public void setMarginBottom(int marginBottom) {this.marginBottom = marginBottom;} + /** + * @return . + */ + public int getMarginLeft() {return marginLeft; } + /** + * @param marginLeft . + */ + public void setMarginLeft(int marginLeft) { + this.marginLeft = marginLeft; + this.columnWidth = pageWidth - (marginLeft + marginRight); + } + /** + * @return . + */ + public int getMarginRight() {return marginRight;} + /** + * @param marginRight . + */ + public void setMarginRight(int marginRight) { + this.marginRight = marginRight; + this.columnWidth = pageWidth - (marginLeft + marginRight); + } + /** + * @return . + */ + public int getMarginTop() {return marginTop;} + /** + * @param marginTop . + */ + public void setMarginTop(int marginTop) {this.marginTop = marginTop;} + /** + * @return . + */ + public int getPageHeight() {return pageHeight; } + /** + * @param pageHeight . + */ + public void setPageHeight(int pageHeight) { this.pageHeight = pageHeight;} + /** + * @return . + */ + public int getPageWidth() { return pageWidth;} + /** + * @param pageWidth . + */ + public void setPageWidth(int pageWidth) { + this.pageWidth = pageWidth; + this.columnWidth = pageWidth - (marginLeft + marginRight); + } + /** + * @return . + */ + public String getTemplateName() {return templateName;} + /** + * @param templateName . + */ + public void setTemplateName(String templateName) { + this.templateName = templateName; + storeInSession(); + } + + /** + * @return totalPages . + */ + public int getTotalPages() {return totalPages; } + + /** + * @param totalPages . + */ + public void setTotalPages(int totalPages) { this.totalPages = totalPages;} + /** + * @return . + */ + public int getColumnWidth() {return columnWidth;} + /** + * @param columnWidth . + */ + public void setColumnWidth(int columnWidth) {this.columnWidth = columnWidth;} + /** + * @return . + */ + public ReportServiceAsync getModelService() {return modelService;} + + + /** + * metadata . + * @return . + */ + public List getMetadata() { + return metadata; + } + + /** + * + * @return . + * + */ + public String getLastEditBy() { + return lastEditBy; + } + + + /** + * + * @param lastEditBy . + */ + public void setLastEditBy(String lastEditBy) { + this.lastEditBy = lastEditBy; + } + + /** + * + * @return . + */ + public boolean containsLargeTS() { + sections.entrySet(); + for (Entry entry : sections.entrySet()) { + TemplateSection section = (TemplateSection) entry.getValue(); + for (TemplateComponent tc : section.getAllComponents()) { + if (tc.getType() == ComponentType.TIME_SERIES) { + SerializableComponent sc = tc.getSerializable(); + SerializableTimeSeries sts = (SerializableTimeSeries) sc.getPossibleContent(); + if (sts.getFilter() != null) { + int from = sts.getFilter().getFrom(); + int to = sts.getFilter().getTo(); + if (to - from > 200) + return true; + } + } + } + } + return false; + } + + public void updateWorkflowDocument(boolean update) { + modelService.updateWorkflowDocument(update, new AsyncCallback() { + + public void onFailure(Throwable caught) { + Window.alert("failed to update workflow document"); + + } + public void onSuccess(Void result) { + loadWorkflowLibraryApp(); + } + }); + + } + private String location; + /** + * Redirect to VRE Deployer Portlet + */ + private void loadWorkflowLibraryApp(){ + getUrl(); + location += "/../my-workflow-documents"; + Window.open(location, "_self", ""); + } + /** + * Get URL from browser + */ + public native void getUrl()/*-{ + this.@org.gcube.portlets.user.reportgenerator.client.model.TemplateModel::location = $wnd.location.href; + }-*/; + +} + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateSection.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateSection.java new file mode 100644 index 0000000..f7bd04b --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/model/TemplateSection.java @@ -0,0 +1,254 @@ +package org.gcube.portlets.user.reportgenerator.client.model; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.shared.Metadata; +import org.gcube.portlets.user.reportgenerator.client.events.AddCommentEvent; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.ui.Widget; + +/** + * The TemplateSection class represents a Template Section that can be associated to any Template + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2009 (1.4) + */ + +public class TemplateSection { + + /** + * holds the metadata(s) for the sections + */ + private List metadata; + /** + * holds the TemplateComponents for the sections + */ + private List components; + + /** + * + * @param components + * @param metadata + */ + public TemplateSection() { + this.components = new LinkedList(); + this.metadata = new LinkedList(); + } + + /** + * + * @param components . + * @param metadata . + */ + public TemplateSection(List components, List metadata) { + this.components = components; + this.metadata = metadata; + } + + ///*** GETTERS N SETTERS + /** + * enqueue a component + */ + public void addComponent(TemplateComponent tc) { + if (tc != null) + components.add(tc); + else { + throw new NullPointerException(); + } + } + + public boolean removeComponent(TemplateComponent tc) { + if (tc != null) + return components.remove(tc); + else { + throw new NullPointerException(); + } + } + + public ArrayList getSectionComments() { + ArrayList toRet = new ArrayList(); + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getUserComments() != null) { + //toRet. + } + } + return toRet; + } + /** + * look for the model in the current page and edits its size + * @param toResize . + * @param newWidth . + * @param newHeight . + */ + public void resizeModelComponent(Widget toResize, int newWidth, int newHeight) { + + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + + if (tc.getContent() != null && tc.getContent().equals(toResize)) { + GWT.log("FOUND CORRESPONDANCE"); + tc.setWidth(newWidth); + tc.setHeight(newHeight); + tc.setContent(toResize); + break; + } + } + } + + public void discardComments(Widget component) { + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getContent() != null && tc.getContent().equals(component)) { + //removes previous comment is exists + for (Metadata metadata : tc.getAllMetadata()) { + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT)) { + tc.getAllMetadata().remove(metadata); + GWT.log("FOUND and REMOVED"); + break; + } + } + for (Metadata metadata : tc.getAllMetadata()) { + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT_HEIGHT)) { + tc.getAllMetadata().remove(metadata); + break; + } + } + } + } + } + /** + * look for the model in the current page and edits its size + */ + public void addCommentToComponent(Widget component, String comment2Add, int visibleHeight) { + + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getContent() != null && tc.getContent().equals(component)) { + //removes previous comment is exists + for (Metadata metadata : tc.getAllMetadata()) { + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT)) { + tc.getAllMetadata().remove(metadata); + break; + } + } + for (Metadata metadata : tc.getAllMetadata()) { + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT_HEIGHT)) { + tc.getAllMetadata().remove(metadata); + break; + } + } + //add the comment + tc.addMetadata(TemplateModel.USER_COMMENT, comment2Add); + tc.addMetadata(TemplateModel.USER_COMMENT_HEIGHT, ""+visibleHeight); + GWT.log("Comment Added: " + comment2Add); + break; + } + } + } + /** + * look if a comment with a specific metadata (that indicate sit is a comment) + * exists in the current report model: + * @return true if comment is present yet false otherwise + */ + public boolean hasComments(Widget component) { + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getContent() != null && tc.getContent().equals(component)) { + for (Metadata metadata : tc.getAllMetadata()) + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT)) return true; + } + } + return false; + } + + /** + * look if a comment with a specific metadata (that indicate sit is a comment) + * exists in the current report model: + * @return true if comment is present yet false otherwise + */ + public AddCommentEvent getComponentComments(Widget component) { + String commentText = ""; + int commentHeight = -1; + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getContent() != null && tc.getContent().equals(component)) { + for (Metadata metadata : tc.getAllMetadata()) { + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT)) + commentText = metadata.getValue(); + if (metadata.getAttribute().equals(TemplateModel.USER_COMMENT_HEIGHT)) + commentHeight = Integer.parseInt(metadata.getValue()); + } + } + } + return new AddCommentEvent(null, commentText, commentHeight); + } + + /** + * look for the model in the current section and edits its position + * @param toRepos . + * @param newX . + * @param newY . + */ + public void repositionModelComponent(Widget toRepos, int newX, int newY) { + + for (int i = 0; i < components.size(); i++) { + TemplateComponent tc = components.get(i); + if (tc.getContent().equals(toRepos)) { + GWT.log("FOUND CORRESPONDANCE", null); + tc.setX(newX); + tc.setY(newY); + tc.setContent(toRepos); + break; + } + } + } + /** + * + * @param index . + * @return . + */ + public TemplateComponent getComponent(int index) { + return components.get(index); + } + + /** + * + * @param attr . + * @param value . + */ + public void addMetadata(String attr, String value) { + if (attr != null && value != null) { + metadata.add(new Metadata(attr, value)); + } + else + throw new NullPointerException(); + } + + /** + * + * @return . + */ + public List getAllMetadata() { + if (metadata == null) { + new LinkedList(); + } + return metadata; + } + + /** + * + * @return . + */ + public List getAllComponents() { + if (components == null) { + new TemplateSection(); + } + return components; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/FimesReportTreeStructureResources.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/FimesReportTreeStructureResources.java new file mode 100644 index 0000000..64f7a2e --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/FimesReportTreeStructureResources.java @@ -0,0 +1,45 @@ +package org.gcube.portlets.user.reportgenerator.client.resources; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.resources.client.ClientBundle.Source; + +public interface FimesReportTreeStructureResources extends ClientBundle { +public static final FimesReportTreeStructureResources INSTANCE = GWT.create(FimesReportTreeStructureResources.class); + + @Source("report.png") + ImageResource root(); + + @Source("page.png") + ImageResource section(); + + @Source("text_heading_1.png") + ImageResource heading1(); + + @Source("text_heading_2.png") + ImageResource heading2(); + + @Source("text_heading_3.png") + ImageResource heading3(); + + @Source("text_heading_4.png") + ImageResource heading4(); + + @Source("text_dropcaps.png") + ImageResource text(); + + @Source("table.png") + ImageResource table(); + + @Source("image.png") + ImageResource image(); + + @Source("information.png") + ImageResource instructions(); + + @Source("comments.png") + ImageResource comments(); + +} + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/comments.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/comments.png new file mode 100644 index 0000000000000000000000000000000000000000..39433cf78a3e9869f24b0a95f04b1819391596e8 GIT binary patch literal 557 zcmV+|0@D47P)kO-!8JjERGZgNx4o8zwI5pnrkJT^AW7B+k01lLkoCLBu@bfRhnJSkT}{ z5cwz-C?AEk;`Q7|NyO0V@Jst%?>X<@)8|?6hNplZoH}p}R=_wBd4A);huvr*D{8ta zv>weaRZy(zA{a{x)NMK$oUyoq;&Q_jA9Yid>V_!Q3{lkDazCTg+2GL8fKO$yVv7pZ zw#ZdlB3o|B^q?JFdAt+nq80!As0d}1Z|KFR(*lEh^G}{es&~_I}wY;n4d5jAs0d}gj@(+ z%6*K*29I(Myv%_UPWDD&5qS@s3~ZAJGDH vT*SlN0ce3)r#d%-F%SaNZe6;L@E^Vb!Ji3~dec0&00000NkvXXu0mjflI-*P literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/image.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/image.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3c393caa3bc4371d12d0c67ffd6d333ecf1d8e GIT binary patch literal 516 zcmV+f0{i`mP)0oSgT$J*kO*Aq9I~CW*s{G*(t$KS{OS+#aO%?udUme<*TTEO`Fr@r_QT zk=#}u-n~>Vm!+9S1PE{@3<)G~CPb<$Za;W?3+O}|+q)?*Pn355=}S(XIZmEANjZci zf5 zj<%@MX^bD1^BwlS^+AD|$dm-1wial0hwPI;CDM?Y9SXW#@w-UF0SQ8OgplRTleOB2 zUjkDS|0U9pI|lSN*EvXUa~*UIclJdZ#)Npbwh9>YT?Z;=B8|l&^t~P~om?<5Lre$+ z;%`P>SL7`djY#8Y9$wv9dv|3p)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*0)+jEP);68^d)m`eN0o>(5%D`Q(1;j>g@G;xlf`0VBQ`PFY?6)!N&f?*K}$p; zB!U=NBn{eB8${1}&-2_L*HuZp@ZP1@clS@cHp)4iM1ewzw59vko7eMM{e9z|%NNdX z0V;`?KKSzTCvTm5bc{L^CIKLUxc2X{i{ISz$8Sgf{q)1nXTP{`{s?9mQ$4&hPiKC- zY8q7(Y1Xu5iCf33=O4Vy(+|zQ?rW#gkKB0f%}?+6{G*qT22|DQB-73`YzA{N4W^=s zq0kQYcbtFfz zLz)H<&|z(Y4ksm$HQ(N)Ek< zrc#vXMLdW}TWpphCZsGREkUZr{Mg;M&b;luZ0IGA9rnH1`DVU1->eh_0hG(-dw<@) z-1S-xc+D!@wd^?Z=a`M%%phe@J_EnT0QpH7V3 jcG~XA#&PRl)Zh6(yXt(^KFGF}00000NkvXXu0mjfDwr>g literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/table.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/table.png new file mode 100644 index 0000000000000000000000000000000000000000..abcd93689a08ec9bdbf0984927e8da06c043c7cd GIT binary patch literal 566 zcmV-60?GY}P)>q?GuNnCdgP^*Bj5V_b?dAq2Ppn9^MBB^YUM zad0N-T{Ujg*A6d~mYV4na=hT4Nz+_}SGTgW|Iir!%$ z;@OGkWI6+j0H}~K4RYR%!7y|zM`O@*K>rL{*&}x3lR**HrMXC1->#slU>X|w!U1xQ zqcLqe|nkKbQs_~+l>*^DmDAMWj~mUJxYIg!Y)N!CM> z*|4K5Ht^-f_7L$FCexixdjt52Tl@RZ*Uva>Q1k4JWQaI}X)BZFgk#kXYh2c7M=Y2% zb%9wMqv@UIPmXLQ3>!P=&XsNB&bzy-Rg&!qLxqHkn_JS2roP0D42$O5*ZZZ4S5#O3 zS5L7v`uFFj@zmIa?CjtFpP!!}@t6B>{l7ns$F3AI9^EO(U@`aN<^{{<{s#Js!PC{x JWt~$(695Iyd-ebT literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_1.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9c122e91e358860733eaf08fd543e5fc585d4cfd GIT binary patch literal 276 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$x=IP=XqH%ujg^j!|20W|*-XbO@ zAtBSd^khRzd{=pNv@vN)9uZDqGTXuVPf6#I=?;x2B`Y;1YQMI>>GxvE??vtn{c>{A z7MYxUVrui2JTF|YR&ldntL8M3{q7no52$4`vIX;r@S8@YTFOM5*~nV4Gk-UYI5L$} zDw(h9UDksmVjphbEsSQ?UdGUxU4Htk{EZoY&3@-Y5*_;Wwk`ZAkg@!FaC~ii{N>;; VD%(>GD}XL$@O1TaS?83{1OVXtVO9VD literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_2.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_2.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd87657fbe001c0a78fb095284fffc32e739497 GIT binary patch literal 304 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$ROXGNhtQ`{C(%$wdeB3 zGTnLdz~IMJtNg?T>Z(s;oVU0)KW5x*9xvq)rPF;` zY|Fc4&#rLa>Txf#@y+aKf+ac0%`STzAI(*qdYo^XFH557y+_x*JpKO5^1S9?c^6}{ zP=+&OVHtDUrGNmdKI;Vst0KHFj AM*si- literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_3.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c7836cf09e4565cc76c13bd14c13971c9e093c40 GIT binary patch literal 306 zcmV-20nPr2P)wEzGB literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_4.png b/src/main/java/org/gcube/portlets/user/reportgenerator/client/resources/text_heading_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4e929eaf583f10cf50eb1666ff6530b9d4cc7915 GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-&H?&;zfqH%ujg^j$;1_G=B-XbO( zon2btF4r#xDw?mmvtwaL3R_~+Yz66*rrQmiHySwec#9a-mn?F*9`VcnzTNDrbNY9( zxOA;CUb9S|sk-b7=Pc<<>lMA8+|AaBj(NoLhh2`-;+F zenR#-z6;(Syt?;Ub#DVE_OC literal 0 HcmV?d00001 diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/AttributeArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/AttributeArea.java new file mode 100644 index 0000000..3ae77a3 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/AttributeArea.java @@ -0,0 +1,142 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.shared.SerializableAttribute; +import org.gcube.portlets.d4sreporting.common.shared.SerializableAttributeArea; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.ui.CheckBox; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +/** + * AttributeArea class + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version April 2011 (1.0) + */ +public class AttributeArea extends Composite { + + private HorizontalPanel myPanel; + private HTML attrName; + private CheckBox[] boxes; + + /** + * Coming form a template constructor + */ + public AttributeArea(final Presenter presenter, int left, int top, int width, final int height, String textToDisplay) { + myPanel = new HorizontalPanel(); + myPanel.setTitle("Attribute Area"); + myPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); + myPanel.setPixelSize(width, 20); + myPanel.addStyleName("attributeArea"); + + attrName = new HTML(getAttributeName(textToDisplay)); + attrName.getElement().getStyle().setMarginLeft(10, Unit.PX); + attrName.getElement().getStyle().setMarginRight(5, Unit.PX); + HorizontalPanel boxesPanel = new HorizontalPanel(); + boxesPanel.add(attrName); + myPanel.add(boxesPanel); + myPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); + boxes = getCheckboxes(textToDisplay); + for (int i = 0; i < boxes.length; i++) { + boxesPanel.add(boxes[i]); + } + initWidget(myPanel); + } + /** + * Coming form a report constructor + */ + public AttributeArea(final Presenter presenter, int left, int top, int width, final int height, SerializableAttributeArea sata) { + myPanel = new HorizontalPanel(); + myPanel.setTitle("Attribute Area"); + myPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); + myPanel.setPixelSize(width, 20); + myPanel.addStyleName("attributeArea"); + + attrName = new HTML(sata.getAttrName(), true); + attrName.getElement().getStyle().setMarginLeft(10, Unit.PX); + attrName.getElement().getStyle().setMarginRight(5, Unit.PX); + HorizontalPanel boxesPanel = new HorizontalPanel(); + boxesPanel.add(attrName); + myPanel.add(boxesPanel); + myPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT); + int values = sata.getValues().size(); + boxes = new CheckBox[values]; + int j = 0; + for (SerializableAttribute attr: sata.getValues()) { + CheckBox toAdd = new CheckBox(attr.getName()); + toAdd.setStyleName("checkAttribute"); + toAdd.setValue(attr.getValue()); + boxes[j] = toAdd; + j++; + } + + //adding it to the panel + for (int i = 0; i < boxes.length; i++) { + boxesPanel.add(boxes[i]); + } + initWidget(myPanel); + } + /** + * + * @param toParse + * @return + */ + private String getAttributeName(String toParse) { + if (toParse == null) + return ""; + String toReturn = ""; + try { + toReturn = toParse.substring(0, toParse.indexOf(":")); + } catch (StringIndexOutOfBoundsException e) { + GWT.log("Could not find : returning empty"); + } + return toReturn; + } + /** + * + * @param toParse + * @return + */ + private CheckBox[] getCheckboxes(String toParse) { + String toSplit = toParse.substring(toParse.indexOf(":")+1, toParse.length()); + String[] values = toSplit.split("\\|"); + GWT.log("toSplit" + toSplit); + GWT.log("values" + values.length); + CheckBox[] boxes = new CheckBox[values.length]; + for (int i = 0; i < values.length; i++) { + boxes[i] = new CheckBox(); + boxes[i].setStyleName("checkAttribute"); + boxes[i].setText(" " + values[i].trim()); + } + return boxes; + } + /** + * + * @return + */ + public ComponentType getType() { + return ComponentType.ATTRIBUTE; + } + /** + * + * @return + */ + public CheckBox[] getBoxes() { + return boxes; + } + /** + * + * @return + */ + public String getAttrName() { + return attrName.getText(); + } + + +} + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/BasicTextArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/BasicTextArea.java new file mode 100644 index 0000000..1762722 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/BasicTextArea.java @@ -0,0 +1,111 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.user.reportgenerator.client.ReportGenerator; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.TextArea; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +/** + * BasicTextArea + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class BasicTextArea extends ReportTextArea { + private TextArea textArea = new TextArea(); + private VerticalPanel myPanel; + private Presenter presenter; + + int currHeight = 0; + + + public BasicTextArea(ComponentType type, final Presenter presenter, int left, int top, int width, final int height, boolean hasComments) { + super(type, presenter, left, top, width, height, hasComments); + this.presenter = presenter; + myPanel = getResizablePanel(); + + textArea.setPixelSize(width, height); + + textArea.addMouseOutHandler(new MouseOutHandler() { + + public void onMouseOut(MouseOutEvent event) { + presenter.storeChangeInSession((Widget) event.getSource()); + } + }); + switch (type) { + case TITLE: + textArea.setStyleName("titleArea"); + myPanel.setTitle("Title"); + break; + case HEADING_1: + textArea.setStyleName("headgin1Area"); + myPanel.setTitle("Heading: Level 1"); + break; + case HEADING_2: + textArea.setStyleName("headgin2Area"); + myPanel.setTitle("Heading Level 2"); + break; + case HEADING_3: + textArea.setStyleName("headgin3Area"); + myPanel.setTitle("Heading: Level 3"); + break; + default: + break; + } + myPanel.add(textArea); + myPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); + myPanel.setPixelSize(width, height); + + textArea.addMouseOutHandler(new MouseOutHandler() { + + public void onMouseOut(MouseOutEvent event) { + presenter.storeChangeInSession((Widget) event.getSource()); + + } + }); + + textArea.addKeyUpHandler(new KeyUpHandler() { + + public void onKeyUp(KeyUpEvent event) { + HTML div = ReportGenerator.get().getDivHidden(); + GWT.log("element.getHTML():\n" + textArea.getText(), null); + div.setHTML(textArea.getText()); + int newHeight = div.getOffsetHeight(); + if (newHeight > height-10 && newHeight != currHeight) { + resizeMe(myPanel.getOffsetWidth(), newHeight); + } + + } + }); + + + } + /** + * resize the panel + * @param w + * @param h + */ + private void resizeMe(int w, int h) { + resizePanel(w, h); + //Window.alert("myInstance.top: " + myInstance.top); + presenter.resizeTemplateComponentInModel(this, myPanel.getOffsetWidth(), h+5); + } + + public String getText() { + return textArea.getText(); + } + public void setText(String text) { + textArea.setText(text); + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/Coords.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/Coords.java new file mode 100644 index 0000000..ad1ebd3 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/Coords.java @@ -0,0 +1,26 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +public class Coords { + + private int X; + private int Y; + public Coords(int x, int y) { + super(); + X = x; + Y = y; + } + public int getX() { + return X; + } + public void setX(int x) { + X = x; + } + public int getY() { + return Y; + } + public void setY(int y) { + Y = y; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/D4sRichTextarea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/D4sRichTextarea.java new file mode 100644 index 0000000..dd61df4 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/D4sRichTextarea.java @@ -0,0 +1,227 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.user.reportgenerator.client.ReportGenerator; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.extjs.gxt.ui.client.widget.MessageBox; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.RichTextArea; +import com.google.gwt.user.client.ui.TextArea; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + + +/** + * D4sRichTextArea class is a template component that goes into the workspace + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ +public class D4sRichTextarea extends ReportTextArea { + + /** + * the text area + */ + private RichTextArea area = new RichTextArea(); + + + TextArea text = new TextArea(); + /** + * a flag + */ + boolean firstClick = true; + + int currHeight = 0; + + VerticalPanel myPanel; + /** + * + * + */ + public D4sRichTextarea() {} + + /** + * + * @param presenter . + * @param left left + * @param top top + * @param width . + * @param height . + * @param type . + */ + public D4sRichTextarea(ComponentType type, final Presenter presenter, int left, int top, int width, final int height, boolean hasComments) { + super(type, presenter, left, top, width, height, hasComments); + currHeight = height; + myPanel = getResizablePanel(); + + area.setPixelSize(width-6, height-2); + area.setStyleName("d4sRichTextArea"); + + + switch (type) { + case TITLE: + area.addStyleName(""); + break; + case HEADING_1: + area.addStyleName(""); + break; + case HEADING_2: + area.addStyleName(""); + break; + case HEADING_3: + area.addStyleName(""); + break; + case BODY: + area.addStyleName("bodyArea"); + break; + default: + break; + } + + + myPanel.add(area); + //repositionMyPanel(0, 15); + myPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); + myPanel.setPixelSize(width, height-15); + setStyleName("d4sFrame"); + + area.addMouseDownHandler(new MouseDownHandler() { + public void onMouseDown(MouseDownEvent event) { + if (event.getNativeButton() == Event.BUTTON_RIGHT) { + event.preventDefault(); + event.stopPropagation(); + MessageBox.alert("Warning","Please, use CTRL+V (CMD+V) for pasting into this area", null); + } + if (firstClick) { + presenter.enableTextToolBar(area); + presenter.enableBiblioEntry(area); + firstClick = false; + ReportGenerator.get().getDivHidden().setPixelSize(area.getOffsetWidth(), -1); + } + HTML div = ReportGenerator.get().getDivHidden(); + div.setHTML(area.getHTML()); + int newHeight = div.getOffsetHeight()+20 ; + if (newHeight > height-10 && newHeight != currHeight) { + presenter.shiftComponentsByTextArea(myInstance.top, newHeight - currHeight); + resizePanel(myPanel.getOffsetWidth(), div.getOffsetHeight()); + //Window.alert("myInstance.top: " + myInstance.top); + presenter.resizeTemplateComponentInModel(myInstance, myPanel.getOffsetWidth(), newHeight); + } + } + }); + + area.addMouseOutHandler(new MouseOutHandler() { + public void onMouseOut(MouseOutEvent event) { + firstClick = true; + presenter.storeChangeInSession((Widget) event.getSource()); + } + + }); + //TODO: aggiorna +// area.addKeyDownHandler(new KeyDownHandler() { +// public void onKeyDown(KeyDownEvent event) { +//// if (event.isAnyModifierKeyDown() && event.getNativeKeyCode() == 86) { //event.getNativeKeyCode() == 86 is the V (to avoid ctrl V or cmd V) +//// MessageBox.show(new MessageBoxConfig() { +//// { +//// setTitle("Paste operation"); +//// setMsg("Please enter your text here (PLAIN)"); +//// setWidth(500); +//// setButtons(MessageBox.OKCANCEL); +//// setMultiline(true); +//// setCallback(new MessageBox.PromptCallback() { +//// public void execute(String btnID, String text) { +//// if (btnID.compareTo("ok") == 0) { +//// area.setText(text); +//// +//// //resize if needed +//// HTML div = ReportGenerator.get().getDivHidden(); +//// //GWT.log("element.getHTML():\n" + area.getHTML(), null); +//// div.setHTML(area.getHTML()); +//// int newHeight = div.getOffsetHeight()+20 ; +//// if (newHeight > height-10 && newHeight != currHeight) { +//// resizePanel(myPanel.getOffsetWidth(), div.getOffsetHeight()); +//// } +//// } +//// +//// } +//// }); +//// } +//// }); +// event.stopPropagation(); +// event.preventDefault(); +// } +// +// } +// }); + area.addKeyUpHandler(new KeyUpHandler() { + public void onKeyUp(KeyUpEvent event) { + HTML div = ReportGenerator.get().getDivHidden(); + div.setHTML(area.getHTML()); + int newHeight = div.getOffsetHeight()+20 ; + if (newHeight > height-10 && newHeight != currHeight) { + presenter.shiftComponentsByTextArea(myInstance.top, newHeight - currHeight); + resizePanel(myPanel.getOffsetWidth(), div.getOffsetHeight()); + //Window.alert("myInstance.top: " + myInstance.top); + presenter.resizeTemplateComponentInModel(myInstance, myPanel.getOffsetWidth(), newHeight); + } + } + }); + } + + /** + * used to resize the panel + * @param width w + * @param height h + */ + @Override + public void resizePanel(int width, int height) { + if (height > 15 && width > 15) { + mainPanel.setPixelSize(width, height+20); + resizablePanel.setPixelSize(width, height+20); + mainPanel.setWidgetPosition(topPanel, width-30 , 0); + area.setPixelSize(width-4, height+20); + currHeight = height + 20; + } + } + + /** + * + * @return . + */ + public String getHTML() { + return area.getHTML(); + } + + /** + * @param html the html + */ + public void setHTML(String html) { + area.setHTML(html); + } + /** + * + * @return . + */ + public RichTextArea getArea() { + return area; + } + + /** + * + * @param firstClick . + */ + public void setFirstClick(boolean firstClick) { + this.firstClick = firstClick; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DoubleColumnPanel.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DoubleColumnPanel.java new file mode 100644 index 0000000..361f996 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DoubleColumnPanel.java @@ -0,0 +1,42 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Widget; + + +/** + * DoubleColumnPanel class is a Widget that places to widget in the same y + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2009 (1.4) + */ +public class DoubleColumnPanel extends Composite { + + private Widget left; + private Widget right; + + private HorizontalPanel mainPanel = new HorizontalPanel(); + + + /** + * + * @param left . + * @param right . + */ + public DoubleColumnPanel(Widget left, Widget right) { + super(); + + this.left = left; + this.right = right; + + mainPanel.add(left); + mainPanel.add(right); + mainPanel.setWidth("800"); + initWidget(mainPanel); + + } + + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropImageListener.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropImageListener.java new file mode 100644 index 0000000..99ef935 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropImageListener.java @@ -0,0 +1,122 @@ +/** + * + */ +package org.gcube.portlets.user.reportgenerator.client.targets; + + + +import java.util.List; + +import org.gcube.portlets.user.workspace.client.interfaces.GXTFolderItemTypeEnum; +import org.gcube.portlets.user.workspace.client.model.FileModel; +import org.gcube.portlets.user.workspace.client.workspace.GWTWorkspaceItem; +import org.gcube.portlets.user.workspace.client.workspace.GWTWorkspaceItemType; +import org.gcube.portlets.user.workspace.client.workspace.folder.GWTFolderItem; +import org.gcube.portlets.user.workspace.client.workspace.folder.GWTFolderItemType; +import org.gcube.portlets.user.workspace.client.workspace.folder.item.GWTExternalImage; +import org.gcube.portlets.user.workspace.client.workspace.folder.item.gcube.GWTImageDocument; + +import com.extjs.gxt.ui.client.dnd.DropTarget; +import com.extjs.gxt.ui.client.dnd.Insert; +import com.extjs.gxt.ui.client.dnd.DND.Operation; +import com.extjs.gxt.ui.client.event.DNDEvent; +import com.extjs.gxt.ui.client.store.TreeStoreModel; +import com.extjs.gxt.ui.client.widget.Html; +import com.extjs.gxt.ui.client.widget.treepanel.TreePanel; +import com.google.gwt.core.client.GWT; + + + +/** + * @author Massimiliano Assante assante@isti.cnr.it + * + */ +public class DropImageListener extends DropTarget { + /** + * + */ + public static final String TIFF = "image/tiff"; + + protected DroppingArea panel; + + /** + * + * @param panel . + * @param config . + */ + public DropImageListener(DroppingArea panel) { + super(panel); + this.panel = panel; + //IMPORTANT + setOperation(Operation.COPY); + } + @Override + protected void showFeedback(DNDEvent event) { + if (!isValidDropTarget(event)) { + Insert.get().hide(); + event.getStatus().setStatus(false); + return; + } + super.showFeedback(event); + } + + + @SuppressWarnings("unchecked") + private boolean isValidDropTarget(DNDEvent event) { + GWT.log("isValidDropTarget"); + TreePanel source = (TreePanel) event.getDragSource().getComponent(); + List selection = source.getSelectionModel().getSelection(); + + for (FileModel model : selection) { + GWT.log("selection: " + model.getGXTFolderItemType()); + if(model.getGXTFolderItemType()!=null){ + + if (model.getGXTFolderItemType().equals(GXTFolderItemTypeEnum.EXTERNAL_IMAGE) || model.getGXTFolderItemType().equals(GXTFolderItemTypeEnum.IMAGE_DOCUMENT)) + return true; + // + // if (model.getGXTFolderItemType().equals(GXTFolderItemTypeEnum.TIME_SERIES)) + // return true; + + // if(source.getStore().getParent(model) == target.getModel()) + // return false; + } + } + + return false; + } + + /** + * @param source . + * @param e . + * @param data . + * @return . + */ + protected void onDragDrop(DNDEvent event) { + + super.onDragDrop(event); + + if(event.getData() != null){ + List listItemsSource = event.getData(); + GWT.log("Number of move " + listItemsSource.size()); + + FileModel sourceFileModel = null; //for print + + for(TreeStoreModel itemSource : listItemsSource){ + + sourceFileModel = (FileModel) itemSource.getModel(); + + if(sourceFileModel.getParentFileModel()!=null) + GWT.log("Source Name " + sourceFileModel.getName() + " id " + sourceFileModel.getIdentifier() + " end drag " + " Parent Name: " + sourceFileModel.getParentFileModel().getName() + "id " + sourceFileModel.getParentFileModel().getIdentifier()); + else + GWT.log("Source Name " + sourceFileModel.getName() + " id " + sourceFileModel.getIdentifier() + " end drag "); + + GWT.log("Child count: " + itemSource.getChildCount()); + + panel.fetchImage(sourceFileModel.getIdentifier(), false , true); + + } + } + + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropTSListener.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropTSListener.java new file mode 100644 index 0000000..90ffd44 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DropTSListener.java @@ -0,0 +1,115 @@ +/** + * + */ +package org.gcube.portlets.user.reportgenerator.client.targets; + + + + +import java.util.List; + +import org.gcube.portlets.user.workspace.client.interfaces.GXTFolderItemTypeEnum; +import org.gcube.portlets.user.workspace.client.model.FileModel; + +import com.extjs.gxt.ui.client.dnd.DND.Operation; +import com.extjs.gxt.ui.client.dnd.DropTarget; +import com.extjs.gxt.ui.client.dnd.Insert; +import com.extjs.gxt.ui.client.event.DNDEvent; +import com.extjs.gxt.ui.client.store.TreeStoreModel; +import com.extjs.gxt.ui.client.widget.treepanel.TreePanel; +import com.google.gwt.core.client.GWT; + +/** + * @author Federico De Faveri defaveri@isti.cnr.it + * + */ +public class DropTSListener extends DropTarget { + /** + * + */ + public static final String NO_DROP = "x-dd-drop-nodrop"; + /** + * + */ + public static final String OK_DROP = "x-dd-drop-ok"; + /** + * + */ + public static final String OK_DROP_ADD = "x-dd-drop-ok-add"; + + protected TSArea panel; + + /** + * + * @param panel . + * @param config . + */ + public DropTSListener(TSArea panel) { + super(panel); + this.panel = panel; + //IMPORTANT + setOperation(Operation.COPY); + } + + @Override + protected void showFeedback(DNDEvent event) { + if (!isValidDropTarget(event)) { + Insert.get().hide(); + event.getStatus().setStatus(false); + return; + } + super.showFeedback(event); + } + + + @SuppressWarnings("unchecked") + private boolean isValidDropTarget(DNDEvent event) { + GWT.log("isValidDropTarget"); + TreePanel source = (TreePanel) event.getDragSource().getComponent(); + List selection = source.getSelectionModel().getSelection(); + + for (FileModel model : selection) { + GWT.log("selection: " + model.getGXTFolderItemType()); + if(model.getGXTFolderItemType()!=null){ + if (model.getGXTFolderItemType().equals(GXTFolderItemTypeEnum.TIME_SERIES)) + return true; + } + } + return false; + } + + /** + * @param source . + * @param e . + * @param data . + * @return . + */ + protected void onDragDrop(DNDEvent event) { + + super.onDragDrop(event); + + if(event.getData() != null){ + List listItemsSource = event.getData(); + GWT.log("Number of move " + listItemsSource.size()); + + FileModel sourceFileModel = null; //for print + + for(TreeStoreModel itemSource : listItemsSource){ + + sourceFileModel = (FileModel) itemSource.getModel(); + + if(sourceFileModel.getParentFileModel()!=null) + GWT.log("Source Name " + sourceFileModel.getName() + " id " + sourceFileModel.getIdentifier() + " end drag " + " Parent Name: " + sourceFileModel.getParentFileModel().getName() + "id " + sourceFileModel.getParentFileModel().getIdentifier()); + else + GWT.log("Source Name " + sourceFileModel.getName() + " id " + sourceFileModel.getIdentifier() + " end drag "); + + GWT.log("Child count: " + itemSource.getChildCount()); + + panel.fetchTS(sourceFileModel.getIdentifier(), false , true); + + } + } + + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DroppingArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DroppingArea.java new file mode 100644 index 0000000..362d59d --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/DroppingArea.java @@ -0,0 +1,214 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import org.gcube.portlets.user.reportgenerator.client.ReportGenerator; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.workspace.client.workspace.GWTWorkspaceItem; +import org.gcube.portlets.user.workspace.client.workspace.folder.item.GWTExternalImage; + +import com.extjs.gxt.ui.client.widget.Component; +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HasAlignment; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; + + +/** + * DroppingArea class is a Widget you can drop image on + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version May 20012 (3.5) + */ +public class DroppingArea extends Component { + + private String expectedContent = ""; + + private VerticalPanel mainPanel; + private Image droppedImage; + private Presenter presenter; + + private String idInBasket; + + private String currentUser; + private String currentScope; + + Label label; + + private int width, height; + + /** + * @param presenter . + * @param width . + * @param height . + * @param tag the label to display + */ + public DroppingArea(Presenter presenter, int width, int height, String tag) { + if (tag.equals("")) { + tag = "No suggestions available"; + } + this.width = width; + this.height = height; + this.presenter = presenter; + mainPanel = new VerticalPanel(); + super.setWidth(width+"px"); + super.setHeight(height+"px"); + mainPanel.setWidth(width+"px"); + mainPanel.setHeight(height+"px"); + setElement(mainPanel.getElement()); + + addStyleName("droppingArea-Image"); + + mainPanel.setHorizontalAlignment(HasAlignment.ALIGN_CENTER); + mainPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); + + label = new Label(tag); + label.addStyleName("label"); + mainPanel.add(label); + + droppedImage = null; + } + + public void add(Widget w) { + mainPanel.add(w); + } + /** + * called when dropped an image on the area + * @param toShow the image to show + */ + public void showImage(Image toShow) { + + //mainPanel.remove(label); + mainPanel.clear(); + this.droppedImage = toShow; + toShow.setPixelSize(width, height); + + mainPanel.add(toShow); + presenter.storeChangeInSession(this); + + } + + /** + * + * @param url . + * @param id the id in the folder + */ + public void dropImage(String url, String id) + { + GWT.log("URL:" + url, null); + idInBasket = id; + showImage(new Image(url)); + } + + public void fetchImage(String identifier, boolean isInteralImage, boolean fullDetails) { + this.mask("fetching image, pleas wait", "loading-indicator"); + ReportGenerator.get().getWSTreeService().getImageById(identifier, isInteralImage, fullDetails, new AsyncCallback() { + + public void onSuccess(GWTWorkspaceItem result) { + unmask(); + GWTExternalImage image = (GWTExternalImage) result; + dropImage(image.getImageUrl(), image.getId()); + } + public void onFailure(Throwable caught) { + unmask(); + Window.alert("Could not fetch image from infrastructure " + caught.getCause()); + } + }); + } + + /** + * + * @return the image + */ + public Image getDroppedImage() { + if (droppedImage == null) + return new Image(); + return droppedImage; + } + + /** + * + * @return the possible content + */ + public Label getLabel() { + return label; + } + + /** + * + * @param label set the label + */ + public void setLabel(Label label) { + this.label = label; + } + + + /** + * return a URL which is lookable for on the web + * @param imageName . + * @param templateName . + * @return . + */ + public String getImageURL(String imageName, String templateName) { + currentUser = presenter.getCurrentUser(); + currentScope = presenter.getCurrentScope(); + /** + * Images will be stored under webapps/usersArea... + * GWT.getModuleBaseURL() returns * e.g. http://dlib28.isti.cnr.it/templatecreator/html/ + * need to get just http://dlib28.isti.cnr.it/ + */ + //remove "/html/" and get e.g. http://dlib28.isti.cnr.it/templatecreator + String host = GWT.getModuleBaseURL().substring(0, GWT.getModuleBaseURL().length()-6); + + //loog for last slash + int lastSlash = host.lastIndexOf("/"); + + //get what i need : e.g. http://dlib28.isti.cnr.it/ or host = "http://localhost:8080/"; + host = host.substring(0, lastSlash +1 ); + //host = "http://localhost:8080/"; + + String imgURL = host + "usersArea/" + currentScope + "/templates/" + + currentUser + "/CURRENT_OPEN/images/" + imageName; + + return imgURL; + } + + /** + * + * @return . + */ + public String getIdInBasket() { + return idInBasket; + } + + /** + * + * @param idInBasket . + */ + public void setIdInBasket(String idInBasket) { + this.idInBasket = idInBasket; + } + /** + * + * @return expectedContent + */ + public String getExpectedContent() { + return expectedContent; + } + + /** + * + * @param expectedContent . + */ + public void setExpectedContent(String expectedContent) { + this.expectedContent = expectedContent; + if (expectedContent.compareTo("") != 0) + label.setText(expectedContent); + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenTableCell.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenTableCell.java new file mode 100644 index 0000000..c296de6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenTableCell.java @@ -0,0 +1,158 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import com.google.gwt.user.client.ui.TextArea; +/** + * + * @author massi + * + */ +public class GenTableCell extends TextArea { + + /** + * + */ + private int cellWidth; + /** + * + */ + private int cellHeight; + /** + * + */ + private int rowindex; + /** + * + */ + private int colindex; + /** + * + */ + private int colspan; + /** + * + */ + boolean selected = false; + /** + * + * @param rowindex + * @param colindex + */ + public GenTableCell() { + super(); + this.rowindex = 0; + this.colindex = 0; + this.colspan = 1; + + } + /** + * + * @param rowindex + * @param colindex + */ + public GenTableCell(int rowindex, int colindex, int cellWidth, int colspan) { + super(); + this.rowindex = rowindex; + this.colindex = colindex; + this.colspan = colspan; + this.cellWidth = cellWidth; + } + /** + * + * @return + */ + public int getWidth() { + return cellWidth; + } + /** + * + * @param width + */ + public void setWidth(int width) { + this.cellWidth = width; + } + /** + * + * @return + */ + public int getHeight() { + return cellHeight; + } + /** + * + * @param height + */ + public void setHeight(int height) { + this.cellHeight = height; + } + /** + * + * @return + */ + public int getRowindex() { + return rowindex; + } + /** + * + * @param rowindex + */ + public void setRowindex(int rowindex) { + this.rowindex = rowindex; + } + /** + * + * @return + */ + public int getColindex() { + return colindex; + } + /** + * + * @param colindex + */ + public void setColindex(int colindex) { + this.colindex = colindex; + } + /** + * + * @return + */ + public boolean isSelected() { + return selected; + } + /** + * + * @param selected + */ + public void setSelected(boolean selected) { + this.selected = selected; + } + /** + * + * @return + */ + public int getColspan() { + return colspan; + } + /** + * + * @param colspan + */ + public void setColspan(int colspan) { + this.colspan = colspan; + } + public int getCellWidth() { + return cellWidth; + } + public void setCellWidth(int cellWidth) { + this.cellWidth = cellWidth; + } + public int getCellHeight() { + return cellHeight; + } + public void setCellHeight(int cellHeight) { + this.cellHeight = cellHeight; + } + +} + + diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenericTable.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenericTable.java new file mode 100644 index 0000000..10e2d78 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/GenericTable.java @@ -0,0 +1,145 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import java.util.ArrayList; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.TableCell; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.VerticalPanel; + +/** + * + * @author Massimiliano Assante ISTI-CNR + * @version 1.0 + * + */ +public class GenericTable extends Composite { + private VerticalPanel myPanel; + private FlexTable myTable; + + Presenter presenter; + + private int rows; + private int cols; + + private int cellWidth; + private int cellSpacing = 1; + private int cellPadding = 0; + + private GenTableCell selectedCell = null; + + /** + * constructor called when reading the model + * @param sTable + */ + public GenericTable(SerializableTable sTable, Presenter presenter, int top, int left, int width, int height) { + + commonConstructorCode(presenter); + this.rows = sTable.getRowCount(); + this.cols = sTable.getColsNo(); + + /** + * construct the table + */ + for (int i = 0; i < rows; i++) { + for (int j = 0; j < sTable.getCellCount(i); j++) { + TableCell toPut = sTable.getValue(i, j); + int cellWidth = toPut.getCellWidth(); + int cellHeight = toPut.getCellHeight(); + int colspan = toPut.getColspan(); + GenTableCell toAdd = new GenTableCell(i, j, cellWidth, colspan); + toAdd.setText(toPut.getContent()); + toAdd.setStyleName("tableBorder"); + toAdd.setWidth(""+cellWidth+"px"); + myTable.setWidget(i, j, toAdd); + myTable.getFlexCellFormatter().setColSpan(i, j, colspan); + } + } + + myPanel = new VerticalPanel(); + myPanel.setWidth(width+"px"); + myPanel.setStyleName("d4sFrame"); + myPanel.add(myTable); + initWidget(myPanel); + } + /** + * common Constructors Code + */ + private void commonConstructorCode(Presenter presenter) { + this.presenter = presenter; + myTable= new FlexTable(); + myTable.setWidth("90%"); + myTable.setCellSpacing(cellSpacing); + myTable.setCellPadding(cellPadding); + + } + + + public FlexTable getMyTable() { + return myTable; + } + + public void setMyTable(FlexTable myTable) { + this.myTable = myTable; + } + + public int getRowsNo() { + return rows; + } + + public void setRows(int rows) { + this.rows = rows; + } + + public int getCols() { + return cols; + } + + public void setCols(int cols) { + this.cols = cols; + } + + /** + * + * @return + */ + public SerializableTable getSerializable() { + SerializableTable toReturn = new SerializableTable(this.cols); + for (int i = 0; i < myTable.getRowCount(); i++) { + toReturn.addRow(getRow(i)); + } + + return toReturn; + } + + public ArrayList getRow(int i) { + ArrayList toReturn = new ArrayList(); + for (int j = 0; j < myTable.getCellCount(i); j++) { + GenTableCell tb = (GenTableCell) myTable.getWidget(i, j); + int colspan = tb.getColspan(); + + toReturn.add(new TableCell(tb.getText(), colspan, tb.getWidth(), tb.getHeight())); + } + return toReturn; + } + + + public GenTableCell getSelectedCell() { + return selectedCell; + } + + /** + * adda a column at the left of the selected cell of the selected table + * TODO: next version + */ + public void addColumnLeft(int colindex) { + // myTable.insertCell(beforeRow, beforeColumn) + } + + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ImageArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ImageArea.java new file mode 100644 index 0000000..f4b6702 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ImageArea.java @@ -0,0 +1,158 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + + +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.VerticalPanel; +/** + * ImageArea class is the Widget that goes into the workspace + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ +public class ImageArea extends Composite { + + private String templateName; + private String imageName; + + private String currentUser; + private String currentScope; + + VerticalPanel myPanel; + Image myImage = new Image(); + + /** + * Creates an image with a specified URL. The load event will be fired once + * the image at the given URL has been retrieved by the browser. + * + * @param presenter . + * @param param the imageName of the image to be displayed or the URL to be displayed depending on the isURL param + * @param myTemplate the template name that owns the image, useful when template it's saved with another name + * to eventually copy the images in the new template images folder + * @param isURL true if passing a URL, false is passing image name + * @param w width + * @param h height + */ + public ImageArea(Presenter presenter, String param, String myTemplate, boolean isURL, int w, int h) { + myPanel = new VerticalPanel(); + currentUser = presenter.getCurrentUser(); + currentScope = presenter.getCurrentScope(); + //Window.alert("Image Area"); + + if (isURL) { + //need to get the name from the URL + int lastSlash = param.lastIndexOf("/"); + if (lastSlash > -1) { + imageName = param.substring(lastSlash+1, param.length()); + } + else + imageName = param; + this.templateName = "CURRENT_OPEN"; + //Window.alert(param); + myImage.setUrl(param); + + } else { + imageName = param; + this.templateName = myTemplate; + + String imgURL = getImageURL(imageName, "CURRENT_OPEN"); + + + myImage.setUrl(imgURL); + } + myImage.setPixelSize(w, h); + myPanel.setStyleName("d4sFrame"); + myPanel.add(myImage); + initWidget(myPanel); + } + + /** + * + * @return . + */ + public String getUrl() { + return myImage.getUrl(); + } + + /** + * return a URL which is lookable for on the web + * @param imageName . + * @param templateName . + * @return . + */ + public String getImageURL(String imageName, String templateName) { + + + /** + * Images will be stored under webapps/usersArea... + * GWT.getModuleBaseURL() returns * e.g. http://dlib28.isti.cnr.it/templatecreator/html/ + * need to get just http://dlib28.isti.cnr.it/ + */ + //remove "/html/" and get e.g. http://dlib28.isti.cnr.it/templatecreator + String host = GWT.getModuleBaseURL().substring(0, GWT.getModuleBaseURL().length()-6); + + //loog for last slash + int lastSlash = host.lastIndexOf("/"); + + //get what i need : e.g. http://dlib28.isti.cnr.it/ or host = "http://localhost:8080/"; + host = host.substring(0, lastSlash +1 ); + //host = "http://localhost:8080/"; + + String imgURL = host + "usersArea/" + currentScope + "/templates/" + + currentUser + "/" + "CURRENT_OPEN" + "/images/" + imageName; + GWT.log(imgURL); + return imgURL; + } + /** + * + * @return a string containing the owner template name + */ + public String getTemplateName() { + return templateName; + } + + /** + * + * @param myTemplate the template owner + */ + public void setTemplateName(String myTemplate) { + this.templateName = myTemplate; + } + + /** + * + * @return . + */ + public String getImageName() { + return imageName; + } + + /** + * + * @param imageName . + */ + public void setImageName(String imageName) { + this.imageName = imageName; + } + /** + * + * @return the scope in which the application is running on + */ + public String getCurrentScope() { + return currentScope; + } + + /** + * + * @return the user username who is using the application + */ + public String getCurrentUser() { + return currentUser; + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ReportTextArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ReportTextArea.java new file mode 100644 index 0000000..6683054 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/ReportTextArea.java @@ -0,0 +1,260 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.client.ImageConstants; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.dialog.CommentDialog; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.AbsolutePanel; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Image; +import com.google.gwt.user.client.ui.VerticalPanel; + + +/** + * ReportTextArea class represent the generic Widget that can be placed in the UI Component + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class ReportTextArea extends Composite { + + /** + * the allowance when mouse cursor is on borders + */ + public final int DELTA = 7; + + + /** + * variables of the components + */ + protected int left, top, width, height; + + /** + * the controller instance of the widget + */ + private Presenter presenter; + + private ComponentType type; + + protected AbsolutePanel mainPanel; + + protected HorizontalPanel topPanel; + + protected VerticalPanel resizablePanel; + + protected Image commentImage; + /** + * + * @return . + */ + public VerticalPanel getResizablePanel() { + return resizablePanel; + } + protected ReportTextArea myInstance; + + /** + * default constructor + * + */ + public ReportTextArea() { + super(); + } + + /** + * + * @param presenter . + * @param left left + * @param top top + * @param width . + * @param height . + * @param type a + */ + public ReportTextArea(ComponentType type, final Presenter presenter, int left, int top, int width, int height, boolean hasComments) { + myInstance = this; + + + this.type = type; + this.presenter = presenter; + this.left = left; + this.top = top; + this.width = width; + this.height = height; + + mainPanel = new AbsolutePanel(); + + topPanel = new HorizontalPanel(); + resizablePanel = new VerticalPanel(); + + mainPanel.setPixelSize(width, height); + + topPanel.setPixelSize(30, 15); + resizablePanel.setPixelSize(width, height); + + commentImage = new Image((hasComments) ? ImageConstants.IMAGE_COMMENTS : ImageConstants.IMAGE_COMMENTS_GRAY); + commentImage.setTitle("Show user comments"); + topPanel.add(commentImage); + + commentImage.setStyleName("selectable"); + commentImage.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { + String previousComments = ""; + int commentHeight = -1; + previousComments = presenter.getComponentComments(myInstance).getComment(); + commentHeight = presenter.getComponentComments(myInstance).getAreaHeight(); + CommentDialog dlg = new CommentDialog(presenter.getEventBus(), myInstance, presenter.getCurrentUser(), previousComments, commentHeight); + dlg.setPopupPosition(commentImage.getAbsoluteLeft()+20, commentImage.getAbsoluteTop()); + dlg.show(); + } + }); + + topPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); + + mainPanel.add(resizablePanel, 0, 0); + mainPanel.add(topPanel, width-18, 0); + mainPanel.setStyleName("d4sFrame"); + initWidget(mainPanel); + } + + + /** + * + * @return . + */ + public ComponentType getType() { + return type; + } + + /** + * + * @param type . + */ + public void setType(ComponentType type) { + this.type = type; + } + + + /** + * used to resize the panel + * @param width w + * @param height h + */ + public void resizePanel(int width, int height) { + if (height > 15 && width > 15) { + mainPanel.setPixelSize(width, height); + resizablePanel.setPixelSize(width, height); + mainPanel.setWidgetPosition(topPanel, width-15, 0); + } + } + + + /*** + * + * @param height g + */ + public void setHeight(int height) { + + if (height > this.height) { + mainPanel.setHeight(""+(height+20)); + resizablePanel.setHeight(""+(height+20)); + mainPanel.setWidgetPosition(topPanel, width-15, 0); + } + + } + /** + * + * @param left . + * @param top . + */ + public void repositionMyPanel(int left, int top) { + //mainPanel.setWidgetPosition(resizablePanel, left, top); + } + + + /** + * @return . + */ + public int getLeft() { + return left; + } + + + /** + * + * @param left . + */ + public void setLeft(int left) { + this.left = left; + } + + /** + * + * @return -. + */ + public int getTop() { + return top; + } + + /** + * + * @param top . + */ + public void setTop(int top) { + this.top = top; + } + + /** + * + * @return the controller instance of the widget + */ + public Presenter getController() { + return presenter; + } + + + /** + * + * @return . + */ + public ReportTextArea getMyInstance() { + return myInstance; + } + + /** + * + * @param myInstance . + */ + public void setMyInstance(ReportTextArea myInstance) { + this.myInstance = myInstance; + } + + public void removeCommentView() { + commentImage.setUrl(ImageConstants.IMAGE_COMMENTS_GRAY); + } + public void addCommentView() { + commentImage.setUrl(ImageConstants.IMAGE_COMMENTS); + } + + public void showComment(String comment) { +// final Window window = new Window(); +// window.setTitle(""); +// window.setMaximizable(true); +// window.setResizable(true); +// window.setLayout(new FitLayout()); +// window.setWidth(200); +// window.setHeight(100); +// window.setModal(false); +// +// Panel windowPanel = new Panel(); +// windowPanel.setBaseCls("comment-popup"); +// windowPanel.setHtml(comment); +// windowPanel.setShadow(true); +// window.add(windowPanel); +// window.setPosition(commentImage.getAbsoluteLeft()+25, commentImage.getAbsoluteTop()); +// window.show(); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/TSArea.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/TSArea.java new file mode 100644 index 0000000..aad5dc5 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/targets/TSArea.java @@ -0,0 +1,314 @@ +package org.gcube.portlets.user.reportgenerator.client.targets; + +import java.util.LinkedList; +import java.util.List; + +import org.gcube.portlets.d4sreporting.common.shared.SerializableTSFilter; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTSinfo; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.user.reportgenerator.client.ReportGenerator; +import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; +import org.gcube.portlets.user.reportgenerator.client.dialog.TimeSeriesDialog; +import org.gcube.portlets.user.reportgenerator.client.dialog.TimeSeriesFilter; +import org.gcube.portlets.user.reportgenerator.client.dialog.TimeSeriesSampleDialog; +import org.gcube.portlets.user.workspace.client.workspace.GWTWorkspaceItem; +import org.gcube.portlets.user.workspace.client.workspace.folder.item.GWTTimeSeries; + +import com.extjs.gxt.ui.client.widget.Composite; +import com.extjs.gxt.ui.client.widget.VerticalPanel; +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.Grid; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; + + + +/** + * TSArea class is a Widget you can drop a Workspace Time Series on + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version July 2011 (3.0) + */ +public class TSArea extends Composite { + + private VerticalPanel mainPanel; + private SerializableTimeSeries sts = new SerializableTimeSeries(); + private String idInBasket; + private Presenter presenter; + private FlexTable flexTable; + private TSArea singleton; + + VerticalPanel tableContainer = new VerticalPanel(); + Grid metadata = new Grid(3, 2); + + Label label; + /** + * @param presenter . + * @param width . + * @param height . + * @param sts the time series + */ + public TSArea(Presenter presenter, int width, int height, SerializableTimeSeries sts) { + singleton = this; + this.presenter = presenter; + mainPanel = new VerticalPanel(); + //setElement(mainPanel.getElement()); + + mainPanel.setStyleName("timeseriesArea"); + mainPanel.addStyleName("timeseriesArea_bg"); + mainPanel.setWidth(width); + mainPanel.setHeight(height); + + mainPanel.add(new HTML(" ", true)); + this.sts = sts; + if (sts != null) { + if (sts.getTsMetadata() != null) { + showTS(sts.getTsMetadata()); + } + } + initComponent(mainPanel); + mainPanel.layout(true); + } + + + /** + * called when dropped a TS on the area + * @param toShow the TS to show + */ + public void showTS(SerializableTSinfo toShow) { + mainPanel.removeAll(); + mainPanel.removeStyleName("timeseriesArea_bg"); + tableContainer.removeAll(); + + metadata.setWidget(0, 0, new HTML("TS name:", true)); + metadata.setWidget(0, 1, new HTML(toShow.getTitle())); + metadata.setWidget(1, 0, new HTML("Creation Date: ", true)); + metadata.setWidget(1, 1, new HTML(toShow.getTimeSeriesCreationDate())); + metadata.setWidget(2, 0, new HTML("Total rows:", true)); + metadata.setWidget(2, 1, new HTML(""+toShow.getDimension())); + + + List headers = toShow.getHeaderLabels(); + flexTable = new FlexTable(); + + int n = (headers.size() > 10) ? 10 : headers.size(); + + for (int i = 0; i < n ; i++) { + flexTable.getCellFormatter().setStyleName(0, i, "timeSeries_header"); + flexTable.setWidget(0, i, new HTML(headers.get(i))); + flexTable.setWidget(1, i, new HTML("..")); + flexTable.getCellFormatter().setStyleName(1, i, "timeSeries_td"); + } + if (headers.size() > 10) { + flexTable.setWidget(0, 11, new HTML(" more ..")); + flexTable.setWidget(1, 11, new HTML("..")); + flexTable.getCellFormatter().setStyleName(0, 11, "timeSeries_header"); + flexTable.getCellFormatter().setStyleName(1, 11, "timeSeries_td"); + } + + tableContainer.add(flexTable); + + mainPanel.add(metadata); + mainPanel.add(tableContainer); + + Button moreDetails = new Button("View Timeseries Metadata"); + Button filter = new Button("Filter Table"); + Button showSample = new Button("Show Sample"); + + HorizontalPanel buttonsPanel = new HorizontalPanel(); + buttonsPanel.setSpacing(5); + buttonsPanel.add(moreDetails); + buttonsPanel.add(filter); + buttonsPanel.add(showSample); + + mainPanel.add(buttonsPanel); + + moreDetails.addClickHandler(viewMetadataTS); + showSample.addClickHandler(showTSSample); + filter.addClickHandler(applyFilterTs); + + //TODO: check this + presenter.storeChangeInSession(this); + mainPanel.layout(true); + } + + ClickHandler viewMetadataTS = new ClickHandler() { + public void onClick(ClickEvent event) { + TimeSeriesDialog dlg = new TimeSeriesDialog(sts.getTsMetadata()); + dlg.setAnimationEnabled(true); + dlg.show(); + } + + }; + + ClickHandler applyFilterTs = new ClickHandler() { + + public void onClick(ClickEvent event) { + TimeSeriesFilter dlg = new TimeSeriesFilter(singleton, sts); + //dlg.setPopupPosition(sender.getAbsoluteLeft(), sender.getAbsoluteTop()); + dlg.setAnimationEnabled(true); + dlg.show(); + } + + }; + + ClickHandler showTSSample = new ClickHandler() { + public void onClick(ClickEvent event) { + presenter.getModel().getModelService().getSampleTimeSeries(sts, new AsyncCallback() { + public void onFailure(Throwable caught) { Window.alert("There were Problem contacting Server, please try later");} + + public void onSuccess(SerializableTable result) { + SerializableTable toPass = result; + TimeSeriesSampleDialog dlg = new TimeSeriesSampleDialog(toPass); + dlg.setAnimationEnabled(true); + dlg.show(); + } + }); + } + }; + /** + * + * @param droppedTS the dropped timeseries + */ + public void dropTS(GWTTimeSeries droppedTS) { + idInBasket = droppedTS.getId(); + SerializableTSinfo tsMetadata = convertWSTS2SerialazableTS(droppedTS); + sts = new SerializableTimeSeries(null, tsMetadata); + GWT.log("showTS TS"); + showTS(tsMetadata); + } + + public void fetchTS(String identifier, boolean isInteralImage, boolean fullDetails) { + GWT.log("FETCH TS"); + this.mask("fetching TimeSeries, pleas wait", "loading-indicator"); + + ReportGenerator.get().getWSTreeService().getTimeSeriesById(identifier, new AsyncCallback() { + public void onSuccess(GWTWorkspaceItem result) { + unmask(); + GWTTimeSeries ts = (GWTTimeSeries) result; + dropTS(ts); + } + public void onFailure(Throwable caught) { + unmask(); + Window.alert("Could not fetch Time Series from infrastructure " + caught.getCause()); + } + }); + } + + /** + * converts the WorkSpace TS Object into a Report TS Object + * @param md the TS metadata to convert + * @return + */ + private SerializableTSinfo convertWSTS2SerialazableTS(GWTTimeSeries md) { + SerializableTSinfo tsMetadata = new SerializableTSinfo(md.getId(), md.getName(), md.getDescription(), md.getOwner(), + md.getCreationTime(), md.getLastModificationTime(), md.getTimeSeriesId(), md.getTitle(), md.getCreator(), + md.getTimeSeriesDescription(), md.getTimeSeriesCreationDate(), + md.getPublisher(), md.getSourceId(), md.getSourceName(), md.getRights(), md.getDimension(), md.getHeaderLabels()); + + return tsMetadata; + } + + /** + * refresh the headers once the TS has been filtered + */ + public void refreshHeaders() { + tableContainer.removeAll(); + flexTable = new FlexTable(); + + List filteredHeaders = new LinkedList(); + SerializableTSFilter tf = sts.getFilter(); + + for (Integer colNo : tf.getColsNumberToShow()) { + String toAdd = sts.getTsMetadata().getHeaderLabels().get(colNo); + filteredHeaders.add(toAdd); + } + + + int n = (filteredHeaders.size() > 10) ? 10 : filteredHeaders.size(); + + for (int i = 0; i < n ; i++) { + flexTable.getCellFormatter().setStyleName(0, i, "timeSeries_header"); + flexTable.setWidget(0, i, new HTML(filteredHeaders.get(i))); + flexTable.setWidget(1, i, new HTML("..")); + flexTable.getCellFormatter().setStyleName(1, i, "timeSeries_td"); + } + if (filteredHeaders.size() > 10) { + flexTable.setWidget(0, 11, new HTML(" more ..")); + flexTable.setWidget(1, 11, new HTML("..")); + flexTable.getCellFormatter().setStyleName(0, 11, "timeSeries_header"); + flexTable.getCellFormatter().setStyleName(1, 11, "timeSeries_td"); + } + + tableContainer.add(flexTable); + Grid newGrid = new Grid(1, 2); + newGrid.setWidget(0, 0, new HTML("Selected Interval: ", true)); + newGrid.setWidget(0, 1, new HTML(tf.getFrom() + " - " + tf.getTo() )); + tableContainer.add(newGrid); + + } + /** + * + * @return the possible content + */ + public Label getLabel() { + return label; + } + + /** + * + * @param label set the label + */ + public void setLabel(Label label) { + this.label = label; + } + + + /** + * + * @return . + */ + public String getIdInBasket() { + return idInBasket; + } + + /** + * + * @param idInBasket . + */ + public void setIdInBasket(String idInBasket) { + this.idInBasket = idInBasket; + } + + /** + * + * @return . + */ + public SerializableTimeSeries getSts() { + return sts; + } + + /** + * + * @param sts . + */ + public void setSts(SerializableTimeSeries sts) { + this.sts = sts; + } + + /** + * + * @param tsf the new ts filter + */ + public void setNewFilter(SerializableTSFilter tsf) { + this.sts.setFilter(tsf); + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.java b/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.java new file mode 100644 index 0000000..01a2c47 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.java @@ -0,0 +1,26 @@ +/** + * + */ +package org.gcube.portlets.user.reportgenerator.client.toursteps; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.Element; +import com.google.gwt.uibinder.client.UiBinder; +import com.google.gwt.user.client.ui.HTML; + +/** + * @author massi + * + */ +public class Intro extends HTML { + + private static IntroUiBinder uiBinder = GWT.create(IntroUiBinder.class); + + interface IntroUiBinder extends UiBinder { + } + + public Intro() { + setHTML(uiBinder.createAndBindUi(this).getInnerHTML()); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.ui.xml b/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.ui.xml new file mode 100644 index 0000000..9df30c6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/client/toursteps/Intro.ui.xml @@ -0,0 +1,31 @@ + + + + /* Add CSS here. See the GWT docs on UI Binder for more details */ + .important { + font-weight: bold; + } + +
+ +
+
+ gCube Reporting + allows users to create Reports and generate different + export formats + (OpenXML, HTML, PDF) based on results retrieved from the + infrastructure. +
+
+ gCube Templates are loaded by this + gCube Report Generator + to produce actual reports. +
+
+ Discover + gCube Reporting features through this quick tour. +
+
+
+
\ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/portlet/ReportGeneratorPortlet.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/portlet/ReportGeneratorPortlet.java new file mode 100644 index 0000000..e9d3052 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/portlet/ReportGeneratorPortlet.java @@ -0,0 +1,44 @@ + +package org.gcube.portlets.user.reportgenerator.server.portlet; + +import javax.portlet.GenericPortlet; +import javax.portlet.ActionRequest; +import javax.portlet.PortletSession; +import javax.portlet.RenderRequest; +import javax.portlet.ActionResponse; +import javax.portlet.RenderResponse; +import javax.portlet.PortletException; +import java.io.IOException; +import javax.portlet.PortletRequestDispatcher; + +import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper; + +import com.liferay.portal.PortalException; +import com.liferay.portal.SystemException; +import com.liferay.portal.model.User; +import com.liferay.portal.service.UserLocalServiceUtil; + +/** + * ReportGeneratorPortlet Portlet Class + * @author massi + */ +public class ReportGeneratorPortlet extends GenericPortlet { + + public void doView(RenderRequest request, RenderResponse response) + throws PortletException, IOException { + + ScopeHelper.setContext(request); + + PortletRequestDispatcher dispatcher = + getPortletContext().getRequestDispatcher("/WEB-INF/jsp/ReportGeneratorPortlet_view.jsp"); + dispatcher.include(request, response); + + } + + + public void processAction(ActionRequest request, ActionResponse response) + throws PortletException, IOException { + + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/DocLibraryUtil.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/DocLibraryUtil.java new file mode 100644 index 0000000..bfd8e54 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/DocLibraryUtil.java @@ -0,0 +1,311 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.gcube.application.framework.core.session.ASLSession; +import org.gcube.common.core.utils.logging.GCUBELog; +import org.gcube.portal.custom.communitymanager.OrganizationsUtil; +import org.gcube.portlets.admin.wfdocslibrary.shared.PermissionType; +import org.gcube.portlets.admin.wfdocslibrary.shared.Step; +import org.gcube.portlets.admin.wfdocslibrary.shared.WfRole; + +import com.liferay.portal.kernel.exception.PortalException; +import com.liferay.portal.kernel.exception.SystemException; +import com.liferay.portal.model.Organization; +import com.liferay.portal.model.ResourceConstants; +import com.liferay.portal.model.Role; +import com.liferay.portal.model.User; +import com.liferay.portal.service.CompanyLocalServiceUtil; +import com.liferay.portal.service.OrganizationLocalServiceUtil; +import com.liferay.portal.service.PermissionLocalServiceUtil; +import com.liferay.portal.service.ResourceLocalServiceUtil; +import com.liferay.portal.service.ServiceContext; +import com.liferay.portal.service.UserLocalServiceUtil; +import com.liferay.portlet.documentlibrary.NoSuchFolderException; +import com.liferay.portlet.documentlibrary.model.DLFileEntry; +import com.liferay.portlet.documentlibrary.model.DLFolder; +import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil; +import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil; + +public class DocLibraryUtil { + + public static final String WORKFLOWS_FOLDER = "Workflow Documents"; + /** + * + */ + private static GCUBELog log = new GCUBELog(DocLibraryUtil.class); + + /** + * write the Report File (payload) into Liferay DocLibrary in the workflowdocs folder + * @param roles + * @param start each Step contains a Map> that is needed in the writeFileIntoDocLibrary + * @param fileName + * @param buffer the payload as byte array + */ + public static boolean writeFileIntoDocLibrary(ASLSession session, List roles, Step start, String fileName, byte[] buffer) { + long docfolderid = -1; + try { + docfolderid = getWfFolder(session); + long userId = getUserId(session); + //write the file into doclib + DLFileEntry fileEntry = DLFileEntryLocalServiceUtil.addFileEntry( + userId, + getGroupID(session), + docfolderid, + fileName, + fileName, + "workflow document", + "", + "", + buffer, + new ServiceContext()); + log.debug("Wrote file into DocumentLibrary"); + + + + //get the file entry resource id + long resourceId = ResourceLocalServiceUtil.getResource(fileEntry.getCompanyId(), + DLFileEntry.class.getName(), ResourceConstants.SCOPE_INDIVIDUAL, String.valueOf(fileEntry.getFileEntryId())).getResourceId(); + + //set the permission on the file for each role + for (Role role : roles) { + String[] actionIds = getPermissionsFromWfStep(role, start); + PermissionLocalServiceUtil.setRolePermissions(role.getRoleId(), actionIds, resourceId); + log.debug("set the permissions for Role: " + role.getName()); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + log.debug(" WROTE INTO DOCsLib and ADDING permissions for name: " + fileName); + return true; + } + + public static DLFileEntry updateFileIntoDocLibrary(ASLSession session, String workflowid, byte[] buffer) { + long docfolderid = -1; + DLFileEntry fileEntry = null; + try { + fileEntry = getFileEntry(session, workflowid); + docfolderid = getWfFolder(session); + long userId = getUserId(session); + + String fileName = fileEntry.getTitle(); + log.debug("Update file into DocumentLibrary with Name: " + fileName); + + DLFileEntryLocalServiceUtil.updateFileEntry( + userId, + getGroupID(session), + docfolderid, + fileEntry.getName(), + fileEntry.getName(), + fileName, + fileEntry.getDescription(), + "", + true, + "", + buffer, + new ServiceContext()); + + log.debug("Update file into DocumentLibrary"); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + return fileEntry; + } + + public static boolean deleteFileFromDocLibrary(ASLSession session, String workflowid) { + DLFileEntry fileEntry = null; + try { + fileEntry = getFileEntry(session, workflowid); + DLFileEntryLocalServiceUtil.deleteDLFileEntry(fileEntry); + log.debug("Deleted"); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + /** + * + * @param session + * @param workflowid + * @return + * @throws Exception + * @throws SystemException + * @throws PortalException + */ + public static InputStream getFileEntryAsStream(ASLSession session, String workflowid) throws Exception { + String titleWithExtension = workflowid+".zip"; + + DLFileEntry fileEntry = DLFileEntryLocalServiceUtil.getFileEntryByTitle(getGroupID(session), getWfFolder(session), + titleWithExtension); + + return DLFileEntryLocalServiceUtil.getFileAsStream(fileEntry.getCompanyId(), + getUserId(session), getGroupID(session), getWfFolder(session), fileEntry.getName()); + + } + + public static DLFileEntry getFileEntry(ASLSession session, String workflowid) throws PortalException, SystemException, Exception { + String titleWithExtension = workflowid+".zip"; + + return DLFileEntryLocalServiceUtil.getFileEntryByTitle(getGroupID(session), getWfFolder(session), + titleWithExtension); + + } + + /** + * + * @param role is the liferay role, for convention is created as ROLENAME_WFID e.g. EDITOR_123 + * @param step containts the permissions attached to each role (just the name, e.g. EDITOR) + * @return the permissions to apply + */ + public static String[] getPermissionsFromWfStep(Role role, Step step) { + ArrayList toConvert = new ArrayList(); + for (WfRole steprole : step.getPermissions().keySet()) { + System.out.println("Steprole: "+ steprole.getRolename()); + String name = role.getName().split("_")[0]; //e.g. EDITOR <- EDITOR_123 + System.out.println("role Name: "+ name); + if (steprole.getRolename().equals(name)) { + toConvert = step.getPermissions().get(steprole); + } + } + String[] toReturn = new String[toConvert.size()]; + int i = 0; + for (PermissionType p : toConvert) { + toReturn[i] = getLRActionIdFromWfPermissionType(p); + i++; + } + return toReturn; + } + /** + * check the existence of the WFFolder or create it if not exists + * @param session + * @return true is everything goes ok + * @throws PortalException + * @throws SystemException + */ + public static long getWfFolder(ASLSession session) throws Exception { + long parentFolderId = 0; + DLFolder folder = null; + if (! wfFolderExists(session)) { + folder = DLFolderLocalServiceUtil.addFolder(getUserId(session), getGroupID(session), parentFolderId, WORKFLOWS_FOLDER, "Folder for Workflow Documents", new ServiceContext()); + log.debug("Folder for WorkflowDocs created: /" + WORKFLOWS_FOLDER); + } else + folder = DLFolderLocalServiceUtil.getFolder( getGroupID(session), parentFolderId, WORKFLOWS_FOLDER); + return folder.getFolderId(); + } + /** + * + * @param session the ASL Session instance + * @return true if the workflow docs exists + */ + public static boolean wfFolderExists(ASLSession session) { + try { + long groupid = getGroupID(session); + long parentfolder = 0; + if (DLFolderLocalServiceUtil.getFolder(groupid, parentfolder, "Workflow Documents") != null) + return true; + else + return false; + } + catch (NoSuchFolderException ex) { + log.debug("Folder does not exists"); + return false; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } + /** + * + * @param session + * @return + * @throws PortalException + * @throws SystemException + */ + public static long getGroupID(ASLSession session) throws PortalException, SystemException { + long organizationid = session.getGroupId(); + Organization myOrg = OrganizationLocalServiceUtil.getOrganization(organizationid); + return myOrg.getGroup().getGroupId(); + } + /** + * + * @return the company webid + * @throws PortalException + * @throws SystemException + */ + public static long getCompanyID() throws PortalException, SystemException { + return OrganizationsUtil.getCompany().getCompanyId(); + } + /** + * + * @param session the ASL Session instance + * @return the list of the root folders + * @throws SystemException . + * @throws PortalException . + */ + public static List getFolders(ASLSession session) throws SystemException, PortalException { + long companyid = getCompanyID(); + List folders = null; + folders = DLFolderLocalServiceUtil.getFolders(companyid); + for (DLFolder folder : folders) { + log.debug("Folder name: " + folder.getName() + " ID: " + folder.getFolderId() + " Parent: " + folder.getParentFolderId() + " Groupid: " + folder.getGroupId()); + } + return folders; + } + + /** + * + * @param session the ASL Session instance + * @return the userid in the liferay system + */ + public static long getUserId(ASLSession session) { + List users = null; + long userId = 0; + try { + users = UserLocalServiceUtil.getUsers(0, UserLocalServiceUtil.getUsersCount()); + } catch (SystemException e) { + e.printStackTrace(); + } + for(User user: users){ + if(user.getScreenName().equalsIgnoreCase(session.getUsername())){ + userId = user.getUserId(); + break; + } + } + return userId; + } + + + /** + * needed to convert Workflows permission into Lifearay permissions (ActionIDs) + * @param type + * @return + */ + private static String getLRActionIdFromWfPermissionType(PermissionType type) { + switch (type) { + case EDIT_PERMISSIONS: + return "PERMISSIONS"; + case VIEW: + return "VIEW"; + case UPDATE: + return "UPDATE"; + case DELETE: + return "DELETE"; + case ADD_DISCUSSION: + return "ADD_DISCUSSION"; + case DELETE_DISCUSSION: + return "DELETE_DISCUSSION"; + case UPDATE_DISCUSSION: + return "UPDATE_DISCUSSION"; + default: + return ""; + } + } + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ImagesUploadServlet.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ImagesUploadServlet.java new file mode 100644 index 0000000..b2d9414 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ImagesUploadServlet.java @@ -0,0 +1,181 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet; + + + + +import java.io.File; +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.gcube.application.framework.core.session.ASLSession; +import org.gcube.application.framework.core.session.SessionManager; +import org.gcube.common.core.utils.logging.GCUBEClientLog; + +/** + * ImagesUploadServlet class is the server code delgated to receinve the byte stream and store i + * + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version October 2008 (0.2) + */ + +public class ImagesUploadServlet extends HttpServlet { + + static GCUBEClientLog _log = new GCUBEClientLog(ImagesUploadServlet.class); + + final String returnOKMessage = "OK"; + + private static final long serialVersionUID = 1L; + + private String currentUser; + + private String currentScope; + + /** + * + * @param message the msg + */ + public static void logger (String message) { + System.out.println("***" + message); + } + /** + * return the user template folder + * @param templateName + * @param currentDL . + * @param currentUser . + * @return . + */ + private String getTemplateFolder(String currentDL, String currentUser) { + _log.debug("getTemplateFolder Method called"); + // platform indipendent slash + String sl = File.separator; + //e.g. /home/massi/workspace/templategen/tomcat/webapps/ROOT + String path = System.getenv("CATALINA_HOME"); + path += sl + "webapps" + sl +"usersArea" + sl + currentDL + + sl + "templates" + sl + currentUser + sl ; + _log.debug("Returning Path= " + path); + return path; + + } + /** + * file upload handler + * @param request . + * @param response . + * @throws ServletException . + * @throws IOException . + */ + + public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + +// logger("ImagesUploadServlet received:"); +// +// currentUser = getUsername(request); +// currentScope = getVreName(request); +// +// String currTemplateName = request.getParameter("currTemplateName"); +// +// logger("currentUser: "+currentUser); +// logger("currentVRE: "+currentScope); +// logger("currTemplateName: "+currTemplateName); +// logger("CALLING :getTemplateFolder "); +// logger("RETURNED :getTemplateFolder "); +// //platform indipendent slash +// String sl = File.separator; +// String startDirectory = getTemplateFolder(currentScope, currentUser); //e.g. /home/massi/workspace/templategen/tomcat/webapps/ROOT +// int lastSlash = startDirectory.lastIndexOf(sl); +// startDirectory = startDirectory.substring(0, lastSlash); +// +// startDirectory += sl + "CURRENT_OPEN" + sl + "images"; +// +// logger("RETURNED : " + startDirectory); +// logger("WRITING... :"); +// +// String fileName = ""; +// PrintWriter out = response.getWriter(); +// +// if (!ServletFileUpload.isMultipartContent(request)) +// return; +// +// FileItemFactory factory = new DiskFileItemFactory(); +// ServletFileUpload upload = new ServletFileUpload(factory); +// +// List items = null; +// try { +// items = upload.parseRequest(request); +// } +// catch (FileUploadException e) { +// e.printStackTrace(); +// return; +// } +// File uploadedFile = null; +// for (Iterator i = items.iterator(); i.hasNext();) { +// FileItem item = (FileItem) i.next(); +// +// if (item.isFormField()) +// continue; +// fileName = item.getName(); +// if (fileName != null && fileName.compareTo("")!=0) { +// fileName = FilenameUtils.getName(fileName); +// +// uploadedFile = new File(startDirectory + File.separator + fileName); +// try { +// if(!uploadedFile.exists()){ +// File toCreate = new File(startDirectory); +// boolean success = toCreate.mkdirs(); +// if (success) +// Logger.debug("New file \"" + uploadedFile + "\" has been created "); +// } +// item.write(uploadedFile); +// } +// catch (Exception e) { e.printStackTrace(); } +// +// } +// } +// +// out.print(returnOKMessage); +// out.close(); + + } //end service + + /** + * + * @param httpServletRequest . + * @return . + */ + public String getUsername(HttpServletRequest httpServletRequest) { + + HttpSession session = httpServletRequest.getSession(); + String user = (String) session.getAttribute("username"); + if(session.getAttribute("username")== null) + { + user = "massi"; + logger("D4ScienceSession user NULL set to: " + user); + } + logger("D4ScienceSession user: " + user); + + ASLSession d4session = SessionManager.getInstance().getASLSession(session.getId(), user); + d4session.setAttribute("username", user); + return user; + } + + /** + * @param httpServletRequest . + * @return the shared session + */ + public String getVreName(HttpServletRequest httpServletRequest) { + HttpSession session = httpServletRequest.getSession(); + + ASLSession d4session = SessionManager.getInstance().getASLSession(session.getId(), getUsername(httpServletRequest)); + String scope = d4session.getScopeName(); + //need to remove the initial / of the scope + if (scope.charAt(0) == '/') + scope = scope.substring(1, scope.length()); + logger("ImagesUploadServlet SCOPE: " + scope); + //String scope = "gcube/devsec"; + return scope; + } +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ReportServiceImpl.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ReportServiceImpl.java new file mode 100644 index 0000000..f39eab1 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ReportServiceImpl.java @@ -0,0 +1,1751 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import net.sf.csv4j.CSVFileProcessor; +import net.sf.csv4j.CSVLineProcessor; +import net.sf.csv4j.ParseException; +import net.sf.csv4j.ProcessingException; + +import org.apache.commons.io.IOUtils; +import org.gcube.application.framework.accesslogger.library.impl.AccessLogger; +import org.gcube.application.framework.core.session.ASLSession; +import org.gcube.application.framework.core.session.SessionManager; +import org.gcube.applicationsupportlayer.social.ApplicationNotificationsManager; +import org.gcube.applicationsupportlayer.social.NotificationsManager; +import org.gcube.common.core.scope.GCUBEScope.MalformedScopeExpressionException; +import org.gcube.common.core.utils.logging.GCUBEClientLog; +import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper; +import org.gcube.portlets.admin.wfdocslibrary.client.WfDocsLibrary; +import org.gcube.portlets.admin.wfdocslibrary.server.db.MyDerbyStore; +import org.gcube.portlets.admin.wfdocslibrary.server.db.Store; +import org.gcube.portlets.d4sreporting.common.client.ComponentType; +import org.gcube.portlets.d4sreporting.common.server.ServiceUtil; +import org.gcube.portlets.d4sreporting.common.shared.SerializableComponent; +import org.gcube.portlets.d4sreporting.common.shared.SerializableModel; +import org.gcube.portlets.d4sreporting.common.shared.SerializableSection; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTable; +import org.gcube.portlets.d4sreporting.common.shared.SerializableTimeSeries; +import org.gcube.portlets.d4sreporting.common.shared.TableCell; +import org.gcube.portlets.docxgenerator.DocxGenerator; +import org.gcube.portlets.user.homelibrary.home.HomeLibrary; +import org.gcube.portlets.user.homelibrary.home.exceptions.HomeNotFoundException; +import org.gcube.portlets.user.homelibrary.home.exceptions.InternalErrorException; +import org.gcube.portlets.user.homelibrary.home.workspace.Workspace; +import org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceFolder; +import org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItem; +import org.gcube.portlets.user.homelibrary.home.workspace.WorkspaceItemType; +import org.gcube.portlets.user.homelibrary.home.workspace.exceptions.InsufficientPrivilegesException; +import org.gcube.portlets.user.homelibrary.home.workspace.exceptions.ItemAlreadyExistException; +import org.gcube.portlets.user.homelibrary.home.workspace.exceptions.ItemNotFoundException; +import org.gcube.portlets.user.homelibrary.home.workspace.exceptions.WorkspaceFolderNotFoundException; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.FolderItem; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.FolderItemType; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.items.ExternalImage; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.items.Report; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.items.ReportTemplate; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.items.gcube.ImageDocument; +import org.gcube.portlets.user.homelibrary.home.workspace.folder.items.ts.TimeSeries; +import org.gcube.portlets.user.reportgenerator.client.ReportConstants; +import org.gcube.portlets.user.reportgenerator.client.ReportService; +import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType; +import org.gcube.portlets.user.reportgenerator.server.servlet.loggers.CreateReportLogEntry; +import org.gcube.portlets.user.reportgenerator.server.servlet.loggers.GenerateReportLogEntry; +import org.gcube.portlets.user.reportgenerator.server.servlet.loggers.OpenReportLogEntry; +import org.gcube.portlets.user.reportgenerator.server.servlet.loggers.OpenWorkflowLogEntry; +import org.gcube.portlets.user.reportgenerator.server.servlet.loggers.SaveWorkflowLogEntry; +import org.gcube.portlets.user.reportgenerator.shared.SessionInfo; + +import com.google.gwt.user.server.rpc.RemoteServiceServlet; +import com.liferay.portal.service.LockLocalServiceUtil; +import com.liferay.portlet.documentlibrary.model.DLFileEntry; + + + +/** + * + * class implementing services + * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it + * @version Feb 2012 (3.3) + */ +@SuppressWarnings("serial") +public class ReportServiceImpl extends RemoteServiceServlet implements ReportService { + + public static GCUBEClientLog logger = new GCUBEClientLog(ReportServiceImpl.class); + /** + * EXPORT DIR + */ + private static final String EXPORTS_DIR = "EXPORTS"; + + /** + * + */ + public static final String USERNAME_ATTRIBUTE = "user"; + /** + * + */ + public static final String GIF = "image/gif"; + /** + * + */ + public static final String PNG = "image/png"; + /** + * + */ + public static final String JPEG = "image/jpeg"; + /** + * + */ + public static final String JPG = "image/jpg"; + /** + * + */ + public static final String TIFF = "image/tiff"; + /** + * + */ + public static final String BMP = "image/bmp"; + + /** + * + */ + public static final String CURRENT_REPORT_ID_ATTRIBUTE = "CURRENT_REPORT_ID_ATTRIBUTE"; + /** + * + */ + public static final String CURRENT_REPORT_INSTANCE = "myReport"; + /** + * + */ + public static final String PREVIOUS_REPORT_INSTANCE = "myPreviousReport"; + + + private String currentHost = ""; + + /** + * the WF DB Store + */ + private Store store; + + + //set to true if wanna test workflow menu mode + boolean testWorkflow = false; + + /** + * Called then servlet is intialized + */ + public void init() { + logger.info("Initializing Servlet ReportServiceImpl..."); + store = new MyDerbyStore(); + } + + /** + * the current ASLSession + * @return . + */ + private ASLSession getASLSession() { + String sessionID = this.getThreadLocalRequest().getSession().getId(); + String user = (String) this.getThreadLocalRequest().getSession().getAttribute(ScopeHelper.USERNAME_ATTRIBUTE); + + + logger.error("Report PORTLET SessionID= " + sessionID); + + if (user == null) { + user = "massimiliano.assante"; + this.getThreadLocalRequest().getSession().setAttribute(ScopeHelper.USERNAME_ATTRIBUTE, user); + SessionManager.getInstance().getASLSession(sessionID, user).setScope("/gcube/devsec"); + } + return SessionManager.getInstance().getASLSession(sessionID, user); + } + /** + * Retrieve the user saved template names + * + * @return a String[] containing the template names + */ + public String[] getUserTemplateNames() { + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + Vector tmp = new Vector(); + String userDir = myUtil.getTemplateFolder(getVreName(), getUsername()); + + logger.debug("userDir: " + userDir); + + File f = new File(userDir); + //checking if dir exists + if (! f.exists()) { + try { + f.mkdirs(); + return new String[0]; + } catch (SecurityException ex) { + return new String[0]; + } + } + else { + File []f2 = f.listFiles(); + for(int i = 0; i < f2.length; i++){ + if(f2[i].isDirectory()) { + tmp.add(f2[i].getName()); + } + } + return tmp.toArray(new String[0]); + } + } + + + /** + * @return a SerializableModel instance of the imported fimes xml + */ + public SerializableModel readImportedModel(String tempPath) { + SerializableModel toConvert = null; + + FileInputStream fis = null; + ObjectInputStream in = null; + + try { + + fis = new FileInputStream(tempPath); + in = new ObjectInputStream(fis); + toConvert = (SerializableModel) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + logger.debug("Converting Imported Fimes to Serializable object, num sectionss: " + toConvert.getSections().size()); + return (toConvert); + } + + /** + * @return a SerializableModel instance of the templatename passed as parameter + * @param templateName : the template to read from disk + * @param templateObjectID the id in the basket + * @param isTemplate says if you're opening a template or a report + * @param isImporting says if your importing or youre loading a template in the UI + * + */ + public SerializableModel readModel(String templateName, String templateObjectID, boolean isTemplate, boolean isImporting) { + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + logger.debug("Reading " + templateName); + if (! ReportConstants.isDeployed) { + + SerializableModel toConvert = null; + + FileInputStream fis = null; + ObjectInputStream in = null; + try { + String path = myUtil.getTemplateFolder(getVreName(), getUsername()); + fis = new FileInputStream(path + "CURRENT_OPEN/CURRENT_OPEN.d4st"); + in = new ObjectInputStream(fis); + toConvert = (SerializableModel) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + logger.debug("Converting fileToRead to Serializable object"); + return toConvert; + + } else { + + Workspace root = null; + + try { + root = getWorkspaceArea(); + } catch (WorkspaceFolderNotFoundException e) { + e.printStackTrace(); + } catch (InternalErrorException e) { + e.printStackTrace(); + } catch (HomeNotFoundException e) { + e.printStackTrace(); + } + + + + WorkspaceItem item = null; + try { + item = root.getItem(templateObjectID); + if (! isImporting) + storeReportItemIDInSession(templateObjectID); + } catch (ItemNotFoundException e) { + e.printStackTrace(); + } + + logger.debug("getItem: " + templateObjectID); + String zipToExtract = ""; + + if (item.getType() == WorkspaceItemType.FOLDER_ITEM) { + + logger.debug("\nItem is a BASKET_ITEM"); + + FolderItem bi = (FolderItem) item; + boolean fromBasket = false; + + if (isTemplate) { + if (bi.getFolderItemType() == FolderItemType.REPORT_TEMPLATE) { + ReportTemplate zippedTemplate = (ReportTemplate) bi; + String zipFilename = ""; + if (! isTemplate) {//then is a report + zipFilename = templateName + "-report.zip"; //gCube report + logger.debug("********************** Reading report -----------------"); + } + else + zipFilename = templateName + ".zip"; //gCube template + + String zipPath = myUtil.getTemplatePath(templateName, getVreName(), getUsername()); + fromBasket = getTemplateFromBasket(zippedTemplate, zipPath, zipFilename); + zipToExtract = zipPath + zipFilename; + } + } + + if (bi.getFolderItemType() == FolderItemType.REPORT) { + + logger.debug("Item is a REPORT"); + Report zippedTemplate = (Report) bi; + + String zipFilename = ""; + if (! isTemplate) {//then is a report + zipFilename = templateName + "-report.zip"; //d4science template + logger.debug("********************** Reading report -----------------"); + } + else + zipFilename = templateName + ".zip"; //d4science template + + File toDelete = new File(zipFilename); + toDelete.delete(); + + String zipPath = myUtil.getTemplatePath(templateName, getVreName(), getUsername()); + fromBasket = getReportFromBasket(zippedTemplate, zipPath, zipFilename); + zipToExtract = zipPath + zipFilename; + } + + if (bi.getFolderItemType() == FolderItemType.REPORT || bi.getFolderItemType() == FolderItemType.REPORT_TEMPLATE) { + + if (fromBasket) { + File toExtract = new File(zipToExtract); + File outputDir = new File( myUtil.getTemplatePath(templateName, getVreName(), getUsername()) ); + ZipUtil.unzipArchive(toExtract, outputDir); + + String templatePath = myUtil.getTemplatePath(templateName, getVreName(), getUsername()); + + String modelFilename = ""; + try { + modelFilename = seekModel(templatePath, templateName); + } catch (FileNotFoundException e) { e.printStackTrace(); } + + String fileToRead = templatePath + modelFilename + ".d4st" ; + + //TODO: check + // String fileToCheck = templatePath + "gCube-label.d4s" ; //lo deve anche cancellare + // File file2Check = new File(fileToCheck); + // Logger.debug("Checking: " + fileToCheck); + // if (! file2Check.exists()) { + // Logger.debug("Not Found: " + fileToCheck); + // return new SerializableModel(950); + // } else { + // file2Check.delete(); + // } + + + logger.debug("Loading fileToRead from Disk"); + + SerializableModel toReturn = null; + SerializableModel toConvert = null; + + FileInputStream fis = null; + ObjectInputStream in = null; + try { + fis = new FileInputStream(fileToRead); + in = new ObjectInputStream(fis); + toConvert = (SerializableModel) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + logger.debug("Converting fileToRead to Serializable object"); + toReturn = (toConvert); + + // changes the template name model + toReturn.setTemplateName(templateName); + + File toDelete1 = new File( myUtil.getTemplatePath(templateName, getVreName(), getUsername())); + boolean deleted1 = toDelete1.delete(); + + + File toDelete2 = new File(zipToExtract); + boolean deleted2 = toDelete2.delete(); + + logger.debug("dirToDelete: " + toDelete1 + " result: " + deleted1 + " \n\n\n"); + + logger.debug("dirToDelete: " + toDelete2 + " result: " + deleted2 + " \n\n\n"); + + //**** IMPORTANT **** + if (! isImporting) { + storeTemplateInSession(toReturn); + logger.debug("storeTemplateInSession DONE"); + } + + AccessLogger log = AccessLogger.getAccessLogger(); + OpenReportLogEntry logEntry = new OpenReportLogEntry(toReturn.getTemplateName(), templateObjectID); + log.logEntry(getASLSession().getUsername(), getASLSession().getScopeName(), logEntry); + + return toReturn; + } + } + logger.error("FAILED TO READ RETURING EMPTY Serializable Template"); + return new SerializableModel(); + } + logger.error("FAILED TO READ FROM BASKET RETURING EMPTY Serializable Template"); + return new SerializableModel(); + } + } + + + + + /** + * handles the case that the user has changed the template name in the basket + * @param templatePath + * @param templateName + * @return + * @throws FileNotFoundException + */ + private String seekModel(String templatePath, String templateName) throws FileNotFoundException { + logger.debug("seekModel: tPath=" + templatePath); + String fileToSeek = templatePath + templateName + ".d4st"; + + File toSeek = new File(fileToSeek); + if (toSeek.exists()) { + logger.debug("seekModel: modelName is the SAME returning"); + return templateName; + } + else { + logger.debug("seekModel: modelName DIFFERENT upgrading"); + File dirToLookIn = new File(templatePath); + File[] innerFiles = dirToLookIn.listFiles(); + for (int i = 0; i < innerFiles.length; i++) + if (innerFiles[i].getName().endsWith(".d4st")) { + String toReturn = innerFiles[i].getName(); + toReturn = toReturn.substring(0, toReturn.length()-5); + logger.debug("seekModel: returning.. =" + toReturn); + return toReturn; + } + } + throw new FileNotFoundException(); + } + + + /** + * get the template instance from the Basket + * @param repTmp + * @return + */ + private boolean getTemplateFromBasket(ReportTemplate repTmp, String pathToFile, String filename) { + try { + File dir = new File(pathToFile); + logger.debug("DIR: " + pathToFile); + if (! dir.exists() ) + dir.mkdirs(); + + File f = new File(pathToFile+filename); + InputStream inputStream = null; + try { + inputStream = repTmp.getData(); + } catch (InternalErrorException e) { + e.printStackTrace(); + return false; + } + + OutputStream out = new FileOutputStream(f); + + byte buf[] = new byte[1024]; + int len; + while((len = inputStream.read(buf))>0) + out.write(buf,0,len); + out.close(); + inputStream.close(); + logger.info("Successfully got ReportTemplate from Basket: " + pathToFile); + return true; + } + catch (IOException e){ + e.printStackTrace(); + return false; + } + } + + + /** + * get the report instance from the Basket + * @param repTmp . + * @param pathToFile the directory where to save the file + * @param filename the filename to give to the newly created file + * @return + */ + private boolean getReportFromBasket(Report repTmp, String pathToFile, String filename) { + try { + File dir = new File(pathToFile); + logger.debug("DIR: " + pathToFile); + if (! dir.exists() ) + dir.mkdirs(); + + File f = new File(pathToFile+filename); + InputStream inputStream = null; + try { + inputStream = repTmp.getData(); + } catch (InternalErrorException e) { + e.printStackTrace(); + return false; + } + + OutputStream out = new FileOutputStream(f); + + byte buf[] = new byte[1024]; + int len; + while((len = inputStream.read(buf))>0) + out.write(buf,0,len); + out.close(); + inputStream.close(); + logger.info("Successfully got ReportTemplate from Basket: " + pathToFile); + return true; + } + catch (IOException e){ + e.printStackTrace(); + return false; + } + } + /** + * + */ + public String generateTempDocx(SerializableModel model) { + + logger.info("Generating docx file"); + DocxGenerator docxGenerator = new DocxGenerator(model); + logger.debug("DocxGenerator instanciated:"); + boolean result = docxGenerator.exportInDocx(model); + logger.trace("RESULT:" + result); + if (! result) + return "ERROR"; + + File docx = null; + try { + docx = docxGenerator.writeOutputTempFile(model.getTemplateName()); + } catch (Exception e) { + e.printStackTrace(); + return "ERROR"; + } + logger.info("Generated docx file: " + docx.getAbsolutePath()); + return docx.getAbsolutePath(); + } + /** + * @param model the model + * @param type the type + * @return true if the generatePDF is successful + */ + public boolean generateManifestation(SerializableModel model, ExportManifestationType type) { + + //in case there are dynamic images need to get the from the HL + importDynamicImagesFromHL(model); + + + //in case there are dynamic TS need to get the CSV from HL and add it to the component + for (SerializableSection section : model.getSections()) { + for (SerializableComponent tc : section.getComponents()) { + if (tc.getType() == ComponentType.TIME_SERIES) { + SerializableTimeSeries sts = (SerializableTimeSeries) tc.getPossibleContent(); + File toPass = getTimeSeriesFromWorkspace(sts); + if (toPass == null) + tc.setPossibleContent(null); + else { + sts.setCsvFile(toPass.getAbsolutePath()); + tc.setPossibleContent(sts); + } + } + } + } + + boolean result = false; + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + logger.info("Generating docx file"); + logger.debug("Model Converted"); + DocxGenerator docxGenerator = new DocxGenerator(model); + logger.info("DocxGenerator instanciated:"); + result = docxGenerator.exportInDocx(model); + logger.trace("RESULT:" + result); + //remove the extension + String exportName = model.getTemplateName(); + if (exportName.endsWith(".d4sT") || exportName.endsWith(".d4sR") ) + exportName = model.getTemplateName().substring(0, model.getTemplateName().length() - 5); + + + if (result) { + switch (type) { + case DOCX: + try { + File docx = docxGenerator.writeOutputTempFile(exportName); + logger.debug("Generated docx file: " + docx.getAbsolutePath()); + + + File toMoveTo = new File(myUtil.getTemplateFolder(getVreName(), getUsername()) + EXPORTS_DIR + File.separator + exportName + ".docx"); + String folder = (myUtil.getTemplateFolder(getVreName(), getUsername()) + EXPORTS_DIR + File.separator); + myUtil.copyFile(docx, toMoveTo, folder); + logger.trace("1 File Copied to " + toMoveTo.getAbsolutePath()); + + String name = exportName+".docx"; + String desc = name; + String mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + saveInWorkSpace(name, desc, mimeType, toMoveTo, type); + + } catch (Exception e) { + e.printStackTrace(); + } + break; + case HTML: + try { + File html = docxGenerator.createHTML(); + logger.info("Generated HTML file: " + html.getAbsolutePath()); + + File toMoveTo = new File(myUtil.getTemplateFolder(getVreName(), getUsername()) + EXPORTS_DIR + File.separator + exportName + ".html"); + String folder = (myUtil.getTemplateFolder(getVreName(), getUsername()) + EXPORTS_DIR + File.separator); + myUtil.copyFile(html, toMoveTo, folder); + logger.trace("1 File Copied to " + toMoveTo.getAbsolutePath()); + + String name = exportName+".html"; + String desc = name; + String mimeType = "text/html"; + saveInWorkSpace(name, desc, mimeType, toMoveTo, type); + + } catch (Exception e) { + e.printStackTrace(); + } + break; + default: + break; + } + } + + + return result; + } + + + /** + * save the manifestation in default folder, overwrites if the file name exists already + * + * @param name the name in the Workspace + * @param desc the desc + * @param mimeType its mimetype + * @param payLoad a File instance + */ + private boolean saveInWorkSpace(String name, String desc, String mimeType, File payLoad, ExportManifestationType type ) { + try { + String defaultBasketID = getDefaultBasket(); + + // Read the pdf input stream + InputStream inputStream = new BufferedInputStream(new FileInputStream(payLoad)); + Workspace wp = getWorkspaceArea(); + WorkspaceFolder toSaveIn = wp.getRoot(); + + if (toSaveIn.exists(name)) { + logger.warn("Item exists already, deleting and creating new one"); + toSaveIn.removeChild(toSaveIn.find(name)); + } + + if (type == ExportManifestationType.PDF) { + wp.createExternalPDFFile(name, name, mimeType, inputStream, defaultBasketID); + } else + wp.createExternalFile(name, name, mimeType, inputStream, defaultBasketID); + + + AccessLogger log = AccessLogger.getAccessLogger(); + GenerateReportLogEntry logEntry = new GenerateReportLogEntry(name, mimeType, type.toString()); + log.logEntry(getASLSession().getUsername(), getASLSession().getScopeName(), logEntry); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + + + /** + * + * @return the shared session + */ + public String getUsername() { + if (! ReportConstants.isDeployed) { + return "massimiliano.assante"; + } else { + HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); + HttpSession session = httpServletRequest.getSession(); + String user = (String) session.getAttribute(ScopeHelper.USERNAME_ATTRIBUTE); + if(session.getAttribute(ScopeHelper.USERNAME_ATTRIBUTE)== null) + { + user = "massimiliano.assante"; + logger.warn("D4ScienceSession user NULL set to: " + user); + } + logger.warn("ASLSession user: " + user); + + ASLSession d4session = SessionManager.getInstance().getASLSession(session.getId(), user); + d4session.setAttribute(ScopeHelper.USERNAME_ATTRIBUTE, user); + return user; + } + } + + /** + * + * @return the current scope + */ + public String getVreName() { + if (! ReportConstants.isDeployed) { + return "d4science.research-infrastructures.eu/FARM/FCPPS"; + } else { + HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); + HttpSession session = httpServletRequest.getSession(); + + ASLSession d4session = SessionManager.getInstance().getASLSession(session.getId(), getUsername()); + String scope = d4session.getScopeName(); + + if(scope == null) { + scope = "gcube/devsec"; + logger.warn("ASL Session scope NULL set to: " + scope); + } + + //need to remove the initial / of the scope + if (scope.charAt(0) == '/') + scope = scope.substring(1, scope.length()); + logger.info("SCOPE: " + scope); + return scope; + } + + } + + + + /** + * + * @return an instance of the user WorkspaceArea + * @throws HomeNotFoundException + * @throws InternalErrorException + * @throws WorkspaceFolderNotFoundException + * @throws WorkspaceNotFoundException + * @throws InternalErrorException + * @throws HomeNotFoundException + */ + protected Workspace getWorkspaceArea() throws WorkspaceFolderNotFoundException, InternalErrorException, HomeNotFoundException { + return HomeLibrary.getUserWorkspace(getASLSession()); + } + + + /** + * reads from the file system and returns the user workspace as TreeNode object + * + * @return the Default basket if if there is no basket in session, else the basket in session id + */ + public String getDefaultBasket() { + logger.info("getDefaultBasket()"); + + try { + Workspace workspaceArea = getWorkspaceArea(); + WorkspaceFolder basket = workspaceArea.getRoot(); + return basket.getId(); + } catch (MalformedScopeExpressionException e) { e.printStackTrace(); + } catch (InternalErrorException e) {e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } catch (WorkspaceFolderNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return "Coud not open default basket"; + } + + /** + * + * @return the model previously stored in the session + */ + public SerializableModel readTemplateFromSession() { + ASLSession d4Session = getASLSession(); + + String templateid = (String) d4Session.getAttribute("idreport"); + + Object workflowid = getASLSession().getAttribute(WfDocsLibrary.LAST_WORKFLOW_ID); + logger.debug(" (templateid != null && workflowid != null) = " + (templateid != null) + " - " + (workflowid != null)); + if (workflowid != null) { + getASLSession().setAttribute(WfDocsLibrary.LAST_WORKFLOW_ID, null); + return null; + } + + String templateName = ""; + logger.debug("TEMPLATE ID==NULL " + (templateid == null)); + if (templateid != null) { + if (! templateid.equals("")) { + logger.debug("READING SESSION VARIABLE FOR REPORT ID... " + templateid); + //reset the value + d4Session.setAttribute("idreport", ""); + Workspace root = null; + WorkspaceItem item = null; + try { + root = getWorkspaceArea(); + + item = root.getItem(templateid); + logger.info("READ REPORT FROM WP... " + item.getName()); + templateName = item.getName(); + } catch (WorkspaceFolderNotFoundException e) {e.printStackTrace(); + } catch (InternalErrorException e) { e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } catch (ItemNotFoundException e) { e.printStackTrace();} + + SerializableModel toReturn = readModel(templateName, templateid, false, false); + return toReturn; + } + if (d4Session.getAttribute(CURRENT_REPORT_INSTANCE) != null) + return (SerializableModel) d4Session.getAttribute(CURRENT_REPORT_INSTANCE) ; + return null; + } + else { + if (d4Session.getAttribute(CURRENT_REPORT_INSTANCE) != null) { + logger.debug("getAttribute(\"CURRENT_REPORT_INSTANCE\")..."); + SerializableModel model = (SerializableModel) d4Session.getAttribute(CURRENT_REPORT_INSTANCE) ; + logger.debug(model.getTemplateName()); + + return model; + } + } + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + String dirToClean = myUtil.getTemplateFolder(getVreName(), getUsername()); + logger.info("RETURNING NULL, going to clean user template area: " + dirToClean); + if (ReportConstants.isDeployed) + delTemplateDir(new File(dirToClean)); + return null; + } + + + /** + * recurdively delete the templates folder of the dir dir + * @param dir the dir to delete + */ + public void delTemplateDir(File dir) { + try { + File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) + delTemplateDir(files[i]); + files[i].delete(); + } + } catch (Exception e) { + System.out.println("WARNING: Could not cleaning temp dir: reason unknown"); + } + } + + + /** + * @param model to store in the session + */ + public void storeTemplateInSession(SerializableModel model) { + ASLSession d4Session = getASLSession(); + d4Session.setAttribute(CURRENT_REPORT_INSTANCE, model); + // Vector sections = model.getSections(); + // for (SerialazableSection section : sections) { + // for (SerializableComponent component : section.getComponents()) { + // if (component.getType() == ComponentType.DYNA_IMAGE) { + // Logger.debug("\n\n****FOUND DYNA IMAGE ID In Basket: " + component.getIdInBasket()); + // } + // } + // } + } + + + private void importDynamicImagesFromHL(SerializableModel model) { + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + logger.debug("model == NULL " + (model == null)); + Vector sections = model.getSections(); + for (SerializableSection section : sections) { + logger.debug("\n\n****section.getComponents() == NULL " + (section.getComponents() == null)); + for (SerializableComponent component : section.getComponents()) { + if (component.getType() == ComponentType.DYNA_IMAGE) { + logger.debug("Found DP: " + component.getPossibleContent()); + + logger.debug("ID In Basket null?: " + (component.getIdInBasket() == null)); + + if (component.getIdInBasket() != null) { + + String imageID = component.getIdInBasket(); + String imageNameFile = getRandom(12); + + String imageTargetDIR = myUtil.getTemplatePath(model.getTemplateName(), getVreName(), getUsername()) + "images" + File.separator; + imageNameFile = copyImageFromBasket(imageID, imageTargetDIR, imageNameFile); + + component.setPossibleContent(getImageURL(imageNameFile, model.getTemplateName())); + logger.trace("NEW setPossibleContent: " + component.getPossibleContent()); + } + } + } + } + } + + /** + * + * @param imageName + * @param templateName + * @return + */ + private String getImageURL(String imageName, String templateName) { + String toReturn = currentHost + "usersArea/" + getVreName() + "/templates/" + getUsername() + "/CURRENT_OPEN/images/" + imageName; + logger.info("getImageURL" + toReturn); + return toReturn; + + } + + /** + * + * @param imageIDinBasket . + * @param pathToFile the directory where to save the file + * @param filename the filename to give to the newly created file + * @return the file imagename with its extension + */ + private String copyImageFromBasket(String imageIDinBasket, String pathToFile, String filename) { + + Workspace root = null; + try { + root = getWorkspaceArea(); + } catch (WorkspaceFolderNotFoundException e) {e.printStackTrace(); + } catch (InternalErrorException e) { e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } + + WorkspaceItem item = null; + try { + item = root.getItem(imageIDinBasket); + } catch (ItemNotFoundException e) { + e.printStackTrace(); + } + + logger.debug("pathToFile: " + pathToFile); + File f = null; + String toReturn =""; + if (item.getType() == WorkspaceItemType.FOLDER_ITEM) { + logger.debug("\nItem is a BASKET_ITEM"); + FolderItem bi = (FolderItem) item; + try { + File dir = new File(pathToFile); + logger.debug("DIR: " + pathToFile); + if (! dir.exists() ) + dir.mkdirs(); + + + + InputStream data = null; + + if (bi.getFolderItemType()==FolderItemType.EXTERNAL_IMAGE){ + logger.debug("EXTERNAL_IMAGE -|- " + item.getType()); + ExternalImage image = (ExternalImage)item; + data = image.getData(); + } + + if (bi.getFolderItemType()==FolderItemType.IMAGE_DOCUMENT){ + ImageDocument image = (ImageDocument)item; + if (image.getMimeType().equals("image/tiff")) + data = image.getThumbnail(); + else + data = image.getData(); + } + toReturn = filename + "." + getImageExtension(bi); + f = new File(pathToFile+toReturn); + OutputStream out = new FileOutputStream(f); + + byte buf[] = new byte[1024]; + int len; + while((len = data.read(buf))>0) + out.write(buf,0,len); + out.close(); + data.close(); + } + catch (IOException e){ + e.printStackTrace(); + } catch (InternalErrorException e) { + e.printStackTrace(); + } + } + logger.info("RETURNING: " + f.getAbsolutePath()); + return toReturn; + } + + + /** + * return a string for the file extension given a mimetype + * + * @param bi the basketItem + * @return a string for the file extension given a mimetype + */ + public static String getImageExtension(FolderItem bi) { + + String mimetype = ""; + if (bi.getFolderItemType()==FolderItemType.EXTERNAL_IMAGE){ + ExternalImage image = (ExternalImage) bi; + mimetype = image.getMimeType(); + } + + if (bi.getFolderItemType()==FolderItemType.IMAGE_DOCUMENT){ + ImageDocument image = (ImageDocument) bi; + mimetype = image.getMimeType(); + } + + if (mimetype.equals(GIF)) + return "gif"; + else if (mimetype.equals(PNG)) + return "png"; + else if (mimetype.equals(JPG)) + return "jpg"; + else if (mimetype.equals(JPEG)) + return "jpg"; + else if (mimetype.equals(TIFF)) + return "png"; + else if (mimetype.equals(BMP)) + return "bmp"; + else + return "jpg"; + } + + + + /** + * generate a random uid + * @param length + * @return + */ + private String getRandom(int length) { + UUID uuid = UUID.randomUUID(); + String myRandom = uuid.toString(); + return myRandom.substring(length); + } + + /** + * Copies a image from fromTemplate/images/imageNameFile to toTemplate/images/imageNameFile + * @param fromTemplate the origin template + * @param toTemplate the target template + * @param imageNameFile . + * @return true if the copy went fine + */ + public boolean copyImage(String fromTemplate, String toTemplate, String imageNameFile) { + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + String imageFrom = myUtil.getTemplatePath(fromTemplate, getVreName(), getUsername()) + "images" + File.separator + imageNameFile; + String imageTarget = myUtil.getTemplatePath(toTemplate, getVreName(), getUsername()) + "images" + File.separator + imageNameFile; + + String imageNewFolder = myUtil.getTemplatePath(toTemplate, getVreName(), getUsername()) + "images" + File.separator; + + logger.debug("Copying:\n" + imageFrom + "\nto: " + imageTarget); + + File from = new File(imageFrom); + File to = new File(imageTarget); + + try { + myUtil.copyFile(from, to, imageNewFolder); + } catch (Exception e) { + logger.error("Error While Copying: " + e.getMessage()); + return false; + } + logger.debug("Copying Success\n"); + return true; + } + + + + /** + * @param reportItemid the report itemd id in basket to store in the session + */ + public void storeReportItemIDInSession(String reportItemid) { + ASLSession d4Session = getASLSession(); + d4Session.setAttribute(CURRENT_REPORT_ID_ATTRIBUTE, reportItemid); + logger.debug("WROTE REPORT ID IN SESSION: " + reportItemid); + } + + /** + * @return the report item id in basket, or "" if doesn't exist + */ + public String getReportItemIDFromSession() { + ASLSession d4Session = getASLSession(); + if (d4Session.getAttribute(CURRENT_REPORT_ID_ATTRIBUTE) == null) + return ""; + else + return d4Session.getAttribute(CURRENT_REPORT_ID_ATTRIBUTE).toString(); + } + /** + * used to save the report in the same basket * + */ + public void saveReport() { + Workspace root = null; + try { + root = getWorkspaceArea(); + } catch (WorkspaceFolderNotFoundException e) {e.printStackTrace(); + } catch (InternalErrorException e) { e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } + + WorkspaceItem item = null; + String folderid = ""; + String itemName = ""; + try { + if (getReportItemIDFromSession().equals("")) { + folderid = getDefaultBasket(); + + } + + else { + logger.debug("getReportItemIDFromSession RETURNS -> " + getReportItemIDFromSession() + ""); + + item = root.getItem(getReportItemIDFromSession()); + folderid = item.getParent().getId(); + itemName = item.getName(); + } + } catch (ItemNotFoundException e) { + logger.error("ITEM NOT FOUND -> " + getReportItemIDFromSession()); + + } catch (InternalErrorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + logger.debug("folderid -> " + folderid); + + saveReport(folderid, itemName); + } + + + /** + * @param basketidToSaveIn . + * + */ + public void saveReport(String folderid, String newname) { + + SerializableModel model = readTemplateFromSession(); + //raplacing " " with _ + logger.info("Serializing Model basketidToSaveIn: " + folderid ); + + logger.info("Trying to convert dynamic images ... "); + importDynamicImagesFromHL(model); + + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + boolean result = myUtil.writeModel(model, "CURRENT_OPEN", getVreName(), getUsername()); + + + + if (!result) { + logger.debug("Could not save report, serializing failed"); + } + else { + String templatePath = myUtil.getTemplateFolder(getVreName(), getUsername()) + "CURRENT_OPEN"; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + logger.debug("Trying to zip folder: " + templatePath); + + String folderToZip = templatePath; + String outZip = templatePath+"-report.zip"; + + try { + ZipUtil.zipDir(outZip, folderToZip); + } catch (IOException e) { + logger.error("Could not zip template, serializing failed"); + e.printStackTrace(); + } + logger.info("Folder zipped, result: "+ outZip); + + InputStream isZip = null; + + WorkspaceFolder toSaveIn = null; + try { + isZip = new BufferedInputStream(new FileInputStream(outZip)); + + toSaveIn = getBasketInstance(folderid); + String templateName = newname; + + if (templateName.endsWith("d4sR") ) { + if (toSaveIn.exists(templateName)) { + logger.warn("Item exists already, deleting and creating new one"); + toSaveIn.removeChild(toSaveIn.find(templateName)); + } + } + + if (toSaveIn.exists(templateName + ".d4sR")) { + logger.warn("Item exists already, deleting and creating new one"); + toSaveIn.removeChild(toSaveIn.find(templateName + ".d4sR")); + } + + //remove the template extension + String templateToInsert = templateName.replace(".d4sT", ""); + if (! templateToInsert.endsWith(".d4sR")) + templateToInsert+=".d4sR"; + + + /** + * Create a Report into this basket. + * @param name the report name. + * @param description the report description. + * @param created the report creation time. + * @param lastEdit the last edit time. + * @param author the report author. + * @param lastEditBy the last report editor. + * @param templateName the source template name. + * @param numberOfSections the number of sections. + * @param status the report status. + * @param reportData the report data. + * @return the report. + * @throws InsufficientPrivilegesException if the user don't have sufficient privileges to perform this operation. + * @throws InternalErrorException if an internal error occurs. + * @throws ItemAlreadyExistException if an item with the specified name already exists. + */ + + Calendar dateCreated = Calendar.getInstance(); + dateCreated.setTime(model.getDateCreated()); + + Calendar lastEdit = Calendar.getInstance(); + lastEdit.setTime(model.getLastEdit()); + + Report rep = toSaveIn.createReportItem(templateToInsert, templateToInsert, dateCreated, lastEdit, + model.getAuthor(), model.getLastEditBy(), templateToInsert, model.getSections().size(), "no-status", isZip); + + + //Report rep = toSaveIn.createReportItem(templateToInsert, templateToInsert, isZip); + storeReportItemIDInSession(rep.getId()); + + AccessLogger log = AccessLogger.getAccessLogger(); + CreateReportLogEntry logEntry = new CreateReportLogEntry(model.getTemplateName(), rep.getId()); + log.logEntry(getASLSession().getUsername(), getASLSession().getScopeName(), logEntry); + + } catch (InsufficientPrivilegesException e) { + e.printStackTrace(); + } catch (InternalErrorException e) { + e.printStackTrace(); + } catch (ItemAlreadyExistException e) { + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (ItemNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } + + private boolean removeIfExist(String name2Check, WorkspaceFolder basket) throws InternalErrorException, InsufficientPrivilegesException { + List items = basket.getChildren(); + for (WorkspaceItem item : items) + if (item.getName().equals(name2Check)) { + item.remove(); + logger.info("ITEM REMOVED: "+ name2Check); + return true; + } + return false; + } + + /** + * Return an instance of + * @param basketId + * @return + * @throws ItemNotFoundException + */ + private WorkspaceFolder getBasketInstance(String basketId) throws ItemNotFoundException { + Workspace root = null; + try { + root = getWorkspaceArea(); + } catch (WorkspaceFolderNotFoundException e) {e.printStackTrace(); + } catch (InternalErrorException e) { e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } + + WorkspaceItem item = null; + try { + item = root.getItem(basketId); + } catch (ItemNotFoundException e) { + logger.info("BASKET : " + basketId + " NOT FOUND RETURNING DEFAULT ONE"); + return(WorkspaceFolder)root.getItem(getDefaultBasket()); + + + } + logger.debug("Item Type: "+item.getType()); + if (item.getType() != WorkspaceItemType.FOLDER) { + logger.error("The item id does not belong to a basket id:" + basketId); + return null; + } + return (WorkspaceFolder) item; + } + + + /** + * return a sample of the given TS to the client + * @param sTS . + * @return . + */ + public SerializableTable getSampleTimeSeries(SerializableTimeSeries sTS) { + + File csvTS = getTimeSeriesFromWorkspace(sTS); + SerializableTable toReturn = null; + try { + toReturn = parseCSV(csvTS, sTS); + } catch (ParseException e) { e.printStackTrace(); + } catch (IOException e) { e.printStackTrace(); + } catch (ProcessingException e) { e.printStackTrace(); + } + + return toReturn; + } + + /** + * retrieve the given TS csv representation and writes it into /tmp returning the File + * @param sTS serializable TS + * @return a File csv + */ + private File getTimeSeriesFromWorkspace(SerializableTimeSeries sTS) { + try { + String timeSeriesBasketID = sTS.getTsMetadata().getId(); + + Workspace root = null; + try { + root = getWorkspaceArea(); + } catch (WorkspaceFolderNotFoundException e) {e.printStackTrace(); + } catch (InternalErrorException e) { e.printStackTrace(); + } catch (HomeNotFoundException e) { e.printStackTrace(); + } + WorkspaceItem item = null; + try { + item = root.getItem(timeSeriesBasketID); + } catch (ItemNotFoundException e) { + e.printStackTrace(); + } + logger.debug("Got Item TS From HL, Item Type: "+item.getType()); + + if (item.getType() != WorkspaceItemType.FOLDER_ITEM) { + logger.debug("The item id does not belong to a timeseries, id:" + timeSeriesBasketID); + return null; + } + FolderItem bItem = (FolderItem) item; + if (bItem.getFolderItemType() != FolderItemType.TIME_SERIES) { + logger.debug("The basket item does not belong to a timeseries, id:" + timeSeriesBasketID); + return null; + } + + TimeSeries ts = (TimeSeries) bItem; + return getTSFromBasket(ts); + } + catch (NullPointerException e) { + logger.error("No TS was dragged in the Area returning NULL"); + return null; + } + } + + /** + * + * @param toParse the csv to parse + * @throws ProcessingException . + * @throws IOException . + * @throws ParseException . + */ + private SerializableTable parseCSV(File toParse, final SerializableTimeSeries sTS) throws ParseException , IOException, ProcessingException { + + final SerializableTable toReturn; + final boolean isFiltered; + final int fromLine; + final int toLine; + + //if there is no filter + if ( sTS.getFilter() == null) { + toReturn = new SerializableTable(sTS.getTsMetadata().getHeaderLabels().size()); + isFiltered = false; + fromLine = 1; + toLine = 10; + } + else { + int headers = sTS.getFilter().getColsNumberToShow().size(); + toReturn = new SerializableTable(headers); + isFiltered = true; + fromLine = sTS.getFilter().getFrom(); + toLine = fromLine + 10; + } + + + final CSVFileProcessor fp = new CSVFileProcessor(); + fp.processFile(toParse.getAbsolutePath() , new CSVLineProcessor() { + boolean keepGoing = true; + + public void processHeaderLine( final int linenumber, final List fieldNames ) { + ArrayList toInsert = new ArrayList(); + for (String field : fieldNames) { + toInsert.add(new TableCell(field)); + } + if (! isFiltered) + toReturn.addRow((ArrayList) toInsert); + else { + ArrayList filteredHeaders = new ArrayList(); + for (Integer colNo : sTS.getFilter().getColsNumberToShow()) { + String toAdd = sTS.getTsMetadata().getHeaderLabels().get(colNo); + filteredHeaders.add(toAdd); + toInsert = new ArrayList(); + for (String field : filteredHeaders) { + toInsert.add(new TableCell(field)); + } + } + toReturn.addRow(toInsert); + } + } + + + public void processDataLine( final int linenumber, final List fieldValues ) { + if (linenumber > toLine) + keepGoing = false; + if (linenumber >= fromLine && linenumber <= toLine) { + ArrayList toInsert = new ArrayList(); + for (String field : fieldValues) { + toInsert.add(new TableCell(field)); + } + if (! isFiltered) + toReturn.addRow(toInsert); + else { + ArrayList filteredFields = new ArrayList(); + for (Integer colNo : sTS.getFilter().getColsNumberToShow()) { + String toAdd = fieldValues.get(colNo); + filteredFields.add(toAdd); + toInsert = new ArrayList(); + for (String field : filteredFields) { + toInsert.add(new TableCell(field)); + } + } + toReturn.addRow(toInsert); + } + } + } + public boolean continueProcessing() { + return keepGoing; + } + } ); + return toReturn; + } + + + /** + * get the TS from the Basket + * @param ts + * @return a csv file + */ + private File getTSFromBasket(TimeSeries ts) { + try { + File temp = File.createTempFile(ts.getName(), ".csv"); + + InputStream inputStream = null; + try { + inputStream = ts.getData(); + } catch (InternalErrorException e) { + e.printStackTrace(); + return null; + } + + OutputStream out = new FileOutputStream(temp); + + byte buf[] = new byte[1024]; + int len; + while((len = inputStream.read(buf))>0) + out.write(buf,0,len); + out.close(); + inputStream.close(); + logger.debug("Successfully got TimeSeries from Basket: \n" + temp.getAbsolutePath()); + return temp; + } + catch (IOException e){ + e.printStackTrace(); + return null; + } catch (InternalErrorException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + + /** + * each portlet instance runs in a scope + * each portlet instance is used by a unique username from within the portal + * @param currentHost . + * @return a SessionInfo bean containing the username the scope andis opening a workflow document or not + */ + public SessionInfo getSessionInfo(String currentHost) { + this.currentHost = currentHost; + + if (testWorkflow) { + + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE, "1"); + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_GIVEN_NAME, "TEST REPORT"); + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_READONLY_ATTRIBUTE, true); + return new SessionInfo(getUsername(), getVreName(), true, true); + } + if (getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE) == null) { + logger.debug("WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE is NULL: "); + return new SessionInfo(getUsername(), getVreName(), false, false); + } + else { + logger.debug("FOUND WORKFLOW_ID_ATTRIBUTE ***** "); + //String workflowid = getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE).toString(); + Boolean canEdit = ! (Boolean) getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_READONLY_ATTRIBUTE); + return new SessionInfo(getUsername(), getVreName(), true, canEdit); + } + } + + + public SerializableModel getWorkflowDocumentFromDocumentLibrary() { + ServiceUtil myUtil = new ServiceUtil(getASLSession()); + + if (testWorkflow) { + FileInputStream fis = null; + ObjectInputStream in = null; + SerializableModel toConvert = null; + try { + fis = new FileInputStream("/Users/massi/portal/CURRENT_OPEN.d4st"); + in = new ObjectInputStream(fis); + toConvert = (SerializableModel) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + toConvert.setTemplateName("TEST"); + logger.info(" Converting TEST REPORT to Serializable object, model name: \n" + toConvert.getTemplateName()); + return toConvert; + } + else { + String workflowid = getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE).toString(); + Boolean canEdit = ! (Boolean) getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_READONLY_ATTRIBUTE); + String documentName = getASLSession().getAttribute(WfDocsLibrary.WORKFLOW_GIVEN_NAME).toString(); + logger.info("getWorkflowDocumentFromDocumentLibrary() CALLED ***** ID = " + workflowid + " name:\n " + documentName); + + //TODO: check this + //reset the values in session + + logger.info("Reset the values in session ... "); + + getASLSession().setAttribute(WfDocsLibrary.LAST_WORKFLOW_ID, workflowid); + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_ID_ATTRIBUTE, null); + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_READONLY_ATTRIBUTE, null); + getASLSession().setAttribute(WfDocsLibrary.WORKFLOW_GIVEN_NAME, null); + + + + try { + InputStream inputStream = DocLibraryUtil.getFileEntryAsStream(getASLSession(), workflowid); + String templatePath = myUtil.getTemplateFolder(getVreName(), getUsername()) + "CURRENT_OPEN/"; + String pathToFile = templatePath; + File toExtract = writeReportToDisk(inputStream, pathToFile, "Workflodoc-report.zip"); + + File outputDir = new File( myUtil.getTemplatePath("", getVreName(), getUsername()) ); + ZipUtil.unzipArchive(toExtract, outputDir); + toExtract.delete(); + + + FileInputStream fis = null; + ObjectInputStream in = null; + SerializableModel toConvert = null; + try { + String path = myUtil.getTemplateFolder(getVreName(), getUsername()); + fis = new FileInputStream(path + "CURRENT_OPEN/CURRENT_OPEN.d4st"); + in = new ObjectInputStream(fis); + toConvert = (SerializableModel) in.readObject(); + in.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + } + toConvert.setTemplateName(documentName); + logger.debug("Converting fileToRead to Serializable object, model name: \n" + toConvert.getTemplateName()); + SerializableModel toReturn = (toConvert); + + //saves this model as previous one in session + getASLSession().setAttribute(PREVIOUS_REPORT_INSTANCE, toConvert); + + AccessLogger log = AccessLogger.getAccessLogger(); + OpenWorkflowLogEntry logEntry = new OpenWorkflowLogEntry(toConvert.getTemplateName(), toConvert.getUniqueID(), toConvert.getAuthor()); + log.logEntry(getASLSession().getUsername(), getASLSession().getScopeName(), logEntry); + + return toReturn; + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + } + + /** + * get the report instance from the Basket + * @param repTmp . + * @param pathToFile the directory where to save the file + * @param filename the filename to give to the newly created file + * @return + */ + private File writeReportToDisk(InputStream isData, String pathToFile, String filename) { + try { + File dir = new File(pathToFile); + logger.debug("DIR: " + pathToFile); + if (! dir.exists() ) + dir.mkdirs(); + + File f = new File(pathToFile+filename); + OutputStream out = new FileOutputStream(f); + + IOUtils.copy(isData, out); + out.close(); + logger.debug("Successfully WROTE ReportTemplate from DL: " + pathToFile); + return f; + } + catch (IOException e){ + e.printStackTrace(); + return null; + } + } + /** + * update the Workflow Document in session + */ + public void updateWorkflowDocument(boolean update) { + ASLSession session = getASLSession(); + ServiceUtil myUtil = new ServiceUtil(session); + + String workflowid = session.getAttribute(WfDocsLibrary.LAST_WORKFLOW_ID).toString(); + SerializableModel model = null; + String documentWorkflowOwnerId = store.getWorkflowById(workflowid).getAuthor(); + String documentWorkflowName = store.getWorkflowById(workflowid).getName(); + if (update) { + logger.debug("SAVING in WorkflowDocument Library "); + + model = (SerializableModel) session.getAttribute(CURRENT_REPORT_INSTANCE); + + logger.debug("Trying to convert dynamic images ... "); + importDynamicImagesFromHL(model); + + + boolean result = myUtil.writeModel(model, "CURRENT_OPEN", getVreName(), getUsername()); + + if (!result) { + logger.error("Could not save report, serializing failed"); + } + else { + String templatePath = myUtil.getTemplateFolder(getVreName(), getUsername()) + "CURRENT_OPEN"; + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + logger.debug("Trying to zip folder: " + templatePath); + + String folderToZip = templatePath; + String outZip = templatePath+"-report.zip"; + + try { + ZipUtil.zipDir(outZip, folderToZip); + logger.debug("Folder zipped, result: "+ outZip); + InputStream isZip = new BufferedInputStream(new FileInputStream(outZip)); + + DocLibraryUtil.updateFileIntoDocLibrary(getASLSession(), workflowid, getBytesFromInputStream(isZip)); + logger.info("Updated in DOC LIB OK"); + store.addWorkflowLogAction(workflowid, getASLSession().getUsername(), "Updated"); + + //send the notification + NotificationsManager nm = new ApplicationNotificationsManager(session, "org.gcube.admin.portlet.wfdocviewer.server.WorkflowDocServiceImpl"); + nm.notifyDocumentWorkflowUpdate(documentWorkflowOwnerId, workflowid, documentWorkflowName); + + AccessLogger log = AccessLogger.getAccessLogger(); + SaveWorkflowLogEntry logEntry = new SaveWorkflowLogEntry(model.getTemplateName(), model.getUniqueID(), model.getAuthor()); + log.logEntry(getASLSession().getUsername(), getASLSession().getScopeName(), logEntry); + + } + catch (Exception e) { + logger.error("Could not zip template, serializing failed"); + e.printStackTrace(); + } + } + } else { + store.addWorkflowLogAction(workflowid, getASLSession().getUsername(), "Viewed"); + //send the notification + NotificationsManager nm = new ApplicationNotificationsManager(session, "org.gcube.admin.portlet.wfdocviewer.server.WorkflowDocServiceImpl"); + nm.notifyDocumentWorkflowView(documentWorkflowOwnerId, workflowid, documentWorkflowName); + } + //unlocks + unlock(workflowid); + getASLSession().setAttribute("idreport", null); + } + + /** + */ + byte[] getBytesFromInputStream(InputStream is) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + try { + IOUtils.copy(is, os); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return os.toByteArray(); + } + /** + * + * @param workflowid . + */ + private void unlock(String workflowid) { + DLFileEntry fileEntry; + try { + fileEntry = DocLibraryUtil.getFileEntry(getASLSession(), workflowid); + logger.info("Log action saved, trying ot unlock document ..."); + LockLocalServiceUtil.unlock(DLFileEntry.class.getName(), fileEntry.getFileEntryId()); + logger.info("UNLOCK OK!"); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void renewLock() { + HttpSession httpSes = this.getThreadLocalRequest().getSession(); + httpSes.setMaxInactiveInterval(-1); //session won't expire + String workflowid = getASLSession().getAttribute(WfDocsLibrary.LAST_WORKFLOW_ID).toString(); + try { + DLFileEntry fileEntry = DocLibraryUtil.getFileEntry(getASLSession(), workflowid); + logger.info("Renewing Lock ..."); + long fifteenMin = 900000; + Date currTimePlus15 = new Date(new Date().getTime() + fifteenMin); + LockLocalServiceUtil.getLock(DLFileEntry.class.getName(), fileEntry.getFileEntryId()).setExpirationDate(currTimePlus15); + logger.info("Lock Renewed, expiring: " + currTimePlus15); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + + + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ZipUtil.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ZipUtil.java new file mode 100644 index 0000000..890a676 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/ZipUtil.java @@ -0,0 +1,130 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.io.IOUtils; +import org.gcube.common.core.utils.logging.GCUBELog; + +/** + * + * @author massi + * + */ +public class ZipUtil { + + + public static GCUBELog logger = new GCUBELog(ZipUtil.class); + + /** + * @param zipFileName zipFileName + * @param dir the dir to compress + * @throws IOException . + */ + public static void zipDir(String zipFileName, String dir) throws IOException { + + File dirObj = new File(dir); + if(!dirObj.isDirectory()) + { + System.err.println(dir + " is not a directory"); + System.exit(1); + } + + ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName)); + logger.debug("Creating : " + zipFileName); + addDir(dirObj, out); + // Complete the ZIP file + out.close(); + } + + private static void addDir(File dirObj, ZipOutputStream out) throws IOException + { + File[] files = dirObj.listFiles(); + byte[] tmpBuf = new byte[1024]; + + for (int i=0; i 0) + { + out.write(tmpBuf, 0, len); + } + + // Complete the entry + out.closeEntry(); + in.close(); + } + } + + /** + * + * @param archive . + * @param outputDir . + */ + public static void unzipArchive(File archive, File outputDir) { + try { + ZipFile zipfile = new ZipFile(archive); + for (Enumeration e = zipfile.entries(); e.hasMoreElements(); ) { + ZipEntry entry = (ZipEntry) e.nextElement(); + unzipEntry(zipfile, entry, outputDir); + } + } catch (Exception e) { + logger.error("while extracting file " + archive); + e.printStackTrace(); + } + } + + private static void unzipEntry(ZipFile zipfile, ZipEntry entry, File outputDir) throws IOException { + + if (entry.isDirectory()) { + createDir(new File(outputDir, entry.getName())); + return; + } + + File outputFile = new File(outputDir, entry.getName()); + if (!outputFile.getParentFile().exists()){ + createDir(outputFile.getParentFile()); + } + + logger.debug("Extracting: " + entry); + BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry)); + BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile)); + + try { + IOUtils.copy(inputStream, outputStream); + } finally { + outputStream.close(); + inputStream.close(); + } + } + + private static void createDir(File dir) { + logger.info("Creating dir "+dir.getName()); + if(!dir.mkdirs()) throw new RuntimeException("Can not create dir "+dir); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/CreateReportLogEntry.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/CreateReportLogEntry.java new file mode 100644 index 0000000..8adc081 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/CreateReportLogEntry.java @@ -0,0 +1,26 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet.loggers; + +import org.gcube.application.framework.accesslogger.model.AccessLogEntry; + +/** + * Represents an access log entry for creating a new Template + */ +public class CreateReportLogEntry extends AccessLogEntry{ + + private String templateName; + + private String templateId; + + public CreateReportLogEntry(String templateName, String templateId) { + super("Create_Report"); + this.templateName = replaceReservedChars(templateName); + this.templateId = replaceReservedChars(templateId); + } + + @Override + public String getLogMessage() { + String message = "Name = " + templateName + "|ID = " + templateId; + return message; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/GenerateReportLogEntry.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/GenerateReportLogEntry.java new file mode 100644 index 0000000..dc63b30 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/GenerateReportLogEntry.java @@ -0,0 +1,28 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet.loggers; + +import org.gcube.application.framework.accesslogger.model.AccessLogEntry; + +/** + * Represents an access log entry for creating a new Template + */ +public class GenerateReportLogEntry extends AccessLogEntry{ + + private String name; + + private String mimetype; + + private String type; + + public GenerateReportLogEntry(String name, String mimetype, String type) { + super("Generate_Report_Output"); + this.name = replaceReservedChars(name); + this.mimetype = replaceReservedChars(mimetype); + } + + @Override + public String getLogMessage() { + String message = "Name = " + name + "|MIMETYPE = " + mimetype+ "|TYPE = " + type; + return message; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenReportLogEntry.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenReportLogEntry.java new file mode 100644 index 0000000..0e661ac --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenReportLogEntry.java @@ -0,0 +1,27 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet.loggers; + +import org.gcube.application.framework.accesslogger.model.AccessLogEntry; + + +/** + * Represents an access log entry for creating a new Template + */ +public class OpenReportLogEntry extends AccessLogEntry{ + + private String templateName; + + private String templateId; + + public OpenReportLogEntry(String templateName, String templateId) { + super("Open_Report"); + this.templateName = replaceReservedChars(templateName); + this.templateId = replaceReservedChars(templateId); + } + + @Override + public String getLogMessage() { + String message = "Name = " + templateName + "|ID = " + templateId; + return message; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenWorkflowLogEntry.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenWorkflowLogEntry.java new file mode 100644 index 0000000..9693eee --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/OpenWorkflowLogEntry.java @@ -0,0 +1,28 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet.loggers; + +import org.gcube.application.framework.accesslogger.model.AccessLogEntry; + + +/** + * Represents an access log entry for creating a new Template + */ +public class OpenWorkflowLogEntry extends AccessLogEntry{ + + private String templateName; + private String author; + private String templateId; + + public OpenWorkflowLogEntry(String templateName, String templateId, String author) { + super("Open_Workflow_Report"); + this.author = author; + this.templateName = replaceReservedChars(templateName); + this.templateId = replaceReservedChars(templateId); + } + + @Override + public String getLogMessage() { + String message = "Name = " + templateName + "|ID = " + templateId+ "|AUTHOR = " + author; + return message; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/SaveWorkflowLogEntry.java b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/SaveWorkflowLogEntry.java new file mode 100644 index 0000000..7fcefad --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/server/servlet/loggers/SaveWorkflowLogEntry.java @@ -0,0 +1,28 @@ +package org.gcube.portlets.user.reportgenerator.server.servlet.loggers; + +import org.gcube.application.framework.accesslogger.model.AccessLogEntry; + + +/** + * Represents an access log entry for creating a new Template + */ +public class SaveWorkflowLogEntry extends AccessLogEntry{ + + private String templateName; + private String author; + private String templateId; + + public SaveWorkflowLogEntry(String templateName, String templateId, String author) { + super("Save_Workflow_Report"); + this.author = author; + this.templateName = replaceReservedChars(templateName); + this.templateId = replaceReservedChars(templateId); + } + + @Override + public String getLogMessage() { + String message = "Name = " + templateName + "|ID = " + templateId+ "|AUTHOR = " + author; + return message; + } + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/reportgenerator/shared/SessionInfo.java b/src/main/java/org/gcube/portlets/user/reportgenerator/shared/SessionInfo.java new file mode 100644 index 0000000..a7e1c6a --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/reportgenerator/shared/SessionInfo.java @@ -0,0 +1,57 @@ +package org.gcube.portlets.user.reportgenerator.shared; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class SessionInfo implements Serializable { + + private String username; + private String scope; + private Boolean isWorkflowDocument; + private Boolean isEditable; + + public SessionInfo() { } + + public SessionInfo(String username, String scope, + Boolean isWorkflowDocument, Boolean canEdit) { + super(); + this.username = username; + this.scope = scope; + this.isWorkflowDocument = isWorkflowDocument; + this.isEditable = canEdit; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public Boolean isWorkflowDocument() { + return isWorkflowDocument; + } + + public void setIsWorkflowDocument(Boolean isWorkflowDocument) { + this.isWorkflowDocument = isWorkflowDocument; + } + + public Boolean isEditable() { + return isEditable; + } + + public void setEditable(Boolean canEdit) { + this.isEditable = canEdit; + } + + +} diff --git a/src/main/resources/org/gcube/portlets/user/reportgenerator/ReportGenerator.gwt.xml b/src/main/resources/org/gcube/portlets/user/reportgenerator/ReportGenerator.gwt.xml new file mode 100644 index 0000000..5304baa --- /dev/null +++ b/src/main/resources/org/gcube/portlets/user/reportgenerator/ReportGenerator.gwt.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/ReportGenerator.css b/src/main/webapp/ReportGenerator.css new file mode 100644 index 0000000..f8cabfe --- /dev/null +++ b/src/main/webapp/ReportGenerator.css @@ -0,0 +1,595 @@ + +.tableBorder { + border: 1px solid #CCC; + height: 30px; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + color: #333; +} + +.selectable { + cursor: pointer; + cursor: hand; +} + +.comment-popup-header { + background-color: #EEE8BC; + border-color: none; +} + +.comment-popup { + background-color: #FFF8CC; + border-color: #EEE8BC; + border-style: solid; + border-width: 2px; +} + +.comment-popup-textarea { + background-color: #FFF8CC; + border:none; + font-family: Arial, Helvetica, sans-serif; + font-size: 11px; +} + +.selectedCell { + background-color: #e3e8f3 !important; +} + +.dialogText { + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} + +tableBorder td { + border: 2px solid #BBBBBB; + padding: 3px; +} + +.checkAttribute label { + margin-left: 5px; + margin-right: 5px; +} + +.wpFlow { + border: 0px solid gray; +} + +.highlight_background { + background-color: #FFFE00; + /* filter:alpha(opacity=80); + -moz-opacity:0.8; + -khtml-opacity: 0.8; + opacity: 0.8;*/ +} + +.none { + border: none; +} + +.d4sRichTextArea { + background-color: #FFFFFF; + font-family: Times; + font-size: 20px; + border: none; +} + +.d4sFrame { + border: 1px dashed #CCC; + background-color: white; + margin-top: 15px; + margin-left: 15px; +} + +.fixedTextArea { + font-family: Times; + font-size: 20px; +} + +.droppingArea-Image { + border: 1px dashed #CCC; + background-image: url(images/droppingImage_bg.gif); + background-repeat: repeat; + margin-top: 25px; + margin-left: 15px; +} + +.label { + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 10px; +} + +.docEditedBy { + color: #666666; + font-family: Arial, sans-serif; + font-size: 11px !important; +} + +.menubar { + background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px; + border: 1px solid #BBBBBB; + text-align: left; + vertical-align: top; + padding-top: 2px; +} + +.menubar-font { + font-family: Arial, sans-serif; + font-size: 16px; + font-weight: bold; +} + +.reportHeader { + background-color: #CADEF4; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + padding: 1px 4px 1px 4px; + border-top: 1px solid #3366CC; +} + +.timeSeries_header { + background-color: #008080; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold; + color: #FFFFFF; + border: 1px solid #BBBBBB; + padding: 3px; +} + +.timeSeries_header_font { + background-color: #008080; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 10px; + font-weight: bold; + color: #FFFFFF; + padding: 3px; +} + +.timeSeries_td { + background-color: #B7B7FF; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 10px; + padding: 3px; +} + +.margins { + border: 1px dashed #CCC; +} + +.pagebreak { + background-image: url(images/pagebreak.gif); + border: 1px dashed #CCC; + background-repeat: repeat-x; +} + +.timeseriesArea { + border: 1px dashed #CCC; + background-repeat: repeat; + margin-top: 25px; + margin-left: 15px; +} + +.d4sRichTextArea { + background-color: #FFFFFF; + font-family: Times; + font-size: 20px; + border: none; +} + +.commentArea { + background-image: url(images/comment_area.gif); + background-repeat: no-repeat; + margin-top: 15px; + margin-left: 20px; + padding-left: 15px; + border: 0px solid gray; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + font-style: italic; + color: #AAA; +} + +.attributeArea { + background-image: url(images/attribute_area.gif); + background-repeat: no-repeat; + margin-top: 15px; + margin-left: 20px; + padding-left: 15px; + border: 1px dashed #CCC; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + color: Blue; +} + +.attributeValue { + padding-right: 5px; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + color: Blue; +} + +.instructionArea { + background-image: url(images/instruction_area.gif); + background-repeat: no-repeat; + margin-top: 15px; + margin-left: 20px; + padding-left: 15px; + border: 0px solid gray; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + font-family: "Courier New", Courier, monospace; + font-size: 11px; + color: #666; +} + +.gridAttribute { + background-color: #FFF; + padding: 3px; +} + +.pagebreak { + background-image: url(images/pagebreak.gif); + border: 1px dashed #CCC; + background-repeat: repeat-x; +} + +.titleArea { + background-image: url(images/title_area.png); + background-repeat: no-repeat; + padding-top: 5px; + padding-left: 20px; + margin-left: 0px; + border: none; + font-family: Times; + font-size: 16pt; + font-family: Verdana; + color: maroon; +} + +.headgin1Area { + background-image: url(images/heading_1.png); + background-repeat: no-repeat; + padding-top: 5px; + padding-left: 20px; + margin-left: 0px; + border: none; + font-family: Times; + font-size: 12pt; + font-family: Verdana; + color: maroon; +} + +.headgin2Area { + background-image: url(images/heading_2.png); + background-repeat: no-repeat; + padding-top: 5px; + padding-left: 20px; + margin-left: 0px; + border: none; + font-family: Times; + font-size: 11pt; + font-family: Verdana; + color: maroon; +} + +.headgin3Area { + background-image: url(images/heading_3.png); + background-repeat: no-repeat; + padding-top: 5px; + padding-left: 20px; + margin-left: 0px; + border: none; + font-family: Times; + font-size: 10pt; + font-family: Verdana; + color: maroon; +} + +.bodyArea { + background-image: none; +} + +.headerArea { + background-image: url(images/header.jpg); +} + +.footerArea { + background-image: url(images/footer.jpg); +} + +.tableArea { + background-image: url(images/table.jpg); +} + +.timeseriesArea_bg { + background-image: url(images/TimeSeries_bg.gif); +} + +.tocArea { + background-image: url(images/toc.jpg); + border: 1px dashed #CCC; + background-repeat: repeat-x; +} + +.biblioArea { + background-image: url(images/biblio.jpg); + border: 1px dashed #CCC; + background-repeat: repeat-x; +} + +.d4sFrame-highlight { + background-color: #e4f2f6; + filter: alpha(opacity = 50); + -moz-opacity: .50; + opacity: .50; + cursor: pointer; + cursor: hand; +} + +.droppingArea-Text { + border: 1px dashed #CCC; + background-image: url(images/droppingText_bg.gif); + background-repeat: repeat; +} + +.droppingArea-Text { + border: 1px dashed #CCC; + background-image: url(images/droppingText_bg.gif); + background-repeat: repeat; +} + +.setVisibilityOff { + visibility: hidden; +} + +.setVisibilityOn { + margin-top: 1px; + visibility: visible; + cursor: pointer; + cursor: hand; +} + +.templateFrame { + border: 1px solid gray; +} + +.toolBoxFrame { + background-color: #FFFFFF; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + /*padding: 1px 4px 1px 4px;*/ + border: 1px solid #CCC; +} + +.toolBoxLabel { + background-color: #CADEF4; + color: gray; + font-weight: bold; + border-bottom: 1px solid #CCC; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + padding: 1px 4px 1px 4px; +} + +.toolFrame { + padding: 4px; + cursor: pointer; + cursor: hand; + border: 1px outset #CCC; +} + +gwt-MenuBar { + cursor: default; + border: none; +} + +.gwt-MenuBar .gwt-MenuItem { + cursor: pointer; + cursor: hand; + border: 0px; + padding: 2px 8px; +} + +.gwt-MenuBar .gwt-MenuItem-selected { + background: #E0EDFE; +} + +.gwt-MenuBar-horizontal { + border: none; +} + +.gwt-MenuBar-horizontal .gwt-MenuItem { + vertical-align: bottom; + color: #3366CC; + font-weight: bold; +} + +.gwt-MenuBar-horizontal .gwt-MenuItemSeparator { + width: 1px; + padding: 0px; + margin: 0px; + border: 0px; + border-left: 1px solid #888888; + background: white; +} + +.gwt-MenuBar-horizontal .gwt-MenuItemSeparator .menuSeparatorInner { + width: 1px; + height: 1px; + background: white; +} + +.gwt-MenuBar-vertical .gwt-MenuItemSeparator .menuSeparatorInner { + margin-top: 0px; + margin-left: 0px; + border-top: 1px solid #888888; + background: white; +} + +.gwt-TextArea { + border: 1px inset #3366CC; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} + +.gwt-TextBox { + padding: 2px; + border: 1px inset #3366CC; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} + +.textArea-inserted-highlight { + background-color: #e4f2f6; + cursor: pointer; + cursor: hand; +} + +.crossCursor { + cursor: crosshair; +} + +.widthResizeCursor { + cursor: e-resize; +} + +.heightResizeCursor { + cursor: s-resize; +} + +.seResizeCursor { + cursor: se-resize; +} + +.cursor-move { + cursor: move; +} + +.position-relative { + position: relative; +} + +.gwt-ToggleButton { + cursor: pointer; + cursor: hand; + color: #3366CC; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + /*border: 1px outset navy;*/ +} + +.gwt-ToggleButton-down,.gwt-ToggleButton-down-hovering,.gwt-ToggleButton-down-disabled + { + padding: 4px 4px 2px 6px; + /* background: none; + color:White; + background-color:#3366CC;*/ +} + +.hasRichTextToolbar { + background-color: #FFFFFF; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; + border: 1px inset #3366CC; +} + +.gwt-RichTextToolbar { + background: #e3e8f3 url(images/hborder.png) repeat-x 0px -2003px; + border-bottom: 1px solid #BBBBBB; + padding: 3px; + margin: 0px; +} + +.gwt-RichTextToolbar .gwt-PushButton-up { + padding: 0px 1px 0px 0px; + margin-right: 4px; + margin-bottom: 4px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-PushButton-up-hovering { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 1px 0px 0px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-PushButton-down { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 0px 0px 1px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-PushButton-down-hovering { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 0px 0px 1px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-ToggleButton-up { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 1px 0px 0px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-ToggleButton-up-hovering { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 1px 0px 0px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-ToggleButton-down { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 0px 0px 1px; + border-width: 1px; +} + +.gwt-RichTextToolbar .gwt-ToggleButton-down-hovering { + margin-right: 4px; + margin-bottom: 4px; + padding: 0px 0px 0px 1px; + border-width: 1px; +} + +.cw-RichText { + border: 1px solid #BBBBBB; + border-spacing: 0px; +} + +/* *********** FANCY FILE UPLOAD **************/ +.fancyfileupload-pending { + font-family: arial; + font-size: 10px; + background: orange; + width: 200px; +} + +.fancyfileupload-loading { + font-family: arial; + font-size: 10px; + background: orange; + width: 200px; +} + +.fancyfileupload-loaded { + font-family: arial; + font-size: 10px; + background: lightgreen; + width: 200px; +} + +.fancyfileupload-failed { + font-family: arial; + font-size: 10px; + background: blue; + width: 200px; +} + +/* *********** END FANCY FILE UPLOAD **************/ +.droppingArea-Text { + border: 1px inset black; +} \ No newline at end of file diff --git a/src/main/webapp/ReportGenerator.html b/src/main/webapp/ReportGenerator.html new file mode 100644 index 0000000..180d5eb --- /dev/null +++ b/src/main/webapp/ReportGenerator.html @@ -0,0 +1,29 @@ + + + + + + + + + + + + Report Generator + + + + + + + + + + + + + + +
+ + diff --git a/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_edit.jsp b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_edit.jsp new file mode 100644 index 0000000..0a197a8 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_edit.jsp @@ -0,0 +1,13 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> + +<%-- Uncomment below lines to add portlet taglibs to jsp +<%@ page import="javax.portlet.*"%> +<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> + + +--%> + + + EDIT MODE + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_help.jsp b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_help.jsp new file mode 100644 index 0000000..39ed5a1 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_help.jsp @@ -0,0 +1,13 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> + +<%-- Uncomment below lines to add portlet taglibs to jsp +<%@ page import="javax.portlet.*"%> +<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> + + +--%> + + + HELP MODE + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_view.jsp b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_view.jsp new file mode 100644 index 0000000..7209bf6 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/ReportGeneratorPortlet_view.jsp @@ -0,0 +1,12 @@ +<%@page contentType="text/html"%> +<%@page pageEncoding="UTF-8"%> + +<%-- Uncomment below lines to add portlet taglibs to jsp +<%@ page import="javax.portlet.*"%> +<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> + + +--%> + + +
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/liferay-display.xml b/src/main/webapp/WEB-INF/liferay-display.xml new file mode 100644 index 0000000..ae4c1f4 --- /dev/null +++ b/src/main/webapp/WEB-INF/liferay-display.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/main/webapp/WEB-INF/liferay-plugin-package.properties b/src/main/webapp/WEB-INF/liferay-plugin-package.properties new file mode 100644 index 0000000..2898b81 --- /dev/null +++ b/src/main/webapp/WEB-INF/liferay-plugin-package.properties @@ -0,0 +1,9 @@ +name=Report Generator +module-group-id=liferay +module-incremental-version=1 +tags= +short-description= +change-log= +page-url=http://www.liferay.com +author=Liferay, Inc. +licenses=MIT \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/liferay-portlet.xml b/src/main/webapp/WEB-INF/liferay-portlet.xml new file mode 100644 index 0000000..fe41288 --- /dev/null +++ b/src/main/webapp/WEB-INF/liferay-portlet.xml @@ -0,0 +1,28 @@ + + + + + + reporting + false + false + false + /ReportGenerator.css + + + administrator + Administrator + + + guest + Guest + + + power-user + Power User + + + user + User + + diff --git a/src/main/webapp/WEB-INF/portlet.xml b/src/main/webapp/WEB-INF/portlet.xml new file mode 100644 index 0000000..20c6017 --- /dev/null +++ b/src/main/webapp/WEB-INF/portlet.xml @@ -0,0 +1,25 @@ + + + + + reporting + Report Generator + org.gcube.portlets.user.reportgenerator.server.portlet.ReportGeneratorPortlet + + view-jsp + /WEB-INF/jsp/ReportGeneratorPortlet_view.jsp + + 0 + + text/html + + + Report Generator + Report Generator + Report Generator + + + administrator + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..ac5168a --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,134 @@ + + + ReportGenerator-portlet + + + ReportServiceImpl + org.gcube.portlets.user.reportgenerator.server.servlet.ReportServiceImpl + + + + ReportServiceImpl + /reports/ReportServiceImpl + + + + + quicktourServlet + org.gcube.portlets.user.guidedtour.server.TourServiceImpl + + + + quicktourServlet + /reports/quicktourServlet + + + + + ImagesUploadServlet + org.gcube.portlets.user.reportgenerator.server.servlet.ImagesUploadServlet + + + + ImagesUploadServlet + /reports/ImagesUploadServlet + + + + WorkspaceLightService + org.gcube.portlets.user.workspace.lighttree.server.WorkspaceServiceImpl + + + + WorkspaceLightService + /reports/WorkspaceLightService + + + + + + remoteLoggerServiceImpl + com.allen_sauer.gwt.log.server.RemoteLoggerServiceImpl + + + + remoteLoggerServiceImpl + /reports/gwt-log + + + + + WorkspaceService + org.gcube.portlets.user.workspace.server.GWTWorkspaceServiceImpl + + + + WorkspaceService + /reports/WorkspaceService + + + + UploadService + org.gcube.portlets.user.workspace.server.UploadServlet + + + + UploadService + /reports/UploadService + + + + DownloadService + org.gcube.portlets.user.workspace.server.DownloadServlet + + + + DownloadService + /reports/DownloadService + + + + ImageService + org.gcube.portlets.user.workspace.server.ImageServlet + + + + ImageService + /reports/ImageService + + + + + + + + + + + DownloadService + /org.gcube.portlets.user.reportgenerator.ReportGeneratorJUnit/DownloadService + + + WorkspaceService + /org.gcube.portlets.user.reportgenerator.ReportGeneratorJUnit/WorkspaceService + + + ImageService + /org.gcube.portlets.user.reportgenerator.ReportGeneratorJUnit/ImageService + + + + UploadService + /org.gcube.portlets.user.reportgenerator.ReportGeneratorJUnit/UploadService + + + + ReportGenerator.html + + diff --git a/src/main/webapp/gxt/css/gxt-all.css b/src/main/webapp/gxt/css/gxt-all.css new file mode 100644 index 0000000..608d24b --- /dev/null +++ b/src/main/webapp/gxt/css/gxt-all.css @@ -0,0 +1,7451 @@ +html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';} +.x-contrast-test { + background: url(../images/default/s.gif); + visibility: hidden; + position: relative; + left: -1000px; + top: -1000px; +} +.ext-el-mask { + z-index: 100; + position: absolute; + top: 0; + left: 0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity = 50); + width: 100%; + height: 100%; + zoom: 1; +} + +.ext-el-mask-msg { + z-index: 101; + position: absolute; + top: 0; + left: 0; + border: 1px solid; + background: repeat-x 0 -16px; + padding: 2px; +} + +.ext-el-mask-msg div { + padding: 5px 10px 5px 10px; + border: 1px solid; + cursor: wait; +} + +.ext-webkit *:focus { + outline: none !important; +} + +.ext-webkit .x-form-check-wrap input:focus { + outline: auto !important; +} + +.ext-shim { + position: absolute; + visibility: hidden; + left: 0; + top: 0; + overflow: hidden; +} + +.ext-ie .ext-shim { + filter: alpha(opacity = 0); +} + +.ext-ie6 .ext-shim { + margin-left: 5px; + margin-top: 3px; +} + +.x-mask-loading div { + padding: 5px 10px 5px 25px; + background: no-repeat 5px 5px; + line-height: 16px; +} + +.x-hidden,.x-hide-offsets { + position: absolute !important; + left: -10000px !important; + top: -10000px !important; + visibility: hidden !important; +} + +.x-hide-display { + display: none !important; +} + +.x-hide-visibility { + visibility: hidden !important; +} + +.x-masked { + overflow: hidden !important; +} + +.x-masked-relative { + position: relative !important; +} + +.x-masked select,.x-masked object,.x-masked embed { + visibility: hidden; +} + +.x-layer { + visibility: hidden; +} + +.x-unselectable,.x-unselectable * { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore; +} + +.x-unselectable-single { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore; +} + +.x-selectable,.x-selectable * { + -moz-user-select: text !important; + -webkit-user-select: auto; +} + +.x-repaint { + zoom: 1; + background-color: transparent; + -moz-outline: none; + outline: 0 none; +} + +.x-item-disabled { + cursor: default; + opacity: .6; + -moz-opacity: .6; + filter: alpha(opacity = 60); +} + +.ext-ie .x-item-disabled { + filter: none !important; +} + +.x-item-disabled * { + cursor: default !important; +} + +.x-splitbar-proxy { + position: absolute; + visibility: hidden; + z-index: 20001; + zoom: 1; + line-height: 1px; + font-size: 1px; + overflow: hidden; +} + +.x-splitbar-h,.x-splitbar-proxy-h { + cursor: e-resize; + cursor: col-resize; +} + +.x-splitbar-v,.x-splitbar-proxy-v { + cursor: s-resize; + cursor: row-resize; +} + +.x-color-palette { + width: 150px; + height: 92px; + cursor: pointer; + -moz-outline: 0 none; + outline: 0 none; +} + +.x-color-palette a { + border: 1px solid; + float: left; + padding: 2px; + text-decoration: none; + -moz-outline: 0 none; + outline: 0 none; + cursor: pointer; +} + +.x-color-palette a.x-color-palette-hover,.x-color-palette a.x-color-palette-sel { + border: 1px solid; +} + +.x-color-palette em { + display: block; + border: 1px solid; +} + +.x-color-palette em span { + cursor: pointer; + display: block; + height: 10px; + line-height: 10px; + width: 10px; +} + +.x-ie-shadow { + display: none; + position: absolute; + overflow: hidden; + left: 0; + top: 0; + zoom: 1; +} + +.x-shadow { + display: none; + position: absolute; + overflow: hidden; + left: 0; + top: 0; +} + +.x-shadow * { + overflow: hidden; +} + +.x-shadow * { + padding: 0; + border: 0; + margin: 0; + clear: none; + zoom: 1; +} + +.x-shadow .xstc,.x-shadow .xsbc { + height: 6px; + float: left; +} + +.x-shadow .xstl,.x-shadow .xstr,.x-shadow .xsbl,.x-shadow .xsbr { + width: 6px; + height: 6px; + float: left; +} + +.x-shadow .xsc { + width: 100%; +} + +.x-shadow .xsml,.x-shadow .xsmr { + width: 6px; + float: left; + height: 100%; +} + +.x-shadow .xsmc { + float: left; + height: 100%; + background: transparent; +} + +.x-shadow .xst,.x-shadow .xsb { + height: 6px; + overflow: hidden; + width: 100%; +} + +.x-shadow .xsml { + background: transparent repeat-y 0 0; +} + +.x-shadow .xsmr { + background: transparent repeat-y -6px 0; +} + +.x-shadow .xstl { + background: transparent no-repeat 0 0; +} + +.x-shadow .xstc { + background: transparent repeat-x 0 -30px; +} + +.x-shadow .xstr { + background: transparent repeat-x 0 -18px; +} + +.x-shadow .xsbl { + background: transparent no-repeat 0 -12px; +} + +.x-shadow .xsbc { + background: transparent repeat-x 0 -36px; +} + +.x-shadow .xsbr { + background: transparent repeat-x 0 -6px; +} + +.loading-indicator { + background: no-repeat left; + padding-left: 20px; + line-height: 16px; + margin: 3px; +} + +.x-text-resize { + position: absolute; + left: -1000px; + top: -1000px; + visibility: hidden; + zoom: 1; +} + +.x-drag-overlay { + width: 100%; + height: 100%; + display: none; + position: absolute; + left: 0; + top: 0; + background-image: url(../images/default/s.gif); + z-index: 20000; +} + +.x-clear { + clear: both; + overflow: hidden; + line-height: 0; + font-size: 0; +} + +.x-spotlight { + z-index: 8999; + position: absolute; + top: 0; + left: 0; + -moz-opacity: 0.5; + opacity: .50; + filter: alpha(opacity = 50); + width: 0; + height: 0; + zoom: 1; +} + +#x-history-frame { + position: absolute; + top: -1px; + left: 0; + width: 1px; + height: 1px; + visibility: hidden; +} + +#x-history-field { + position: absolute; + top: 0; + left: -1px; + width: 1px; + height: 1px; + visibility: hidden; +} + +.x-portlet { + margin-bottom: 10px; +} + +.x-portlet .x-panel-body { + background-color: white !important; +} + +.ext-ie .x-btn-icon .x-btn-center .x-btn-text { + height: auto; +} + +.x-portal-insert div { + height: 4px; + font-size: 0px; + border: 2px dotted blue; +} + +.icon-wait { + background: url(../images/gxt/icons/wait.gif) no-repeat !important; +} + +.x-panel-icon { + padding-left: 20px !important; +} + +.x-icon-btn { + width: 16px; + height: 16px; + overflow: hidden; + background-repeat: no-repeat; + cursor: pointer; +} + +.x-panel-inline-icon { + margin-top: 0; +} + +.x-modal { + position: absolute; + z-index: 10; + background-color: black; + filter: alpha(opacity = 10); + opacity: .1; + left: 0px; + top: 0px; +} + +.x-progress { + font-family: tahoma, arial, helvetica, sans-serif; +} + +.x-float-right { + float: right; +} + +.x-toolbar .x-float-right { + margin-right: 4px; +} + +.x-border { + border: 1px solid #99BBE8; +} + +.x-border-top { + border-top: 1px solid #99BBE8; +} + +.x-layout-popup { + background-color: #DFE8F6; + border: 1px solid #7CA4D9; +} + +.x-panel-popup-body { + border-top: 1px solid #99BBE8; +} + +.x-layout-collapsed .x-panel-header { + border-left: none; + border-right: none; + border-top: none; +} + +.x-layout-collapsed .x-panel-header .x-tool { + margin: 0 0 0 -4px; + padding: 0px; +} + +.x-layout-collapsed { + position: absolute; + visibility: hidden; + background-color: #d2e0f2; + width: 20px; + height: 20px; + overflow: hidden; + border: 1px solid #98c0f4; + z-index: 20; +} + +.ext-border-box .x-layout-collapsed { + width: 22px; + height: 22px; +} + +.x-layout-collapsed-over { + cursor: pointer; + background-color: #d9e8fb; +} + +.x-layout-collapsed-west .x-layout-collapsed-tools,.x-layout-collapsed-east .x-layout-collapsed-tools { + position: absolute; + top: 0; + left: 0; + width: 20px; + height: 20px; +} + +.x-panel-toolbar { + float: right; +} + +.x-cursor-row-resize { + cursor: n-resize; + cursor: row-resize; +} + +.x-date-picker,.x-date-picker a { + font-size: 11px; +} + +.x-date-days { + table-layout: fixed; + width: 100%; +} + +.x-date-days td { + width: 25px; + border: none; +} + +.x-date-days td span { + display: block; + padding: 2px 7px 2px 2px; +} + +.x-date-days td { + background: #DFECFB url(../images/default/shared/glass-bg.gif) repeat-x scroll left top; + border-bottom: 1px solid #A3BAD9; + border-collapse: separate; + color: #233D6D; + cursor: default; + font-family: arial, helvetica, tahoma, sans-serif; + font-size: 10px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: normal; + padding: 0pt; + text-align: right !important; +} + +.x-date-picker .x-date-header { + background: url(../images/default/shared/hd-sprite.gif) repeat-x 0 -83px; + height: 22px; + left: 10px; + top: 10px; + width: 157px; +} + +.x-date-header .x-btn .x-btn-text { + color: #fff; +} + +.x-date-picker-footer { + width: 100%; +} + +.x-date-picker-footer td { + text-align: center; +} + +.x-date-left { + background: transparent url(../images/default/shared/hd-sprite.gif) repeat-x scroll 0pt -83px; + color: #FFFFFF; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 11px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: bold; + line-height: normal; + overflow: hidden; +} + +.x-modal { + position: absolute; + z-index: 10; + background-color: black; + filter: alpha(opacity = 10); + opacity: .1; + left: 0px; + top: 0px; +} + +.x-progress { + font-family: tahoma, arial, helvetica, sans-serif; +} + +.x-float-right { + float: right; +} + +.x-layout-popup { + background-color: #DFE8F6; + border: 1px solid #7CA4D9; +} + +.x-layout-collapsed .x-panel-header .x-tool { + margin: 0 0 0 -4px; + padding: 0px; +} + +.ext-border-box .x-layout-collapsed { + width: 22px; + height: 22px; +} + +.x-layout-collapsed-over { + cursor: pointer; + background-color: #d9e8fb; +} + +.x-layout-collapsed-west .x-layout-collapsed-tools,.x-layout-collapsed-east .x-layout-collapsed-tools { + position: absolute; + top: 0; + left: 0; + width: 20px; + height: 20px; +} + +.x-panel-toolbar { + float: right; +} + +.x-cursor-col-resize { + cursor: e-resize; + cursor: col-resize; +} + +.x-cursor-row-resize { + cursor: n-resize; + cursor: row-resize; +} + +.x-drag-proxy { + border: 1px dashed #3b5a82; + background-color: #EDEDED; + filter: alpha(opacity = 50); + opacity: .5; + background-color: #c3daf9; + z-index: 20000; + overflow: hidden; + position: absolute; + left: 0;; + top: 0; + cursor: move; +}.x-tab-panel { + overflow: hidden; + -moz-outline: none; + outline: 0 none; +} + +.x-tab-panel-header,.x-tab-panel-footer { + border: 1px solid; + overflow: hidden; + zoom: 1; +} + +.x-tab-panel-header { + border: 1px solid; + padding-bottom: 2px; +} + +.x-tab-panel-footer { + border: 1px solid; + padding-top: 2px; +} + +.x-tab-strip-wrap { + width: 100%; + overflow: hidden; + position: relative; + zoom: 1; +} + +ul.x-tab-strip { + display: block; + width: 7000px; + zoom: 1; +} + +ul.x-tab-strip-top { + padding-top: 1px; + background: repeat-x bottom; + border-bottom: 1px solid; +} + +ul.x-tab-strip-bottom { + padding-bottom: 1px; + background: repeat-x top; + border-top: 1px solid; + border-bottom: 0 none; +} + +.x-tab-panel-header-plain .x-tab-strip-top { + background: transparent !important; + padding-top: 0 !important; +} + +.x-tab-panel-header-plain { + background: transparent !important; + border-width: 0 !important; + padding-bottom: 0 !important; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer,.x-tab-panel-footer-plain .x-tab-strip-spacer + { + border: 1px solid; + height: 2px; + font-size: 1px; + line-height: 1px; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer { + border-top: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-bottom: 0 none; +} + +.x-tab-panel-footer-plain .x-tab-strip-bottom { + background: transparent !important; + padding-bottom: 0 !important; +} + +.x-tab-panel-footer-plain { + background: transparent !important; + border-width: 0 !important; + padding-top: 0 !important; +} + +.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer,.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer + { + height: 3px; +} + +ul.x-tab-strip li { + float: left; + position: relative; + margin-left: 2px; +} + +ul.x-tab-strip li.x-tab-edge { + float: left; + margin: 0 !important; + padding: 0 !important; + border: 0 none !important; + font-size: 1px !important; + line-height: 1px !important; + overflow: hidden; + zoom: 1; + background: transparent !important; + width: 1px; +} + +.x-tab-strip a,.x-tab-strip span,.x-tab-strip em { + display: block; +} + +.x-tab-strip a { + text-decoration: none !important; + -moz-outline: none; + outline: none; + cursor: pointer; +} + +.x-tab-strip-inner { + overflow: hidden; + text-overflow: ellipsis; +} + +.x-tab-strip span.x-tab-strip-text { + white-space: nowrap; + cursor: pointer; + padding: 4px 0; +} + +.x-tab-strip-top .x-tab-with-icon .x-tab-right { + padding-left: 6px; +} + +.x-tab-strip .x-tab-with-icon span.x-tab-strip-text { + padding-left: 20px; + background-position: 0 3px; + background-repeat: no-repeat; +} + +.x-tab-strip-active,.x-tab-strip-active a.x-tab-right { + cursor: default; +} + +.x-tab-strip-active span.x-tab-strip-text { + cursor: default; +} + +.x-tab-strip-disabled .x-tabs-text { + cursor: default; +} + +.x-tab-panel-body { + overflow: hidden; +} + +.x-tab-panel-bwrap { + overflow: hidden; +} + +.ext-ie .x-tab-strip .x-tab-right { + position: relative; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + margin-bottom: -1px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text + { + padding-bottom: 5px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + margin-top: -1px; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text + { + padding-top: 5px; +} + +.x-tab-strip-top .x-tab-right { + background: transparent no-repeat 0 -51px; + padding-left: 10px; +} + +.x-tab-strip-top .x-tab-left { + background: transparent no-repeat right -351px; + padding-right: 10px; +} + +.x-tab-strip-top .x-tab-strip-inner { + background: transparent repeat-x 0 -201px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-right { + background-position: 0 -101px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-left { + background-position: right -401px; +} + +.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner { + background-position: 0 -251px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-right { + background-position: 0 0; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-left { + background-position: right -301px; +} + +.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner { + background-position: 0 -151px; +} + +.x-tab-strip-bottom .x-tab-right { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-left { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background: no-repeat bottom left; +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background: no-repeat bottom right; +} + +.x-tab-strip-bottom .x-tab-left { + padding: 0 10px; +} + +.x-tab-strip-bottom .x-tab-right { + padding: 0; +} + +.x-tab-strip .x-tab-strip-close { + display: none; +} + +.x-tab-strip-closable { + position: relative; +} + +.x-tab-strip-closable .x-tab-left { + padding-right: 19px; +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + opacity: .6; + -moz-opacity: .6; + background-repeat: no-repeat; + display: block; + width: 11px; + height: 11px; + position: absolute; + top: 3px; + right: 3px; + cursor: pointer; + z-index: 2; +} + +.x-tab-strip .x-tab-strip-active a.x-tab-strip-close { + opacity: .8; + -moz-opacity: .8; +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover { + opacity: 1; + -moz-opacity: 1; +} + +.x-tab-panel-body { + border: 1px solid; +} + +.x-tab-panel-body-top { + border-top: 0 none; +} + +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} + +.x-tab-scroller-left { + background: transparent no-repeat -18px 0; + border-bottom: 1px solid; + width: 18px; + position: absolute; + left: 0; + top: 0; + z-index: 10; + cursor: pointer; +} + +.x-tab-scroller-left-over { + background-position: 0 0; +} + +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity = 50); + cursor: default; +} + +.x-tab-scroller-right { + background: transparent no-repeat 0 0; + border-bottom: 1px solid; + width: 18px; + position: absolute; + right: 0; + top: 0; + z-index: 10; + cursor: pointer; +} + +.x-tab-scroller-right-over { + background-position: -18px 0; +} + +.x-tab-scroller-right-disabled { + background-position: 0 0; + opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity = 50); + cursor: default; +} + +.x-tab-scrolling-bottom .x-tab-scroller-left,.x-tab-scrolling-bottom .x-tab-scroller-right + { + margin-top: 1px; +} + +.x-tab-scrolling .x-tab-strip-wrap { + margin-left: 18px; + margin-right: 18px; +} + +.x-tab-scrolling { + position: relative; +} + +.x-tab-panel-bbar .x-toolbar { + border: 1px solid; + border-top: 0 none; + overflow: hidden; + padding: 2px; +} + +.x-tab-panel-tbar .x-toolbar { + border: 1px solid; + border-top: 0 none; + overflow: hidden; + padding: 2px; +} + +.x-tab-strip li .x-tab-image { + position: absolute; + top: 3px; + left: 5px; +} + +.ext-ie8 .x-tab-strip li .x-tab-image,.ext-ie8-compatibility .x-tab-strip li .x-tab-image { + top: 4px; + left: 6px; +} + +.ext-ie8 .x-tab-strip-top .x-tab-right,.ext-ie8-compatibility .x-tab-strip-top .x-tab-right + { + top: 1px; +} + +.ext-strict .ext-ie8 .x-tab-strip-top .x-tab-right,.ext-ie8 .x-tab-panel-header-plain .x-tab-strip-top .x-tab-right,.ext-ie8-compatibility .x-tab-panel-header-plain .x-tab-strip-top .x-tab-right + { + top: 0; +} +.ext-strict .ext-ie7 .x-panel-body { + position: relative !important; +} + +.x-form-field { + margin: 0; +} + +.foo { + padding: 1px; +} + +.foo { + margin: 4px; +} + +.x-form-text,textarea.x-form-field { + padding: 1px 3px; + background: repeat-x 0 0; + border: 1px solid; +} + +.ext-gecko textarea.x-form-field { + padding: 0; +} + +.x-form-text,.ext-ie .x-form-file { + height: 22px; + line-height: 18px; + vertical-align: middle; +} + +.ext-ie6 .x-form-text,.ext-ie7 .x-form-text { + margin: -1px 0; + height: 22px; /* ie quirks */ + line-height: 18px; +} + +.ext-ie8-compatibility .x-form-text { + margin: 0; +} + +.ext-ie textarea.x-form-field { + margin: -1px 0; /* ie bogus margin bug */ +} + +.ext-strict .ext-ie8 textarea.x-form-field,.ext-strict .ext-ie8-compatibility textarea.x-form-field { + margin: 0; +} + +.x-form-field-wrap .x-form-text { + position: relative; +} + +.ext-strict .x-form-text { + height: 18px; +} + +.ext-safari.ext-mac textarea.x-form-field { + margin-bottom: -2px; +} + +.ext-gecko .x-form-text,.ext-ie8 .x-form-text { + padding-top: 2px; + padding-bottom: 0; +} + +textarea { + resize: none; +} + +.x-form-select-one { + height: 20px; + line-height: 18px; + vertical-align: middle; + border: 1px solid; +} + +.x-form-check-wrap { + line-height: 18px; + height: 22px; + white-space: nowrap; +} + +.x-editor .x-form-check-wrap { + border: 1px solid; + padding: 2px; + height: 14px; +} + +.x-editor .x-form-checkbox { + height: 13px; +} + +.x-form-check-group-label { + border-bottom: 1px solid; + margin-bottom: 5px; + padding-left: 3px !important; + float: none !important; +} + +.x-form-field-wrap .x-form-trigger { + width: 17px; + height: 21px; + border: 0; + background: transparent no-repeat 0 0; + cursor: pointer; + border-bottom: 1px solid; + position: absolute; + top: 0; +} + +.ext-safari .x-form-field-wrap .x-form-trigger { + height: 21px; +} + +.ext-strict .ext-safari .x-form-field-wrap .x-form-trigger { + height: 23px; +} + +.ext-strict .ext-safari .x-small-editor .x-form-field-wrap .x-form-trigger { + height: 19px; +} + +.ext-strict .ext-ie8 .x-small-editor .x-form-field-wrap .x-form-trigger { + height: 20px !important; +} + +.ext-strict .ext-gecko .x-small-editor .x-form-field-wrap .x-form-trigger { + height: 21px !important; +} + +.x-form-field-wrap .x-form-date-trigger,.x-form-field-wrap .x-form-clear-trigger,.x-form-field-wrap .x-form-search-trigger + { + cursor: pointer; +} + +.ext-safari .x-form-field-wrap .x-form-trigger,.ext-gecko .x-form-field-wrap .x-form-trigger { + right: 0; +} + +.x-form-field-wrap .x-form-twin-triggers .x-form-trigger { + position: static; + top: auto; + vertical-align: top; +} + +.x-form-field-wrap { + position: relative; + left: 0; + top: 0; + zoom: 1; + white-space: nowrap; + text-align: left; +} + +.x-form-field-wrap .x-form-trigger-over { + background-position: -17px 0; +} + +.x-form-field-wrap .x-form-trigger-click { + background-position: -34px 0; +} + +.x-trigger-wrap-focus .x-form-trigger { + background-position: -51px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-over { + background-position: -68px 0; +} + +.x-trigger-wrap-focus .x-form-trigger-click { + background-position: -85px 0; +} + +.x-trigger-wrap-focus .x-form-trigger { + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-over { + background-position: 0 0 !important; + border-bottom: 1px solid; +} + +.x-item-disabled .x-form-trigger-click { + background-position: 0 0 !important; + border-bottom: 1px solid; +} + +.x-form-focus,textarea.x-form-focus { + border: 1px solid; +} + +.x-form-invalid,textarea.x-form-invalid { + background: repeat-x bottom; + border: 1px solid; +} + +.ext-safari .x-form-invalid { + border: 1px solid; +} + +.x-form-inner-invalid,textarea.x-form-inner-invalid { + background: repeat-x bottom; +} + +.x-editor { + padding: 0; + margin: 0; +} + +.x-form-grow-sizer { + left: -10000px; + padding: 8px 3px; + position: absolute; + visibility: hidden; + top: -10000px; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + zoom: 1; +} + +.x-form-grow-sizer p { + margin: 0 !important; + border: 0 none !important; + padding: 0 !important; +} + +.x-form-item { + display: block; + margin-bottom: 4px; +} + +.x-form-item .x-form-item-label { + display: block; + float: left; + width: 100px; + padding: 3px; + padding-left: 0; + clear: left; + z-index: 2; + position: relative; +} + +.x-form-element { + padding-left: 105px; + position: relative; +} + +.x-form-invalid-msg { + padding: 2px; + padding-left: 18px; + background: transparent no-repeat 0 2px; + line-height: 16px; + width: 200px; +} + +.x-form-label-left .x-form-item-label { + text-align: left; +} + +.x-form-label-right .x-form-item-label { + text-align: right; +} + +.x-form-label-top .x-form-item .x-form-item-label { + width: auto; + float: none; + clear: none; + display: inline; + margin-bottom: 4px; + position: static; +} + +.x-form-label-top .x-form-element { + padding-left: 0; + padding-top: 4px; +} + +.x-form-label-top .x-form-item { + padding-bottom: 4px; +} + +.x-small-editor .x-form-text { + height: 20px; + line-height: 16px; + vertical-align: middle; +} + +.ext-ie6 .x-small-editor .x-form-text,.ext-ie7 .x-small-editor .x-form-text { + height: 20px !important; + line-height: 16px !important; +} + +.ext-strict .x-small-editor .x-form-text { + height: 16px !important; +} + +.ext-strict .ext-ie8 .x-small-editor .x-form-text { + height: 17px !important; +} + +.ext-strict .ext-webkit .x-small-editor .x-form-text { + height: 18px !important; + padding: 0px 3px; +} + +.ext-strict .ext-gecko .x-small-editor .x-form-text { + height: 18px !important; +} + +.ext-strict .ext-gecko .x-edit-grid .x-small-editor .x-form-text { + height:17px !important; +} + +.ext-border-box .x-small-editor .x-form-text { + height: 20px; +} + +.x-small-editor .x-form-select-one { + height: 20px; + line-height: 16px; + vertical-align: middle; +} + +.x-small-editor .x-form-num-field { + text-align: right; +} + +.x-small-editor .x-form-field-wrap .x-form-trigger { + height: 19px; +} + +.x-form-clear { + clear: both; + overflow: hidden; + line-height: 0; + font-size: 0; + height: 0; +} + +.x-form-clear-left { + clear: left; + overflow: hidden; + line-height: 0; + font-size: 0; + height: 0; +} + +.x-form-cb-label { + width: auto !important; + float: none !important; + clear: none !important; + display: inline !important; + margin-left: 4px; +} + +.x-form-column { + float: left; + padding: 0; + margin: 0; + width: 48%; + overflow: hidden; + zoom: 1; +} + +.x-form .x-form-btns-ct .x-btn { + float: right; + clear: none; +} + +.x-form .x-form-btns-ct .x-form-btns td { + border: 0; + padding: 0; +} + +.x-form .x-form-btns-ct .x-form-btns-right table { + float: right; + clear: none; +} + +.x-form .x-form-btns-ct .x-form-btns-left table { + float: left; + clear: none; +} + +.x-form .x-form-btns-ct .x-form-btns-center { + text-align: center; +} + +.x-form .x-form-btns-ct .x-form-btns-center table { + margin: 0 auto; +} + +.x-form .x-form-btns-ct table td.x-form-btn-td { + padding: 3px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-left { + background-position: 0 -147px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-right { + background-position: 0 -168px; +} + +.x-form .x-form-btns-ct .x-btn-focus .x-btn-center { + background-position: 0 -189px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-center { + background-position: 0 -126px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-right { + background-position: 0 -84px; +} + +.x-form .x-form-btns-ct .x-btn-click .x-btn-left { + background-position: 0 -63px; +} + +.x-form-invalid-icon { + width: 16px; + height: 18px; + position: absolute; + left: 0; + top: 0; + display: block; + background: transparent no-repeat 0 2px; +} + +.x-fieldset { + border: 1px solid; + padding: 10px; + margin-bottom: 10px; + display: block; +} + +.ext-ie .x-fieldset legend { + margin-bottom: 10px; +} + +.ext-ie .x-fieldset { + padding-top: 0; + padding-bottom: 10px; +} + +.x-fieldset legend .x-tool-toggle { + margin-right: 3px; + margin-left: 0; + float: left !important; +} + +.x-fieldset legend input { + margin-right: 3px; + float: left !important; + height: 13px; + width: 13px; +} + +fieldset.x-panel-collapsed { + padding-bottom: 0 !important; + border-width: 1px 1px 0 1px !important; + border-left-color: transparent; + border-right-color: transparent; +} + +.ext-ie6 fieldset.x-panel-collapsed { + padding-bottom: 0 !important; + border-width: 1px 0 0 0 !important; + margin-left: 1px; + margin-right: 1px; +} + +fieldset.x-panel-collapsed .x-fieldset-bwrap { + visibility: hidden; + position: absolute; + left: -1000px; + top: -1000px; +} + +.ext-ie .x-fieldset-bwrap { + zoom: 1; +} + +.x-fieldset-noborder { + border: 0px none transparent; +} + +.x-fieldset-noborder legend { + margin-left: -3px; +} + +.ext-ie .x-fieldset-noborder legend { + position: relative; + margin-bottom: 23px; +} + +.ext-ie .x-fieldset-noborder legend span { + position: absolute; + left: 16px; +} + +.ext-gecko .x-form-item { + -moz-outline: none; + outline: 0 none; +} + +.x-hide-label label.x-form-item-label { + display: none !important; +} + +.x-hide-label .x-form-element { + padding-left: 0 !important; +} + +.x-fieldset { + overflow: hidden; +} + +/* make top of checkbox/tools visible in webkit */ +.ext-webkit .x-fieldset-header { + padding-top: 1px; +} + +.x-fieldset-bwrap { + overflow: hidden; + zoom: 1; +} + +.x-fieldset-body { + overflow: hidden; +} + +.x-combo-list .x-combo-selected { + border-color: #a3bae9 !important; +} + +.x-combo-list { + background-color: white !important; +} + +.ext-gecko .x-form-file { + height: inherit !important; +} + +.x-form-check { + background: none !important +} + +.x-form-radio { + background: none !important +} + +.x-form-label { + padding: 2px 3px 3px 0px; + font-size: 12px; +} + +.x-form-label-top .x-form-item { + padding-bottom: 0px; + margin-bottom: 2px; +} + +.ext-safari .x-form-text { + height: 22px; /* safari always same size */ + padding: 0 3px; + /* remove extra top/bottom padding */ +} + +.ext-safari .x-small-editor .x-form-text { + height: 20px; +} + +.x-form-group-label,.x-form-cb-label { + font: normal 12px tahoma, arial, helvetica, sans-serif; + padding-right: 10px; +} + +.x-form-list { + background: #FFFFFF url(../images/default/form/text-bg.gif) repeat-x scroll 0 0; + border: 1px solid #B5B8C8; +} + +/* + * FileUploadField component styles + */ +.x-form-file-wrap { + height: 22px; +} + +.x-form-file-wrap .x-form-file { + position: absolute; + right: 0; + -moz-opacity: 0; + filter: alpha(opacity : 0); + opacity: 0; + z-index: 2; + height: 22px; + top: 0; +} + +.x-form-file-wrap .x-form-file-btn { + position: absolute; + right: 0; + z-index: 1; + top: 0; +} + +.x-form-file-wrap .x-form-file-text { + z-index: 3; + color: #777; +} + +.x-form-invalid-icon { + background-position: 0 0 !important; +} + +.x-triggerfield-noedit { + cursor: pointer; +} + +.ext-webkit .x-form-checkbox:focus { + outline: auto !important; +} + +.x-spinner-field .x-form-twin-triggers .x-form-spinner-up, .x-spinner-field .x-form-twin-triggers .x-form-spinner-down { + height: 10px; + position: absolute; +} + +.ext-strict .ext-safari .x-form-field-wrap .x-form-spinner-up { + height: 10px; +} + +.ext-strict .ext-safari .x-form-field-wrap .x-form-spinner-down { + height: 12px; +} + +.x-spinner-field .x-form-twin-triggers .x-form-spinner-up { + top:0px; +} + +.x-spinner-field .x-form-twin-triggers .x-form-spinner-down { + top:11px; +} + +.x-spinner-field .x-form-twin-triggers { + width: 17px; +} + +.x-spinner-field .x-form-spinner-down { + background-position:0 -12px; +} + +.x-trigger-wrap-focus .x-form-spinner-up { + background-position:-85px 0; +} + +.x-trigger-wrap-focus .x-form-spinner-down { + background-position:-85px -12px; +} + +.x-form-field-wrap .x-form-spinner-overup{ + background-position:-17px 0; +} +.x-form-field-wrap .x-form-spinner-clickup{ + background-position:-34px 0; +} + +.x-trigger-wrap-focus .x-form-spinner-overup{ + background-position:-102px 0; +} + +.x-trigger-wrap-focus .x-form-spinner-clickup{ + background-position:-119px 0; +} + +.x-form-field-wrap .x-form-spinner-overdown{ + background-position:-51px -12px; +} +.x-form-field-wrap .x-form-spinner-clickdown{ + background-position:-68px -12px; +} +.x-trigger-wrap-focus .x-form-spinner-overdown{ + background-position:-136px -12px; +} +.x-trigger-wrap-focus .x-form-spinner-clickdown{ + background-position:-153px -12px; +}.x-btn{ + cursor:pointer; + white-space: nowrap; +} +.x-btn button{ + border:0 none; + background:transparent; + padding-left:3px; + padding-right:3px; + cursor:pointer; + margin:0; + overflow:hidden; + width:auto; + -moz-outline:0 none; + outline:0 none; +} +* html .ext-ie .x-btn button { + width:1px; +} +.ext-ie .x-item-disabled .x-btn-mc img { + filter: alpha(opacity=60); +} +.ext-gecko .x-btn button,.ext-webkit .x-btn button { + padding-left:0; + padding-right:0; +} +.ext-gecko .x-btn button::-moz-focus-inner { + padding:0; +} +.ext-ie .x-btn button { + padding-top:2px; +} +.x-btn td { + padding:0 !important; +} +.x-btn-text { + cursor:pointer; + white-space: nowrap; + padding:0; +} +.x-btn-noicon .x-btn-small .x-btn-text{ + height: 16px; +} +.x-btn-noicon .x-btn-medium .x-btn-text{ + height: 24px; +} +.x-btn-noicon .x-btn-large .x-btn-text{ + height: 32px; +} +.x-btn-icon .x-btn-text{ + background-position: center; + background-repeat: no-repeat; +} +.x-btn-icon .x-btn-small .x-btn-text{ + height: 16px; + width: 16px; +} +.x-btn-icon .x-btn-medium .x-btn-text{ + height: 24px; + width: 24px; +} +.x-btn-icon .x-btn-large .x-btn-text{ + height: 32px; + width: 32px; +} +.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:18px; + height:16px; +} +.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:26px; + height:24px; +} +.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{ + background-position: 0 center; + background-repeat: no-repeat; + padding-left:34px; + height:32px; +} +.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:18px; +} +.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:26px; +} +.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{ + background-position: center 0; + background-repeat: no-repeat; + padding-top:34px; +} +.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:18px; + height:16px; +} +.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:26px; + height:24px; +} +.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{ + background-position: right center; + background-repeat: no-repeat; + padding-right:34px; + height:32px; +} +.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:18px; +} +.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:26px; +} +.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{ + background-position: center bottom; + background-repeat: no-repeat; + padding-bottom:34px; +} +.x-btn-tr i, .x-btn-tl i, .x-btn-mr i, .x-btn-ml i, .x-btn-br i, .x-btn-bl i{ + font-size:1px; + line-height:1px; + width:3px; + display:block; + overflow:hidden; +} +.x-btn-tr i, .x-btn-tl i, .x-btn-br i, .x-btn-bl i{ + height:3px; +} +.x-btn-tl{ + width:3px; + height:3px; + background:no-repeat 0 0; +} +.x-btn-tr{ + width:3px; + height:3px; + background:no-repeat -3px 0; +} +.x-btn-tc{ + height:3px; + background:repeat-x 0 -6px; +} +.x-btn-ml{ + width:3px; + background:no-repeat 0 -24px; +} +.x-btn-mr{ + width:3px; + background:no-repeat -3px -24px; +} +.x-btn-mc{ + background:repeat-x 0 -1096px; + vertical-align: middle; + text-align:center; + padding:0 5px; + cursor:pointer; + white-space:nowrap; +} +.x-btn-bl{ + width:3px; + height:3px; + background:no-repeat 0 -3px; +} +.x-btn-br{ + width:3px; + height:3px; + background:no-repeat -3px -3px; +} +.x-btn-bc{ + height:3px; + background:repeat-x 0 -15px; +} +.x-btn-over .x-btn-tl{ + background-position: -6px 0; +} +.x-btn-over .x-btn-tr{ + background-position: -9px 0; +} +.x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} +.x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} +.x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} +.x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} +.x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} +.x-btn-over .x-btn-br{ + background-position: -9px -3px; +} +.x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} +.ext-webkit .x-btn-focus .x-btn-tl{ + background-position: -6px 0; +} +.ext-webkit .x-btn-focus .x-btn-tr{ + background-position: -9px 0; +} +.ext-webkit .x-btn-focus .x-btn-tc{ + background-position: 0 -9px; +} +.ext-webkit .x-btn-focus .x-btn-ml{ + background-position: -6px -24px; +} +.ext-webkit .x-btn-focus .x-btn-mr{ + background-position: -9px -24px; +} +.ext-webkit .x-btn-focus .x-btn-mc{ + background-position: 0 -2168px; +} +.ext-webkit .x-btn-focus .x-btn-bl{ + background-position: -6px -3px; +} +.ext-webkit .x-btn-focus .x-btn-br{ + background-position: -9px -3px; +} +.ext-webkit .x-btn-focus .x-btn-bc{ + background-position: 0 -18px; +} +.x-btn-click .x-btn-tl, .x-btn-menu-active .x-btn-tl, .x-btn-pressed .x-btn-tl{ + background-position: -12px 0 !important; +} +.x-btn-click .x-btn-tr, .x-btn-menu-active .x-btn-tr, .x-btn-pressed .x-btn-tr{ + background-position: -15px 0 !important; +} +.x-btn-click .x-btn-tc, .x-btn-menu-active .x-btn-tc, .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px !important; +} +.x-btn-click .x-btn-ml, .x-btn-menu-active .x-btn-ml, .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px !important; +} +.x-btn-click .x-btn-mr, .x-btn-menu-active .x-btn-mr, .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px !important; +} +.x-btn-click .x-btn-mc, .x-btn-menu-active .x-btn-mc, .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px !important; +} +.x-btn-click .x-btn-bl, .x-btn-menu-active .x-btn-bl, .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px !important; +} +.x-btn-click .x-btn-br, .x-btn-menu-active .x-btn-br, .x-btn-pressed .x-btn-br{ + background-position: -15px -3px !important; +} +.x-btn-click .x-btn-bc, .x-btn-menu-active .x-btn-bc, .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px !important; +} +.x-btn-disabled *{ + cursor:default !important; +} +.x-btn-mc em.x-btn-arrow { + display:block; + background:transparent no-repeat right center; + padding-right:10px; +} +.x-btn-mc em.x-btn-split { + display:block; + background:transparent no-repeat right center; + padding-right:14px; +} +.x-btn-mc em.x-btn-arrow-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} +.x-btn-mc em.x-btn-split-bottom { + display:block; + background:transparent no-repeat center bottom; + padding-bottom:14px; +} +.x-btn-as-arrow .x-btn-mc em { + display:block; + background:transparent; + padding-bottom:14px; +} +.x-btn-group { + padding:1px; +} +.x-btn-group-header { + padding:2px; + text-align:center; +} +.x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} +.x-btn-group-tl { + background: transparent no-repeat 0 0; + padding-left:3px; + zoom:1; +} +.x-btn-group-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:3px; +} +.x-btn-group-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} +.x-btn-group-bc .x-panel-footer { + zoom:1; +} +.x-btn-group-bl { + background: transparent no-repeat 0 bottom; + padding-left:3px; + zoom:1; +} +.x-btn-group-br { + background: transparent no-repeat right bottom; + padding-right:3px; + zoom:1; +} +.x-btn-group-mc { + border:0 none; + padding:1px 0 0 0; + margin:0; +} +.x-btn-group-mc .x-btn-group-body { + background:transparent; + border: 0 none; +} +.x-btn-group-ml { + background: transparent repeat-y 0 0; + padding-left:3px; + zoom:1; +} +.x-btn-group-mr { + background: transparent repeat-y right 0; + padding-right:3px; + zoom:1; +} +.x-btn-group-bc .x-btn-group-footer { + padding-bottom:6px; +} +.x-panel-nofooter .x-btn-group-bc { + height:3px; + font-size:0; + line-height:0; +} +.x-btn-group-bwrap { + overflow:hidden; + zoom:1; +} +.x-btn-group-body { + overflow:hidden; + zoom:1; +} +.x-btn-group-notitle .x-btn-group-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + height:2px; +} +.x-toolbar{ + border-style:solid; + border-width:0 0 1px 0; + display: block; + padding:2px; + background:repeat-x top left; + position:relative; + left:0; + top:0; + zoom:1; + overflow:hidden; +} +.x-toolbar .x-item-disabled .x-btn-icon { + opacity: .35; + -moz-opacity: .35; + filter: alpha(opacity=35); +} +.x-toolbar td { + vertical-align:middle; +} +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{ + white-space: nowrap; +} +.x-toolbar .x-item-disabled { + cursor:default; + opacity:.6; + -moz-opacity:.6; + filter:alpha(opacity=60); +} + +.x-toolbar .x-item-disabled *{ + cursor:default; +} + +.x-toolbar .x-toolbar-cell { + vertical-align:middle; +} +.x-toolbar .x-btn-tl, .x-toolbar .x-btn-tr, .x-toolbar .x-btn-tc, .x-toolbar .x-btn-ml, .x-toolbar .x-btn-mr, +.x-toolbar .x-btn-mc, .x-toolbar .x-btn-bl, .x-toolbar .x-btn-br, .x-toolbar .x-btn-bc +{ + background-position: 500px 500px; +} +.x-toolbar .x-btn-over .x-btn-tl{ + background-position: -6px 0; +} +.x-toolbar .x-btn-over .x-btn-tr{ + background-position: -9px 0; +} +.x-toolbar .x-btn-over .x-btn-tc{ + background-position: 0 -9px; +} +.x-toolbar .x-btn-over .x-btn-ml{ + background-position: -6px -24px; +} +.x-toolbar .x-btn-over .x-btn-mr{ + background-position: -9px -24px; +} +.x-toolbar .x-btn-over .x-btn-mc{ + background-position: 0 -2168px; +} +.x-toolbar .x-btn-over .x-btn-bl{ + background-position: -6px -3px; +} +.x-toolbar .x-btn-over .x-btn-br{ + background-position: -9px -3px; +} +.x-toolbar .x-btn-over .x-btn-bc{ + background-position: 0 -18px; +} +.x-toolbar .x-btn-click .x-btn-tl, .x-toolbar .x-btn-menu-active .x-btn-tl, .x-toolbar .x-btn-pressed .x-btn-tl{ + background-position: -12px 0; +} +.x-toolbar .x-btn-click .x-btn-tr, .x-toolbar .x-btn-menu-active .x-btn-tr, .x-toolbar .x-btn-pressed .x-btn-tr{ + background-position: -15px 0; +} +.x-toolbar .x-btn-click .x-btn-tc, .x-toolbar .x-btn-menu-active .x-btn-tc, .x-toolbar .x-btn-pressed .x-btn-tc{ + background-position: 0 -12px; +} +.x-toolbar .x-btn-click .x-btn-ml, .x-toolbar .x-btn-menu-active .x-btn-ml, .x-toolbar .x-btn-pressed .x-btn-ml{ + background-position: -12px -24px; +} +.x-toolbar .x-btn-click .x-btn-mr, .x-toolbar .x-btn-menu-active .x-btn-mr, .x-toolbar .x-btn-pressed .x-btn-mr{ + background-position: -15px -24px; +} +.x-toolbar .x-btn-click .x-btn-mc, .x-toolbar .x-btn-menu-active .x-btn-mc, .x-toolbar .x-btn-pressed .x-btn-mc{ + background-position: 0 -3240px; +} +.x-toolbar .x-btn-click .x-btn-bl, .x-toolbar .x-btn-menu-active .x-btn-bl, .x-toolbar .x-btn-pressed .x-btn-bl{ + background-position: -12px -3px; +} +.x-toolbar .x-btn-click .x-btn-br, .x-toolbar .x-btn-menu-active .x-btn-br, .x-toolbar .x-btn-pressed .x-btn-br{ + background-position: -15px -3px; +} +.x-toolbar .x-btn-click .x-btn-bc, .x-toolbar .x-btn-menu-active .x-btn-bc, .x-toolbar .x-btn-pressed .x-btn-bc{ + background-position: 0 -21px; +} +.x-toolbar div.xtb-text{ + padding:2px 2px 0; + line-height:16px; + display:block; +} +.x-toolbar .xtb-sep { + background-position: center; + background-repeat: no-repeat; + display: block; + font-size: 1px; + height: 16px; + width:4px; + overflow: hidden; + cursor:default; + margin: 0 2px 0; + border:0; +} +.x-toolbar .xtb-spacer { + width:2px; +} +.x-tbar-page-number{ + width:24px; + height:14px; +} +.x-paging-info { + position:absolute; + top:5px; + right: 8px; +} +.x-toolbar-ct { + width:100%; +} +.x-panel-tbar, .x-panel-bbar, .x-window-tbar, .x-window-bbar, .x-tab-panel-tbar, .x-tab-panel-bbar, .x-plain-tbar, .x-plain-bbar { + overflow:hidden; + zoom:1; +} +.x-toolbar-more .x-btn-small .x-btn-text{ + height: 16px; + width: 12px; +} +.x-toolbar-more em.x-btn-arrow { + display:inline; + background:transparent; + padding-right:0; +} +.x-toolbar-more .x-btn-mc em.x-btn-arrow { + background-image: none; +} +div.x-toolbar-no-items { + color:gray !important; + padding:5px 10px !important; +}.x-resizable-handle { + position:absolute; + z-index:100; + font-size:1px; + line-height:6px; + overflow:hidden; + filter:alpha(opacity=0); + opacity:0; + zoom:1; +} +.x-resizable-handle-east{ + width:6px; + cursor:e-resize; + right:0; + top:0; + height:100%; +} +.ext-ie .x-resizable-handle-east { + margin-right:-1px; +} +.x-resizable-handle-south{ + width:100%; + cursor:s-resize; + left:0; + bottom:0; + height:6px; +} +.ext-ie .x-resizable-handle-south { + margin-bottom:-1px; +} +.x-resizable-handle-west{ + width:6px; + cursor:w-resize; + left:0; + top:0; + height:100%; +} +.x-resizable-handle-north{ + width:100%; + cursor:n-resize; + left:0; + top:0; + height:6px; +} +.x-resizable-handle-southeast{ + width:6px; + cursor:se-resize; + right:0; + bottom:0; + height:6px; + z-index:101; +} +.x-resizable-handle-northwest{ + width:6px; + cursor:nw-resize; + left:0; + top:0; + height:6px; + z-index:101; +} +.x-resizable-handle-northeast{ + width:6px; + cursor:ne-resize; + right:0; + top:0; + height:6px; + z-index:101; +} +.x-resizable-handle-southwest{ + width:6px; + cursor:sw-resize; + left:0; + bottom:0; + height:6px; + z-index:101; +} +.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{ + filter:alpha(opacity=100); + opacity:1; +} +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-position: left; +} +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-position: top; +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-position: top left; +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-position:bottom right; +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-position: bottom left; +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-position: top right; +} +.x-resizable-proxy{ + border: 1px dashed; + position:absolute; + overflow:hidden; + display:none; + left:0; + top:0; + z-index:50000; +} +.x-resizable-overlay{ + width:100%; + height:100%; + display:none; + position:absolute; + left:0; + top:0; + z-index:200000; + -moz-opacity: 0; + opacity:0; + filter: alpha(opacity=0); +} +.x-grid3 { + position: relative; + overflow: hidden; +} + +.x-grid-panel { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.x-grid-panel .x-panel-body { + overflow: hidden !important; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border: 1px solid; +} + +.x-grid3 .x-grid3-row-table, .x-grid3 .x-grid3-summary-table { + table-layout: fixed; +} + +.x-grid3-viewport { + overflow: hidden; +} + +.x-grid3-hd-row .x-grid3-hd,.x-grid3-row .x-grid3-hd,.x-grid3-summary-row .x-grid3-hd { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.x-grid3-summary-row { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore; + outline: 0 none; +} + +.x-grid3-row td.x-grid3-cell,.x-grid3-summary-row td.x-grid3-cell { + line-height: 14px; + vertical-align: top; + padding-left: 1px; + padding-right: 1px; + -moz-outline: none; + outline: 0 none; +} + +.x-grid3-hd-row .x-grid3-hd { + line-height: 15px; + vertical-align: middle; + border-left: 1px solid; + border-right: 1px solid; +} + +.x-grid3-hd-row .x-grid3-marker-hd { + padding: 3px; +} + +.x-grid3-row .x-grid3-marker { + padding: 3px; +} + +.x-grid3-cell-inner,.x-grid3-hd-inner { + overflow: hidden; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + padding: 3px 3px 3px 5px; + white-space: nowrap; +} + +.x-grid3-hd-inner { + position: relative; + cursor: inherit; + padding: 4px 3px 4px 5px; + vertical-align: middle; +} + +.x-grid3-row-body { + white-space: normal; + font-size: 11px; +} + +.x-grid3-body-cell { + -moz-outline: 0 none; + outline: 0 none; +} + +.ext-ie .x-grid3-cell-inner,.ext-ie .x-grid3-hd-inner { + width: 100%; +} + +.ext-strict .x-grid3-cell-inner,.ext-strict .x-grid3-hd-inner { + width: auto; +} + +.x-grid-row-loading { + background: no-repeat center center; +} + +.x-grid-page { + overflow: hidden; +} + +.x-grid3-row { + cursor: default; + border: 1px solid; + width: 100%; +} + +.x-grid3-row-over { + border: 1px solid; + background: repeat-x left top; +} + +.x-grid3-resize-proxy { + width: 1px; + left: 0; + cursor: e-resize; + cursor: col-resize; + position: absolute; + top: 0; + height: 100px; + overflow: hidden; + visibility: hidden; + border: 0 none; + z-index: 7; +} + +.x-grid3-resize-marker { + width: 1px; + left: 0; + position: absolute; + top: 0; + height: 100px; + overflow: hidden; + visibility: hidden; + border: 0 none; + z-index: 7; +} + +.x-grid3-focus { + position: absolute; + left: 0; + top: 0; + width: 1px; + height: 1px; + line-height: 1px; + font-size: 1px; + -moz-outline: 0 none; + outline: 0 none; + -moz-user-select: text; + -khtml-user-select: text; + -webkit-user-select: ignore; +} + +.x-grid3-header { + background: repeat-x 0 bottom; + cursor: default; + zoom: 1; + padding: 0px 0 0 0; +} + +.x-grid3-header-pop { + border-left: 1px solid; + float: right; + clear: none; +} + +.x-grid3-header-pop-inner { + border-left: 1px solid; + width: 14px; + height: 19px; + background: transparent no-repeat center center; +} + +.ext-ie .x-grid3-header-pop-inner { + width: 15px; +} + +.ext-strict .x-grid3-header-pop-inner { + width: 14px; +} + +.x-grid3-header-inner { + overflow: hidden; + zoom: 1; + float: left; +} + +.x-grid3-header-offset { + padding-left: 1px; +} + +td.x-grid3-hd-over,td.sort-desc,td.sort-asc,td.x-grid3-hd-menu-open { + border-left: 1px solid; + border-right: 1px solid; +} + +td.x-grid3-hd-over .x-grid3-hd-inner,td.sort-desc .x-grid3-hd-inner,td.sort-asc .x-grid3-hd-inner,td.x-grid3-hd-menu-open .x-grid3-hd-inner + { + background: repeat-x left bottom; +} + +.x-grid3-sort-icon { + background-repeat: no-repeat; + display: none; + height: 4px; + width: 13px; + margin-left: 3px; + vertical-align: middle; +} + +.sort-asc .x-grid3-sort-icon,.sort-desc .x-grid3-sort-icon { + display: inline; +} + +.ext-strict .ext-ie .x-grid3-header-inner,.ext-strict .ext-ie6 .x-grid3-hd { + position: relative; +} + +.ext-strict .ext-ie6 .x-grid3-hd-inner { + position: static; +} + +.x-grid3-body { + zoom: 1; +} + +.x-grid3-scroller { + overflow: auto; + zoom: 1; + position: relative; +} + +.x-grid3-cell-text,.x-grid3-hd-text { + display: block; + padding: 3px 5px 3px 5px; +} + +.x-grid3-split { + background-position: center; + background-repeat: no-repeat; + cursor: e-resize; + cursor: col-resize; + display: block; + font-size: 1px; + height: 16px; + overflow: hidden; + position: absolute; + top: 2px; + width: 6px; + z-index: 3; +} + +.x-dd-drag-proxy .x-grid3-hd-inner { + background: repeat-x left bottom; + width: 120px; + padding: 3px; + border: 1px solid; + overflow: hidden; +} + +.col-move-top,.col-move-bottom { + width: 9px; + height: 9px; + position: absolute; + top: 0; + line-height: 1px; + font-size: 1px; + overflow: hidden; + visibility: hidden; + z-index: 20000; + background: transparent no-repeat left top; +} + +.x-grid3-row-selected { + border: 1px dotted; +} + +.x-grid3-locked td.x-grid3-row-marker,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker { + background: repeat-x 0 bottom !important; + vertical-align: middle !important; + padding: 0; + border-top: 1px solid; + border-bottom: none !important; + border-right: 1px solid !important; + text-align: center; +} + +.x-grid3-locked td.x-grid3-row-marker div,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div { + padding: 0 4px; + text-align: center; +} + +.x-grid3-dirty-cell { + background: transparent no-repeat 0 0; +} + +.x-grid3-invalid-cell { + background: repeat-x bottom; +} + +.x-grid3-topbar,.x-grid3-bottombar { + overflow: hidden; + display: none; + zoom: 1; + position: relative; +} + +.x-grid3-topbar .x-toolbar { + border-right: 0 none; +} + +.x-grid3-bottombar .x-toolbar { + border-right: 0 none; + border-bottom: 0 none; + border-top: 1px solid; +} + +.x-props-grid .x-grid3-cell { + padding: 1px; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner { + background: transparent repeat-y -16px !important; + padding-left: 12px; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name { + padding: 1px; + padding-right: 0; + border: 0 none; + border-right: 1px solid; +} + +.x-grid3-col-dd { + border: 0 none; + padding: 0; + background: transparent; +} + +.x-dd-drag-ghost .x-grid3-dd-wrap { + padding: 1px 3px 3px 1px; +} + +.x-grid3-hd { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore; +} + +.x-grid3-hd-btn { + display: none; + position: absolute; + width: 14px; + background: no-repeat left center; + right: 0; + top: 0; + z-index: 2; + cursor: pointer; + outline: none; +} + +.x-grid3-hd-over .x-grid3-hd-btn,.x-grid3-hd-menu-open .x-grid3-hd-btn { + display: block; +} + +a.x-grid3-hd-btn:hover { + background-position: -14px center; +} + +.x-grid3-body .x-grid3-td-expander { + background: transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner { + padding: 0 !important; + height: 100%; +} + +.x-grid3-row-expander { + width: 100%; + height: 18px; + background-position: 4px 2px; + background-repeat: no-repeat; + background-color: transparent; +} + +.x-grid3-row-collapsed .x-grid3-row-expander { + background-position: 4px 2px; +} + +.x-grid3-row-expanded .x-grid3-row-expander { + background-position: -21px 2px; +} + +.x-grid3-row-collapsed .x-grid3-row-body { + display: none !important; +} + +.x-grid3-row-expanded .x-grid3-row-body { + display: block !important; +} + +.x-grid3-body .x-grid3-td-checker { + background: transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner,.x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner { + padding: 0 !important; + height: 100%; +} + +.x-grid3-group-checker { + float: left; +} + +.x-grid3-row-checker,.x-grid3-hd-checker { + width: 100%; + height: 18px; + background-position: 2px 2px; + background-repeat: no-repeat; + background-color: transparent; +} + +.x-grid3-hd-checker { + padding-bottom: 0px !important; +} + +.x-grid3-row .x-grid3-row-checker { + background-position: 2px 2px; +} + +.x-grid3-row-selected .x-grid3-row-checker,.x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker + { + background-position: -23px 2px; +} + +.x-grid3-hd-checker { + background-position: 2px 3px; +} + +.x-grid3-hd-checker-on .x-grid3-hd-checker { + background-position: -23px 3px; +} + +.x-grid3-body .x-grid3-td-numberer { + background: transparent repeat-y right; +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + padding: 3px 5px 0 0 !important; + text-align: right; +} + +.x-grid3-body .x-grid3-td-row-icon { + background: transparent repeat-y right; + vertical-align: top; + text-align: center; +} + +.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner { + padding: 0 !important; + background-position: center center; + background-repeat: no-repeat; + width: 16px; + height: 16px; + margin-left: 2px; + margin-top: 3px; +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander + { + background: transparent repeat-y right; +} + +.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner { + padding: 1px 0 0 0 !important; +} + +.x-grid3-check-col { + width: 100%; + height: 16px; + background-position: center center; + background-repeat: no-repeat; + background-color: transparent; +} + +.x-grid3-check-col-on { + width: 100%; + height: 16px; + background-position: center center; + background-repeat: no-repeat; + background-color: transparent; +} + +.x-grid-group,.x-grid-group-body,.x-grid-group-hd { + zoom: 1; +} + +.x-grid-group-hd { + border-bottom: 2px solid; + cursor: pointer; + padding-top: 6px; +} + +.x-grid-group-hd .x-grid-group-div { + background: transparent no-repeat 3px -47px; + padding: 4px 4px 4px 17px; +} + +.x-grid-group-collapsed .x-grid-group-hd .x-grid-group-div { + background-position: 3px 3px; +} + +.x-grid-group-collapsed .x-grid-group-body { + display: none; +} + +.x-grid-empty { + padding: 10px; +} + +.ext-ie7 .x-grid-panel .x-panel-bbar { + position: relative; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + padding-right: 0; + border-right: 1px solid; +} + +.ext-ie6 .x-grid3-header { + position: relative; +} + +.x-grid3-check-col-disabled { + width: 100%; + height: 16px; + background-position: center center; + background-repeat: no-repeat; +} + +.x-row-editor-header { + height: 2px; + overflow: hidden; +} + +.x-row-editor-footer { + height: 2px; + overflow: hidden; +} + +.ext-ie .x-row-editor-footer { + margin-top: -1px; +} + +.x-row-editor-body { + overflow: hidden; + zoom: 1; + padding-top: 2px; +} + +.x-row-editor .x-btns { + position: absolute; + top: 28px; + left: 20px; + padding-left: 5px; +} + +.x-row-editor .x-btns .x-plain-bwrap { + padding-right: 5px; +} + +.x-row-editor .x-btns .x-plain-body { + height: 31px; +} + +.x-row-editor .x-btns .x-table-layout-cell { + padding: 3px; +} + +.x-grid3-footer { + background: #f7f7f7 none repeat scroll 0 0; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + display: block; + overflow: hidden; + position: relative; +} + +.x-grid3-footer-row { + border: 1px solid #EEEEEE; + background-color: #f7f7f7; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore; + cursor: default; +} + +.x-grid3-footer-row td { + line-height: 13px; + vertical-align: top; + padding-left: 1px; + padding-right: 1px; + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-ie6 .x-grid3 .x-editor .x-form-text,.ext-ie7 .x-grid3 .x-editor .x-form-text { + top: -1px; +} + +.ext-ie8-compatibility .x-grid3 .x-editor .x-form-text { + top: 0; +} + +.x-grid-panel .x-livegrid-scroller { + z-index: 1; + position: absolute; + right: 0px; + width: 18px; + overflow-y: scroll; + overflow-x: hidden; +} + +.x-grid3-group-checker div { + width: 14px; + height: 18px; + background-position: -1 -2px; + background-repeat: no-repeat; + background-color: transparent; +} + +.x-grid-group-hd .x-grid3-group-check { + background-image: url(../images/default/menu/checked.gif); +} + +.x-grid-group-hd .x-grid3-group-uncheck { + background-image: url(../images/default/menu/unchecked.gif); +} + +.x-grid3-hd-row .x-filtered-column { + font-style: italic !important; + font-weight: bold !important; +} + +.ext-strict .ext-gecko .x-inline-editor .x-small-editor .x-form-text { + height: 18px !important; +} +.x-dd-drag-proxy{ + position:absolute; + left:0; + top:0; + visibility:hidden; + z-index:15000; +} +.x-dd-drag-ghost{ + -moz-opacity: 0.85; + opacity:.85; + filter: alpha(opacity=85); + border: 1px solid; + padding:3px; + padding-left:20px; + white-space:nowrap; +} +.x-dd-drag-repair .x-dd-drag-ghost{ + -moz-opacity: 0.4; + opacity:.4; + filter: alpha(opacity=40); + border:0 none; + padding:0; + background-color:transparent; +} +.x-dd-drag-repair .x-dd-drop-icon{ + visibility:hidden; +} +.x-dd-drop-icon{ + position:absolute; + top:3px; + left:3px; + display:block; + width:16px; + height:16px; + background-color:transparent; + background-position: center; + background-repeat: no-repeat; + z-index:1; +} +.x-view-selector { + position:absolute; + left:0; + top:0; + width:0; + border:1px dotted; + opacity: .5; + -moz-opacity: .5; + filter:alpha(opacity=50); + zoom:1; +} + +.x-dd-cursor { + cursor: default !important; +} + +.x-insert-bar { + position: absolute; + + z-index: 99999; +} + +.x-insert-bar td { + line-height: 1px; + font-size: 1px; +} + +.x-insert-left { + background: url(../images/gxt/dd/insert-bg.gif) no-repeat; +} + +.x-insert-mid { + background: url(../images/gxt/dd/insert-bg.gif) repeat-x 0 -12px; +} + +.x-insert-right { + background: url(../images/gxt/dd/insert-bg.gif) no-repeat 0px -6px; +} +.tree-folder { + background: url(../images/gxt/icons/folder-closed.gif) no-repeat center + left !important; +} + +.tree-folder-open { + background: url(../images/gxt/icons/folder.gif) no-repeat center left + !important; +} + +.my-tree { + cursor: default; + font-size: 11px; + -moz-outline: none; + -moz-user-focus: none; +} + +.my-root-item { + padding: 4px; +} + +.my-tree-item,.my-tree-item table,.my-tree-item table td { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; + font-size: 11px; +} + +.my-tree-item td { + height: 19px; +} + +.my-tree-indent { + line-height: 1px; + font-size: 1px; +} + +.my-tree-joint div { + width: 15px; + height: 19px; + line-height: 1px; + font-size: 1px; +} + +.my-tree-left,.my-tree-left div,.my-tree-right { + line-height: 1px; + font-size: 1px; + width: 3px; +} + +.my-tree-left div,.my-tree-right div { + width: 3px; +} + +.my-tree-item,.my-treeitem-wrap { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tree-check div { + width: 17px; + height: 17px; + line-height: 1px; + font-size: 1px; +} + +.my-tree-icon div { + width: 16px; + height: 17px; + cursor: pointer; + background-repeat: no-repeat; + background-position: center; +} + +.my-tree-item-text span { + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 12px; + white-space: nowrap; + padding-left: 3px; + padding-right: 3px; + display: block; + height: 15px; + cursor: pointer; +} + +.my-tree-over .my-tree-left { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left + -57px; +} + +.my-tree-over .my-tree-right { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right + -76px; +} + +.my-tree-over .my-tree-check,.my-tree-over .my-tree-icon,.my-tree-over .my-tree-item-text + { + background: url(../images/gxt/shared/select-19-bg.gif) left -95px; +} + +.my-tree-sel .my-tree-left { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left + 0px; +} + +.my-tree-sel .my-tree-right { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right + -19px; +} + +.my-tree-sel .my-tree-check,.my-tree-sel .my-tree-icon,.my-tree-sel .my-tree-item-text + { + background: url(../images/gxt/shared/select-19-bg.gif) left -38px; +} + +.my-tree-drop .my-tree-left { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left + -115px; +} + +.my-tree-drop .my-tree-right { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right + -133px; +} + +.my-tree-drop .my-tree-check,.my-tree-drop .my-tree-icon,.my-tree-drop .my-tree-item-text + { + background: url(../images/gxt/shared/select-19-bg.gif) left -152px; +} + +.my-tree-close { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px + 1px; +} + +.my-tree-open { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px + -32px; +} + +.my-tree-joint-over .my-tree-open { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px + -48px; +} + +.my-tree-joint-over .my-tree-close { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px + -15px; +} + +.my-tree-notchecked { + background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 50%; +} + +.my-tree-checked { + background: url(../images/gxt/tree/checked.gif) no-repeat 0px 50%; +} + +.my-tree-loading .tree-folder { + background: url(../images/gxt/icons/wait.gif) no-repeat 0px -1px + !important; +} + +.my-tree-loading .my-tree-item-text span { + font-style: italic; +} + +.x-ftree-selected .x-ftree-text { + background-color: #d9e8fb; +} + +.x-ftree-node-over .x-ftree-text { + background-color: #eee; +} + +.x-ftree-item { + line-height: 18px; +} + +.x-ftree-joint,.x-ftree-icon { + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-position: center; + background-repeat: no-repeat; +} + +.x-ftree-text { + color: black; + font: normal 11px arial, tahoma, helvetica, sans-serif; + white-space: nowrap; + text-decoration: none; + color: black; + padding-left: 4px; + vertical-align: middle; + line-height: 18px; + padding: 2px 4px 4px 4px; +} + +/* some default icons for leaf/folder */ +.x-ftree-expanded .x-ftree-icon { + background-image: url(../images/default/tree/folder-open.gif); +} + +.x-ftree-leaf .x-ftree-icon { + background-image: url(../images/default/tree/leaf.gif); +} + +.x-ftree-collapsed .x-ftree-icon { + background-image: url(../images/gxt/icons/folder-closed.gif); +} + +/* Arrows */ +.x-ftree-arrows .x-ftree-joint { + background: transparent; +} + +.x-ftree-arrows .x-ftree-joint-plus { + background: transparent url(../images/default/tree/arrows.gif) no-repeat + 0 0; +} + +.x-ftree-arrows .x-ftree-joint-minus { + background: transparent url(../images/default/tree/arrows.gif) no-repeat + -16px 0; +} + +.x-ftree-arrows .x-ftree-ec-over .x-ftree-joint-plus { + background-position: -32px 0; +} + +.x-ftree-arrows .x-ftree-ec-over .x-ftree-joint-minus { + background-position: -48px 0; +} + +.x-ftree2-highlightrow { + border: 1px dotted #545352; +} + +.x-ftree2-selected { + background-color: #d9e8fb !important; +} + +.x-ftree2-node-over { + background-color: #eee; +} + +.x-ftree2-node-drop { + background-color: #defadc; +} + +.x-ftree2-joint,.x-ftree2-icon { + border: 0 none; + height: 18px; + margin: 0; + padding: 0; + vertical-align: top; + width: 16px; + background-position: center; + background-repeat: no-repeat; +} + +.x-ftree2-joint div { + width: 16px; +} + +.x-ftree2-el-ct { + display: none; +} + +.x-ftree2-node { + padding-bottom: 1px; +} + +.x-ftree2-text { + vertical-align: middle !important; + white-space: nowrap !important; +} + +.x-ftree2-text span { + color: black; + font: normal 11px arial, tahoma, helvetica, sans-serif; + white-space: nowrap; + text-decoration: none; + color: black; + padding: 2px 4px 2px 1px; + display: block; +} + +.ext-ie .x-ftree2-text span { + padding-left: 3px; +} + +.x-ftree2-check { + width: 17px; +} + +.x-ftree2-check div { + width: 17px; + height: 17px; +} + +/* some default icons for leaf/folder */ +.x-ftree2-expanded .x-ftree2-icon { + background-image: url(../images/default/tree/folder-open.gif); +} + +.x-ftree2-leaf .x-ftree2-icon { + background-image: url(../images/default/tree/leaf.gif); +} + +.x-ftree2-collapsed .x-ftree2-icon { + background-image: url(../images/gxt/icons/folder-closed.gif); +} + +/* Arrows */ +.x-ftree2-arrows .x-ftree2-joint { + background: transparent; +} + +.x-ftree2-arrows .x-ftree2-joint-plus { + background: transparent url(../images/default/tree/arrows.gif) no-repeat + 0 0; +} + +.x-ftree2-arrows .x-ftree2-joint-minus { + background: transparent url(../images/default/tree/arrows.gif) no-repeat + -16px 0; +} + +.x-ftree2-arrows .x-ftree2-ec-over .x-ftree2-joint-plus { + background-position: -32px 0; +} + +.x-ftree2-arrows .x-ftree2-ec-over .x-ftree2-joint-minus { + background-position: -48px 0; +} + +.x-treegrid { + -moz-outline: none; + -moz-user-focus: none; + outline: 0 none; +} + +.x-treegrid .x-treegrid-column .x-grid3-cell-inner { + padding: 0px !important; +} + +.x-tree3 { + cursor: default; + -moz-outline: none; + -moz-user-focus: none; + outline: 0 none; +} + +.ext-strict .ext-gecko .x-tree3, .ext-strict .ext-webkit .x-tree3 { + padding-bottom: 1px; +} + +.x-tree3-node { + cursor: default; +} + +.x-tree3-el { + white-space: nowrap; + height: 21px; + position: relative; +} + +.x-tree3-node-text { + white-space: nowrap; + line-height: 11px; + text-decoration: none; + padding: 0 0 0 3px; + position: relative; + top: -4px; +} + +.x-tree3-node-ct { + display: none; +} + +.x-tree3-node-text-widget { + position: static !important; + padding: 0px !important; +}.x-date-picker { + border: 1px solid; + border-top:0 none; + position:relative; + -moz-outline:0 none; + outline:0 none; +} +.x-date-picker a { + -moz-outline:0 none; + outline:0 none; +} +.x-date-inner, .x-date-inner td, .x-date-inner th{ + border-collapse:separate; +} +.x-date-middle,.x-date-left,.x-date-right { + background: repeat-x 0 -83px; + overflow:hidden; +} +.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr, +.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr, +.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{ + background:transparent !important; + vertical-align:middle; +} +.x-date-middle .x-btn-mc em.x-btn-arrow { + background:transparent no-repeat right 0; +} +.x-date-right, .x-date-left { + width:18px; +} +.x-date-right{ + text-align:right; +} +.x-date-middle { + padding-top:2px; + padding-bottom:2px; + width:130px; +} +.x-date-right a, .x-date-left a{ + display:block; + width:16px; + height:16px; + background-position: center; + background-repeat: no-repeat; + cursor:pointer; + -moz-opacity: 0.6; + opacity:.6; + filter: alpha(opacity=60); +} +.x-date-right a:hover, .x-date-left a:hover{ + -moz-opacity: 1; + opacity:1; + filter: alpha(opacity=100); +} +.x-date-right a { + margin-right:2px; + text-decoration:none !important; +} +.x-date-left a{ + margin-left:2px; + text-decoration:none !important; +} +table.x-date-inner { + width:100%; + table-layout:fixed; +} +.x-date-inner th { + width:25px; +} +.x-date-inner th { + background: repeat-x left top; + text-align:right !important; + border-bottom: 1px solid; + cursor:default; + padding:0; + border-collapse:separate; +} +.x-date-inner th span { + display:block; + padding:2px; + padding-right:7px; +} +.x-date-inner td { + border: 1px solid; + text-align:right; + padding:0; +} +.x-date-inner a { + padding:2px 5px; + display:block; + text-decoration:none; + text-align:right; + zoom:1; +} +.x-date-inner .x-date-active{ + cursor:pointer; + color:black; +} +.x-date-inner .x-date-selected a{ + background: repeat-x left top; + border:1px solid; + padding:1px 4px; +} +.x-date-inner .x-date-today a{ + border: 1px solid; + padding:1px 4px; +} +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + text-decoration:none !important; +} +.x-date-bottom { + padding:4px; + border-top: 1px solid; + background: repeat-x left top; +} +.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{ + text-decoration:none !important; +} +.x-date-inner .x-date-disabled a { + cursor:default; +} +.x-date-mmenu .x-menu-item { + padding:1px 24px 1px 4px; + white-space: nowrap; +} +.x-date-mmenu .x-menu-item .x-menu-item-icon { + width:10px; + height:10px; + margin-right:5px; + background-position:center -4px !important; +} +.x-date-mp { + position:absolute; + left:0; + top:0; + display:none; +} +.x-date-mp td { + padding:2px; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} +td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn { + border: 0 none; + text-align:center; + vertical-align: middle; + width:25%; +} +.x-date-mp-ok { + margin-right:3px; +} +.x-date-mp-btns button { + text-decoration:none; + text-align:center; + text-decoration:none !important; + border:1px solid; + padding:1px 3px 1px; + cursor:pointer; +} +.x-date-mp-btns { + background: repeat-x left top; +} +.x-date-mp-btns td { + border-top: 1px solid; + text-align:center; +} +td.x-date-mp-month a,td.x-date-mp-year a { + display:block; + padding:2px 4px; + text-decoration:none; + text-align:center; +} +td.x-date-mp-month a:hover,td.x-date-mp-year a:hover { + text-decoration:none; + cursor:pointer; +} +td.x-date-mp-sel a { + padding:1px 3px; + background: repeat-x left top; + border:1px solid; +} +.x-date-mp-ybtn a { + overflow:hidden; + width:15px; + height:15px; + cursor:pointer; + background:transparent no-repeat; + display:block; + margin:0 auto; +} +.x-date-mp-ybtn a.x-date-mp-next { + background-position:0 -120px; +} +.x-date-mp-ybtn a.x-date-mp-next:hover { + background-position:-15px -120px; +} +.x-date-mp-ybtn a.x-date-mp-prev { + background-position:0 -105px; +} +.x-date-mp-ybtn a.x-date-mp-prev:hover { + background-position:-15px -105px; +} +.x-date-mp-ybtn { + text-align:center; +} +td.x-date-mp-sep { + border-right:1px solid; +} + +.x-date-picker, .x-date-picker a { + font-size: 11px; +} + +.x-date-right-icon { + background-image: url(../images/default/shared/right-btn.gif); + margin-right: 2px; + text-decoration: none !important; +} + +.x-date-left-icon { + background-image: url(../images/default/shared/left-btn.gif); + margin-left: 4px; + text-decoration: none !important; +} + +.x-date-days { + table-layout: fixed; + width: 100%; +} + +.x-date-days td { + width: 25px; + border: none; +} + +.x-date-days td span { + display: block; + padding: 2px 7px 2px 2px; +} + +.x-date-days td { + background: #DFECFB url(../images/default/shared/glass-bg.gif) repeat-x scroll left top; + border-bottom: 1px solid #A3BAD9; + border-collapse: separate; + color: #233D6D; + cursor: default; + font-family: arial, helvetica, tahoma, sans-serif; + font-size: 10px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: normal; + padding: 0pt; + text-align: right !important; +} + +.x-date-picker .x-date-header { + background: url(../images/default/shared/hd-sprite.gif) repeat-x 0 -83px; + height: 22px; + left: 10px; + top: 10px; + width: 157px; +} + +.x-date-header .x-btn .x-btn-text { + color: #fff; +} + +.x-date-picker-footer { + width: 100%; +} + +.x-date-picker-footer td { + text-align: center; +} + +.x-date-left { + background: transparent url(../images/default/shared/hd-sprite.gif) repeat-x scroll 0pt -83px; + color: #FFFFFF; + font-family: "sans serif", tahoma, verdana, helvetica; + font-size: 11px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: bold; + line-height: normal; + overflow: hidden; +} + +.x-date-inner .x-date-active-hover { + background: #ddecfe !important; +}.x-tip{ + position: absolute; + top: 0; + left:0; + visibility: hidden; + z-index: 20000; + border:0 none; +} +.x-tip .x-tip-close{ + height: 15px; + float:right; + width: 15px; + margin:0 0 2px 2px; + cursor:pointer; + display:none; +} +.x-tip .x-tip-tc { + background: transparent no-repeat 0 -62px; + padding-top:3px; + overflow:hidden; + zoom:1; +} +.x-tip .x-tip-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + overflow:hidden; + zoom:1; +} +.x-tip .x-tip-tr { + background: transparent no-repeat right 0; + padding-right:6px; + overflow:hidden; + zoom:1; +} +.x-tip .x-tip-bc { + background: transparent no-repeat 0 -121px; + height:3px; + overflow:hidden; +} +.x-tip .x-tip-bl { + background: transparent no-repeat 0 -59px; + padding-left:6px; + zoom:1; +} +.x-tip .x-tip-br { + background: transparent no-repeat right -59px; + padding-right:6px; + zoom:1; +} +.x-tip .x-tip-mc { + border:0 none; +} +.x-tip .x-tip-ml { + background: no-repeat 0 -124px; + padding-left:6px; + zoom:1; +} +.x-tip .x-tip-mr { + background: transparent no-repeat right -124px; + padding-right:6px; + zoom:1; +} +.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc { + font-size:0; + line-height:0; +} +.ext-border-box .x-tip .x-tip-header,.ext-border-box .ext-ie .x-tip .x-tip-tc { + line-height:1px; +} +.x-tip .x-tip-header-text { + padding:0; + margin:0 0 2px 0; +} +.x-tip .x-tip-body { + margin:0 !important; + line-height:14px; + padding:0; +} +.x-tip .x-tip-body .loading-indicator { + margin:0; +} +.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text { + cursor:move; +} +.x-form-invalid-tip .x-tip-tc { + background: repeat-x 0 -12px; + padding-top:6px; +} +.x-form-invalid-tip .x-tip-bc { + background: repeat-x 0 -18px; + height:6px; +} +.x-form-invalid-tip .x-tip-bl { + background: no-repeat 0 -6px; +} +.x-form-invalid-tip .x-tip-br { + background: no-repeat right -6px; +} +.x-form-invalid-tip .x-tip-body { + padding:2px; +} +.x-form-invalid-tip .x-tip-body { + padding-left:24px; + background:transparent no-repeat 2px 2px; +} +.x-tip-anchor { + position: absolute; + width: 9px; + height: 10px; + overflow:hidden; + background: transparent no-repeat 0 0; + zoom:1; +} +.x-tip-anchor-bottom { + background-position: -9px 0; +} +.x-tip-anchor-right { + background-position: -18px 0; + width: 10px; +} +.x-tip-anchor-left { + background-position: -28px 0; + width: 10px; +} +.x-menu { + border: 1px solid; + z-index: 15000; + zoom: 1; + background: repeat-y; + -moz-outline: none; + outline: 0 none; +} + +.x-menu a { + text-decoration: none !important; +} + +.ext-ie .x-menu { + zoom: 1; + overflow: hidden; +} + +.x-menu-list { + padding: 2px; + background: transparent; + border: 0 none; + overflow: hidden; + overflow-y: hidden; +} + +.ext-strict .ext-ie .x-menu-list { + position: relative; +} + +.x-menu x-menu-sep-li { + font-size: 1px; + line-height: 1px; +} + +.x-menu-list-item { + white-space: nowrap; + display: block; + padding: 1px; +} + +.x-menu-item { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore +} + +.x-menu-item-arrow { + background: transparent no-repeat right; +} + +.x-menu-sep { + display: block; + font-size: 1px; + line-height: 1px; + margin: 2px 3px; + border-bottom: 1px solid; + overflow: hidden; +} + +.x-menu-focus { + position: absolute; + left: -1px; + top: -1px; + width: 1px; + height: 1px; + line-height: 1px; + font-size: 1px; + -moz-outline: 0 none; + outline: 0 none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore + overflow: hidden; + display: block; +} + +a.x-menu-item { + cursor: pointer; + display: block; + line-height: 16px; + outline-color: -moz-use-text-color; + outline-style: none; + outline-width: 0; + padding: 3px 21px 3px 27px; + position: relative; + text-decoration: none; + white-space: nowrap; +} + +.x-menu-item-active { + border-style: solid; + border-width: 1px; + padding: 0; +} + +.x-menu-item-icon { + border: 0 none; + height: 16px; + padding: 0; + vertical-align: top; + width: 16px; + position: absolute; + left: 3px; + top: 3px; + margin: 0; + background-position: center; +} + +.ext-ie .x-menu-item-icon { + left: -24px; +} + +.ext-strict .x-menu-item-icon { + left: 3px; +} + +.ext-ie6 .x-menu-item-icon { + left: -24px; +} + +.ext-ie .x-menu-item-icon { + vertical-align: middle; +} + +.x-date-menu .x-menu-list { + padding: 0; +} + +.x-menu-date-item { + padding: 0; +} + +.x-menu .x-color-palette,.x-menu .x-date-picker { + margin-left: 26px; + margin-right: 4px; +} + +.x-menu .x-date-picker { + border: 1px solid; + margin-top: 2px; + margin-bottom: 2px; +} + +.x-menu-plain .x-color-palette,.x-menu-plain .x-date-picker { + margin: 0; + border: 0 none; +} + +.x-date-menu { + padding: 0 !important; +} + +.x-cycle-menu .x-menu-item-checked { + border: 1px dotted !important; + padding: 0; +} + +.x-menu .x-menu-scroller { + width: 100%; + background-repeat: no-repeat; + background-position: center; + height: 8px; + line-height: 8px; + cursor: pointer; + margin: 0; + padding: 0; +} + +.x-menu .x-menu-scroller-active { + height: 6px; + line-height: 6px; +} + +.x-menu-list-item-indent { + padding-left: 27px !important; +} + +.x-menu-text { + + border-style: solid; + background: #D6E3F2; + border-color:#DAE6F4 #99bbe8 #99bbe8 #DAE6F4; + border-width: 1px; + margin:-2px -2px 0; + color:#15428b; + font:bold 10px tahoma,arial,verdana,sans-serif; + display:block; + padding:3px; +} + +.x-menubar { + padding: 3px; + border-style: solid; + border-width: 0 0 1px 0; + cursor: default; + border-color: #a9bfd3; + background-color: #d0def0; + padding: 3px; + background-image: url(../images/default/toolbar/bg.gif); +} + +.x-menubar-item { + padding: 1px 8px; + font: 12px arial, verdana, sans-serif; +} + +.x-menubar-item-over { + background-color: #98c5f5; +} + +.x-menubar-item-active { + background-color: #98c5f5; +}.x-box-tl { + background: transparent no-repeat 0 0; + zoom:1; +} +.x-box-tc { + height: 8px; + background: transparent repeat-x 0 0; + overflow: hidden; +} +.x-box-tr { + background: transparent no-repeat right -8px; +} +.x-box-ml { + background: transparent repeat-y 0; + padding-left: 4px; + overflow: hidden; + zoom:1; +} +.x-box-mc { + background: repeat-x 0 -16px; + padding: 4px 10px; +} +.x-box-mc h3 { + margin: 0 0 4px 0; + zoom:1; +} +.x-box-mr { + background: transparent repeat-y right; + padding-right: 4px; + overflow: hidden; +} +.x-box-bl { + background: transparent no-repeat 0 -16px; + zoom:1; +} +.x-box-bc { + background: transparent repeat-x 0 -8px; + height: 8px; + overflow: hidden; +} +.x-box-br { + background: transparent no-repeat right -24px; +} +.x-box-tl, .x-box-bl { + padding-left: 8px; + overflow: hidden; +} +.x-box-tr, .x-box-br { + padding-right: 8px; + overflow: hidden; +} +.x-combo-list { + border:1px solid; + zoom:1; + overflow:hidden; + position: absolute; +} +.x-combo-list-inner { + overflow:auto; + position:relative; + zoom:1; + overflow-x:hidden; +} +.x-combo-list-hd { + border-bottom:1px solid; + padding:3px; +} +.x-resizable-pinned .x-combo-list-inner { + border-bottom:1px solid; +} +.x-combo-list-item { + padding:2px; + border:1px solid; + white-space: nowrap; + overflow:hidden; + text-overflow: ellipsis; +} +.x-combo-list .x-combo-selected{ + border:1px dotted !important; + cursor:pointer; +} +.x-combo-list .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +} +.x-panel { + border-style: solid; + border-width:0; + outline: 0 none; +} +.x-panel-header { + overflow:hidden; + zoom:1; + padding:5px 3px 4px 5px; + border:1px solid; + line-height: 15px; + background: transparent repeat-x 0 -1px; +} +.x-panel-body { + border:1px solid; + border-top:0 none; + overflow:hidden; + position: relative; +} +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border:1px solid; + border-top:0 none; + overflow:hidden; + padding:2px; +} +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top:1px solid; + border-bottom: 0 none; +} +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top:1px solid; +} +.x-panel-header { + overflow:hidden; + zoom:1; +} +.x-panel-tl .x-panel-header { + padding:5px 0 4px 0; + border:0 none; + background:transparent; + line-height: 15px; +} +.x-panel-tl .x-panel-icon, .x-window-tl .x-panel-icon { + padding-left:20px !important; + background-repeat:no-repeat; + background-position:0 4px; + zoom:1; +} +.x-panel-inline-icon { + width:16px; + height:16px; + background-repeat:no-repeat; + background-position:0 0; + vertical-align:middle; + margin-right:4px; + margin-top:-1px; + margin-bottom:-1px; +} +.x-panel-tc { + background: transparent repeat-x 0 0; + overflow:hidden; +} +.ext-strict .ext-ie7 .x-panel-tc { + overflow: visible; +} +.x-panel-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + border-bottom:1px solid; +} +.x-panel-tr { + background: transparent no-repeat right 0; + zoom:1; + padding-right:6px; +} +.x-panel-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} +.x-panel-bc .x-panel-footer { + zoom:1; +} +.x-panel-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} +.x-panel-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} +.x-panel-mc { + border:0 none; + padding:0; + margin:0; + padding-top:6px; +} +.x-panel-mc .x-panel-body { + background:transparent; + border: 0 none; +} +.x-panel-ml { + background: repeat-y 0 0; + padding-left:6px; + zoom:1; +} +.x-panel-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} +.x-panel-bc .x-panel-footer { + padding-bottom:6px; +} +.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc { + height:6px; + font-size:0; + line-height:0; +} +.x-panel-bwrap { + overflow:hidden; + zoom:1; + left:0; + top:0; +} +.x-panel-body { + overflow:hidden; + zoom:1; +} +.x-panel-collapsed .x-resizable-handle{ + display:none; +} +.ext-gecko .x-panel-animated * { + overflow:hidden !important; +} +.x-plain-body { + overflow:hidden; +} +.x-plain-bbar .x-toolbar { + overflow:hidden; + padding:2px; +} +.x-plain-tbar .x-toolbar { + overflow:hidden; + padding:2px; +} +.x-plain-bwrap { + overflow:hidden; + zoom:1; +} +.x-plain { + overflow:hidden; +} +.x-tool { + overflow:hidden; + width:15px; + height:15px; + float:right; + cursor:pointer; + background:transparent no-repeat; + margin-left:2px; +} +.x-tool-toggle { + background-position:0 -60px; +} +.x-tool-toggle-over { + background-position:-15px -60px; +} +.x-panel-collapsed .x-tool-toggle { + background-position:0 -75px; +} +.x-panel-collapsed .x-tool-toggle-over { + background-position:-15px -75px; +} +.x-tool-close { + background-position:0 -0; +} +.x-tool-close-over { + background-position:-15px 0; +} +.x-tool-minimize { + background-position:0 -15px; +} +.x-tool-minimize-over { + background-position:-15px -15px; +} +.x-tool-maximize { + background-position:0 -30px; +} +.x-tool-maximize-over { + background-position:-15px -30px; +} +.x-tool-restore { + background-position:0 -45px; +} +.x-tool-restore-over { + background-position:-15px -45px; +} +.x-tool-gear { + background-position:0 -90px; +} +.x-tool-gear-over { + background-position:-15px -90px; +} +.x-tool-pin { + background-position:0 -135px; +} +.x-tool-pin-over { + background-position:-15px -135px; +} +.x-tool-unpin { + background-position:0 -150px; +} +.x-tool-unpin-over { + background-position:-15px -150px; +} +.x-tool-right { + background-position:0 -165px; +} +.x-tool-right-over { + background-position:-15px -165px; +} +.x-tool-left { + background-position:0 -180px; +} +.x-tool-left-over { + background-position:-15px -180px; +} +.x-tool-up { + background-position:0 -210px; +} +.x-tool-up-over { + background-position:-15px -210px; +} +.x-tool-down { + background-position:0 -195px; +} +.x-tool-down-over { + background-position:-15px -195px; +} +.x-tool-refresh { + background-position:0 -225px; +} +.x-tool-refresh-over { + background-position:-15px -225px; +} +.x-tool-minus { + background-position:0 -255px; +} +.x-tool-minus-over { + background-position:-15px -255px; +} +.x-tool-plus { + background-position:0 -240px; +} +.x-tool-plus-over { + background-position:-15px -240px; +} +.x-tool-search { + background-position:0 -270px; +} +.x-tool-search-over { + background-position:-15px -270px; +} +.x-tool-save { + background-position:0 -285px; +} +.x-tool-save-over { + background-position:-15px -285px; +} +.x-tool-help { + background-position:0 -300px; +} +.x-tool-help-over { + background-position:-15px -300px; +} +.x-tool-print { + background-position:0 -315px; +} +.x-tool-print-over { + background-position:-15px -315px; +} +.x-panel-ghost { + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + opacity:.65; + -moz-opacity:.65; + filter:alpha(opacity=65); +} +.x-panel-ghost ul { + margin:0; + padding:0; + overflow:hidden; + font-size:0; + line-height:0; + border:1px solid; + border-top:0 none; + display:block; +} +.x-panel-ghost * { + cursor:move !important; +} +.x-panel-dd-spacer { + border:2px dashed; +} +.x-panel-btns { + padding:5px; + overflow:hidden; +} +.x-panel-btns-left .x-buttonbar { + clear:none; +} +.x-panel-btns-center{ + text-align:center; +} +.x-panel-btns-center .x-toolbar-ct { + margin:0 auto; + text-align:left; + width:auto; +} +.x-panel-fbar td.x-toolbar-cell{ + padding:0px; +} +.x-panel-fbar { + display: block; + padding:2px; + position:relative; + left:0; + top:0; + zoom:1; + overflow:hidden; +} + +.x-panel-fbar .x-toolbar-cell { + vertical-align:middle; +} + +.x-panel-fbar td { + vertical-align:middle; +} +.x-panel-btns .x-btn-focus .x-btn-left{ + background-position:0 -147px; +} +.x-panel-btns .x-btn-focus .x-btn-right{ + background-position:0 -168px; +} +.x-panel-btns .x-btn-focus .x-btn-center{ + background-position:0 -189px; +} +.x-panel-btns .x-btn-over .x-btn-left{ + background-position:0 -63px; +} +.x-panel-btns .x-btn-over .x-btn-right{ + background-position:0 -84px; +} +.x-panel-btns .x-btn-over .x-btn-center{ + background-position:0 -105px; +} +.x-panel-btns .x-btn-click .x-btn-center{ + background-position:0 -126px; +} +.x-panel-btns .x-btn-click .x-btn-right{ + background-position:0 -84px; +} +.x-panel-btns .x-btn-click .x-btn-left{ + background-position:0 -63px; +} +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + white-space: nowrap; +} +.x-window { + zoom:1; + -moz-outline: none; + outline: 0 none; +} +.x-window .x-resizable-handle { + opacity:0; + -moz-opacity:0; + filter:alpha(opacity=0); +} +.x-window-proxy { + border:1px solid; + z-index:12000; + overflow:hidden; + position:absolute; + left:0;top:0; + display:none; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} +.x-window-header { + overflow:hidden; + zoom:1; +} +.x-window-bwrap { + z-index:1; + position:relative; + zoom:1; + left:0;top:0; +} +.x-window-tl .x-window-header { + padding:5px 0 4px 0; +} +.x-window-header-text { + cursor:pointer; +} +.x-window-tc { + background: transparent repeat-x 0 0; + overflow:hidden; + zoom:1; +} +.x-window-tl { + background: transparent no-repeat 0 0; + padding-left:6px; + zoom:1; + z-index:1; + position:relative; +} +.x-window-tr { + background: transparent no-repeat right 0; + padding-right:6px; +} +.x-window-bc { + background: transparent repeat-x 0 bottom; + zoom:1; +} +.x-window-bc .x-window-footer { + padding-bottom:6px; + zoom:1; + font-size:0; + line-height:0; +} +.x-window-bl { + background: transparent no-repeat 0 bottom; + padding-left:6px; + zoom:1; +} +.x-window-br { + background: transparent no-repeat right bottom; + padding-right:6px; + zoom:1; +} +.x-window-mc { + border:1px solid; + padding:0; + margin:0; +} +.x-window-ml { + background: transparent repeat-y 0 0; + padding-left:6px; + zoom:1; +} +.x-window-mr { + background: transparent repeat-y right 0; + padding-right:6px; + zoom:1; +} +.x-window-body { + overflow:hidden; +} +.x-window-bwrap { + overflow:hidden; +} +.x-window-maximized .x-window-bl, .x-window-maximized .x-window-br, + .x-window-maximized .x-window-ml, .x-window-maximized .x-window-mr, + .x-window-maximized .x-window-tl, .x-window-maximized .x-window-tr { + padding:0; +} +.x-window-maximized .x-window-footer { + padding-bottom:0; +} +.x-window-maximized .x-window-tc { + padding-left:3px; + padding-right:3px; +} +.x-window-maximized .x-window-mc { + border-left:0 none; + border-right:0 none; +} +.x-window-tbar .x-toolbar, .x-window-bbar .x-toolbar { + border-left:0 none; + border-right: 0 none; +} +.x-window-bbar .x-toolbar { + border-top:1px solid; + border-bottom:0 none; +} +.x-window-draggable, .x-window-draggable .x-window-header-text { + cursor:move; +} +.x-window-maximized .x-window-draggable, .x-window-maximized .x-window-draggable .x-window-header-text { + cursor:default; +} +.x-window-body { + background:transparent; +} +.x-panel-ghost .x-window-tl { + border-bottom:1px solid; +} +.x-panel-collapsed .x-window-tl { + border-bottom:1px solid; +} +.x-window-maximized-ct { + overflow:hidden; +} +.x-window-sizing-ghost ul { + border:0 none !important; +} +.x-dlg-focus{ + -moz-outline:0 none; + outline:0 none; + width:0; + height:0; + overflow:hidden; + position:absolute; + top:0; + left:0; +} +.x-dlg-mask{ + z-index:10000; + display:none; + position:absolute; + top:0; + left:0; + -moz-opacity: 0.5; + opacity:.50; + filter: alpha(opacity=50); +} +body.ext-ie6.x-body-masked select { + visibility:hidden; +} +body.ext-ie6.x-body-masked .x-window select { + visibility:visible; +} +.x-window-plain .x-window-mc { + border: 1px solid; +} +.x-window-plain .x-window-body { + border: 1px solid; + background:transparent !important; +} +.x-html-editor-wrap { + border:1px solid; +} + +.x-html-editor-tb .x-btn-text { + background:transparent no-repeat; +} + +.x-html-editor-tip .x-tip-bd .x-tip-bd-inner { + padding:5px; + padding-bottom:1px; +} + +.x-html-editor-tb .x-toolbar { + position:static !important; +}.x-panel-noborder .x-panel-body-noborder { + border-width:0; +} +.x-panel-noborder .x-panel-header-noborder { + border-width:0 0 1px; + border-style:solid; +} +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +} +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-width:1px 0 0 0; + border-style:solid; +} +.x-window-noborder .x-window-mc { + border-width:0; +} +.x-window-plain .x-window-body-noborder { + border-width:0; +} +.x-tab-panel-noborder .x-tab-panel-body-noborder { + border-width:0; +} +.x-tab-panel-noborder .x-tab-panel-header-noborder { + border-width: 0 0 1px 0; +} +.x-tab-panel-noborder .x-tab-panel-footer-noborder { + border-width: 1px 0 0 0; +} +.x-tab-panel-bbar-noborder .x-toolbar { + border-width: 1px 0 0 0; + border-style:solid; +} +.x-tab-panel-tbar-noborder .x-toolbar { + border-width:0 0 1px; + border-style:solid; +} +.x-border-panel { + position:absolute !important; + left:0; + top:0; +} +.x-tool-collapse-south { + background-position:0 -195px; +} +.x-tool-collapse-south-over { + background-position:-15px -195px; +} +.x-tool-collapse-north { + background-position:0 -210px; +} +.x-tool-collapse-north-over { + background-position:-15px -210px; +} +.x-tool-collapse-west { + background-position:0 -180px; +} +.x-tool-collapse-west-over { + background-position:-15px -180px; +} +.x-tool-collapse-east { + background-position:0 -165px; +} +.x-tool-collapse-east-over { + background-position:-15px -165px; +} +.x-tool-expand-south { + background-position:0 -210px; +} +.x-tool-expand-south-over { + background-position:-15px -210px; +} +.x-tool-expand-north { + background-position:0 -195px; +} +.x-tool-expand-north-over { + background-position:-15px -195px; +} +.x-tool-expand-west { + background-position:0 -165px; +} +.x-tool-expand-west-over { + background-position:-15px -165px; +} +.x-tool-expand-east { + background-position:0 -180px; +} +.x-tool-expand-east-over { + background-position:-15px -180px; +} +.x-tool-expand-north, .x-tool-expand-south { + float:right; + margin:3px; +} +.x-tool-expand-east, .x-tool-expand-west { + float:none; + margin:3px auto; +} +.x-accordion-hd .x-tool-toggle { + background-position:0 -255px; +} +.x-accordion-hd .x-tool-toggle-over { + background-position:-15px -255px; +} +.x-panel-collapsed .x-accordion-hd .x-tool-toggle { + background-position:0 -240px; +} +.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over { + background-position:-15px -240px; +} +.x-accordion-hd { + padding-top:4px; + padding-bottom:3px; + border-top:0 none; + background: transparent repeat-x 0 -9px; +} +.x-layout-collapsed{ + position:absolute; + left:-10000px; + top:-10000px; + visibility:hidden; + width:20px; + height:20px; + overflow:hidden; + border:1px solid; + z-index:20; +} +.ext-border-box .x-layout-collapsed{ + width:22px; + height:22px; +} +.x-layout-collapsed-over{ + cursor:pointer; +} +.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{ + position:absolute; + top:0; + left:0; + width:20px; + height:20px; +} +.x-layout-split{ + position:absolute; + height:5px; + width:5px; + line-height:1px; + font-size:1px; + z-index:3; + background-color:transparent; +} +.ext-strict .ext-ie6 .x-layout-split{ + background-color: #fff !important; + filter: alpha(opacity=1); +} +.x-layout-split-h{ + background-image:url(../images/default/s.gif); + background-position: left; +} +.x-layout-split-v{ + background-image:url(../images/default/s.gif); + background-position: top; +} +.x-column-layout-ct { + overflow:hidden; + zoom:1; +} +.x-column { + float:left; + padding:0; + margin:0; + overflow:hidden; + zoom:1; +} +.x-column-inner { + overflow:hidden; + zoom:1; +} +.x-layout-mini { + position:absolute; + top:0; + left:0; + display:block; + width:5px; + height:35px; + cursor:pointer; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); +} +.x-layout-mini-over, .x-layout-collapsed-over .x-layout-mini{ + opacity:1; + -moz-opacity:1; + filter:none; +} +.x-layout-split-west .x-layout-mini { + top:48%; +} +.x-layout-split-east .x-layout-mini { + top:48%; +} +.x-layout-split-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} +.x-layout-split-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} +.x-layout-cmini-west .x-layout-mini { + top:48%; +} +.x-layout-cmini-east .x-layout-mini { + top:48%; +} +.x-layout-cmini-north .x-layout-mini { + left:48%; + height:5px; + width:35px; +} +.x-layout-cmini-south .x-layout-mini { + left:48%; + height:5px; + width:35px; +} +.x-layout-cmini-west, .x-layout-cmini-east { + border:0 none; + width:5px !important; + padding:0; + background:transparent; +} +.x-layout-cmini-north, .x-layout-cmini-south { + border:0 none; + height:5px !important; + padding:0; + background:transparent; +} +.x-viewport, .x-viewport body { + margin: 0; + padding: 0; + border: 0 none; + overflow: hidden; + height: 100%; +} +.x-abs-layout-item { + position:absolute !important; + left:0; + top:0; +} +.x-abs-layout-container { + position:relative; +} +.ext-ie input.x-abs-layout-item, .ext-ie textarea.x-abs-layout-item { + margin:0; +} +.x-box-layout-ct { + overflow:hidden; + zoom:1; +} +.x-box-inner { + overflow:hidden; + zoom:1; + position:relative; + left:0; + top:0; +} +.x-box-item { + position:absolute !important; + left:0; + top:0; +} +.x-border-layout-ct { + position: relative; +} +.x-progress-wrap { + border:1px solid; + overflow:hidden; +} +.x-progress-inner { + height:18px; + background:repeat-x; + position:relative; +} +.x-progress-bar { + height:18px; + float:left; + width:0; + background: repeat-x left center; + border-top:1px solid; + border-bottom:1px solid; + border-right:1px solid; +} +.x-progress-text { + padding:1px 5px; + overflow:hidden; + position:absolute; + left:0; + text-align:center; +} +.x-progress-text-back { + line-height:16px; +} +.ext-ie .x-progress-text-back { + line-height:15px; +} +.x-slider { + zoom:1; + -moz-outline: none; + outline: 0 none; +} +.x-slider-thumb { + line-height: 0px; + font-size: 0px; + position: absolute; + background:transparent no-repeat 0 0; +} +.x-slider-inner { + position:relative; + left:0; + top:0; + overflow:visible; + zoom:1; +} +.x-slider-focus { + position:absolute; + left:0; + top:0; + width:1px; + height:1px; + line-height:1px; + font-size:1px; + -moz-outline:0 none; + outline:0 none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: ignore + display:block; + overflow:hidden; +} +.x-slider-horz { + padding-left:7px; + background:transparent no-repeat 0 -22px; +} +.x-slider-horz .x-slider-end { + padding-right:7px; + zoom:1; + background:transparent no-repeat right -44px; +} +.x-slider-horz .x-slider-inner { + background:transparent repeat-x 0 0; + height:22px; +} +.x-slider-horz .x-slider-thumb { + width:14px; + height:15px; + left:0; + top:3px; +} +.x-slider-horz .x-slider-thumb-over { + background-position: -14px -15px; +} +.x-slider-horz .x-slider-thumb-drag { + background-position: -28px -30px; +} +.x-slider-vert { + padding-top:7px; + background:transparent no-repeat -44px 0; + width:22px; +} +.x-slider-vert .x-slider-end { + padding-bottom:7px; + zoom:1; + background:transparent no-repeat -22px bottom; +} +.x-slider-vert .x-slider-inner { + background:transparent repeat-y 0 0; +} +.x-slider-vert .x-slider-thumb { + width:15px; + height:14px; + left:3px; + bottom:0; +} +.x-slider-vert .x-slider-thumb-over { + background-position: -15px -14px; +} +.x-slider-vert .x-slider-thumb-drag { + background-position: -30px -28px; +} +.x-window-dlg .x-window-body { + border:0 none !important; + padding:5px 10px; + overflow:hidden !important; +} +.x-window-dlg .x-window-mc { + border:0 none !important; +} +.x-window-dlg .ext-mb-input { + margin-top:4px; + width:95%; +} +.x-window-dlg .ext-mb-textarea { + margin-top:4px; +} +.x-window-dlg .x-progress-wrap { + margin-top:4px; +} +.ext-ie .x-window-dlg .x-progress-wrap { + margin-top:6px; +} +.x-window-dlg .x-msg-box-wait { + background:transparent no-repeat left; + display:block; + width:300px; + padding-left:18px; + line-height:18px; +} +.x-window-dlg .ext-mb-icon { + float:left; + width:47px; + height:32px; +} +.ext-ie .x-window-dlg .ext-mb-icon { + width:44px; +} +.x-window-dlg .x-dlg-icon .ext-mb-content{ + zoom: 1; margin-left: 47px; +} +.x-window-dlg .ext-mb-info, .x-window-dlg .ext-mb-warning, .x-window-dlg .ext-mb-question, .x-window-dlg .ext-mb-error { + background:transparent no-repeat top left; +} +.ext-gecko2 .ext-mb-fix-cursor { + overflow:auto; +} +.arrow-top { + background: url(../images/gxt/icons/top2.gif) no-repeat center left !important; +} +.arrow-bottom { + background: url(../images/gxt/icons/bottom2.gif) no-repeat center left !important; +} +.arrow-up { + background: url(../images/gxt/icons/up2.gif) no-repeat center left !important; +} +.arrow-down { + background: url(../images/gxt/icons/down2.gif) no-repeat center left !important; +} +.arrow-left { + background: url(../images/gxt/icons/left2.gif) no-repeat center left !important; +} +.arrow-double-left { + background: url(../images/gxt/icons/doubleleft2.gif) no-repeat center left !important; +} +.arrow-right { + background: url(../images/gxt/icons/right2.gif) no-repeat center left !important; +} +.arrow-double-right { + background: url(../images/gxt/icons/doubleright2.gif) no-repeat center left !important; +} +.x-info { + border-style: solid; + border-color: #99bbe8; + border-width: 0; + z-index: 99999999; +} + +.x-info-header { + overflow: hidden; + zoom: 1; + color: black; + font: bold 13px tahoma, arial, verdana, sans-serif; + padding: 5px 3px 4px 5px; + line-height: 15px; + background: transparent url(../images/default/panel/white-top-bottom.gif) repeat-x 0 -1px; +} + +.x-info-body { + border-top: 0 none; + overflow: hidden; + background: white; + position: relative; /* added for item scroll positioning */ +} + +.x-info-header { + overflow: hidden; + zoom: 1; +} + +.x-info-tl .x-info-header { + color: #555555; + font-family: tahoma, arial, sans-serif; + font-size: 13px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: bold; + line-height: normal; + padding: 5px 0 4px 0; + border: 0 none; + background: transparent; +} + +.x-info-tl .x-info-icon,.x-window-tl .x-info-icon { + padding-left: 20px !important; + background-repeat: no-repeat; + background-position: 0 4px; + zoom: 1; +} + +.x-info-inline-icon { + width: 16px; + height: 16px; + background-repeat: no-repeat; + background-position: 0 0; + vertical-align: middle; + margin-right: 4px; + margin-top: -1px; + margin-bottom: -1px; +} + +.x-info-tc { + background: transparent url(../images/gxt/info/top-bottom.gif) repeat-x 0 0; + overflow: hidden; +} + +/* fix ie7 strict mode bug */ +.ext-ie7 .x-info-tc { + overflow: visible; +} + +.x-info-tl { + background: transparent url(../images/gxt/info/corners-sprite.gif) no-repeat 0 0; + padding-left: 6px; + zoom: 1; +} + +.x-info-tr { + background: transparent url(../images/gxt/info/corners-sprite.gif) no-repeat right 0; + zoom: 1; + padding-right: 6px; +} + +.x-info-bc { + background: transparent url(../images/default/panel/top-bottom.gif) repeat-x 0 bottom; + zoom: 1; + font-size: 0px; +} + +.x-info-bc .x-info-footer { + zoom: 1; +} + +.x-info-bl { + background: transparent url(../images/default/panel/corners-sprite.gif) no-repeat 0 bottom; + padding-left: 6px; + zoom: 1; +} + +.x-info-br { + background: transparent url(../images/default/panel/corners-sprite.gif) no-repeat right bottom; + padding-right: 6px; + zoom: 1; +} + +.x-info-mc { + border: 0 none; + padding: 0; + margin: 0; + font: normal 11px tahoma, arial, helvetica, sans-serif; + background: #dfe8f6; +} + +.x-info-mc .x-info-body { + background: transparent; + border: 0 none; +} + +.x-info-ml { + background: #fff url(../images/default/panel/left-right.gif) repeat-y 0 0; + padding-left: 6px; + zoom: 1; +} + +.x-info-mr { + background: transparent url(../images/default/panel/left-right.gif) repeat-y right 0; + padding-right: 6px; + zoom: 1; +} + +.x-info-bc .x-info-footer { + padding-bottom: 6px; +} + +.x-info-nofooter .x-info-bc,.x-panel-nofooter .x-info-bc { + height: 6px; + font-size: 0; + line-height: 0; +} + +.x-info-bwrap { + overflow: hidden; + zoom: 1; +} + +.x-info-body { + overflow: hidden; + zoom: 1; + color: #555555; + font-family: tahoma, arial, sans-serif; + font-size: 12px; + font-size-adjust: none; + font-style: normal; + font-variant: normal; + font-weight: normal; +}.x-combo-over { + border: 1px dotted #B5B4B4 !important; + background: #F1F1F1; + cursor: pointer; +} + +.my-list { + border: 1px solid #99BBE8; + -moz-outline: none; + outline: 0 none; + -moz-user-focus: normal; + background-color: white; + font-family: "Myriad Pro", "Myriad Web", "Tahoma", "Helvetica", "Arial", sans-serif; +} + +.my-list-notchecked { + background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 0px !important; + margin: 3px 0pt 0pt 0px; +} + +.my-list-checked { + background: url(../images/gxt/tree/checked.gif) no-repeat 0px 0px !important; + margin: 3px 0pt 0pt 0px; +} + +.ext-ie .my-list-notchecked { + margin: 2px 0pt 0pt 0px; +} + +.ext-ie .my-list-checked { + margin: 2px 0pt 0pt 0px; +} + +.my-list-flat { + border: 1px solid #6593cf; + -moz-outline: none; + outline: 0 none; + -moz-user-focus: normal; + background-color: white; + cursor: default; +} + +.my-list-item { + cursor: pointer; + -moz-outline: none; + outline: 0 none; + -moz-user-focus: normal; +} + +.my-list-flat .my-list-item { + height: 19px; + border: 1px solid white; +} + +.my-list-flat .my-list-item-over { + background-color: #F1F1F1; + border: 1px dotted #B5B4B4; +} + +.my-list-flat .my-list-item-sel { + background-color: #DFE8F6; + border: 1px dotted #9EB8ED; +} + +.my-list-flat .my-list-item-over .my-list-item-l { + background: none; +} + +.my-list-flat .my-list-item-over .my-list-item-icon,.my-list-flat .my-list-item-over .my-list-item-ml,.my-list-flat .my-list-item-over .my-list-item-c + { + background: none; +} + +.my-list-flat .my-list-item-over .my-list-item-r { + background: none; +} + +.my-list-flat .my-list-item-sel .my-list-item-l { + background: none; +} + +.my-list-flat .my-list-item-sel .my-list-item-icon,.my-list-flat .my-list-item-sel .my-list-item-ml,.my-list-flat .my-list-item-sel .my-list-item-c + { + background: none; +} + +.my-list-flat .my-list-item-sel .my-list-item-r { + background: none; +} + +.my-list-item-text { + font-size: 11px; + padding-top: 3px; + padding-left: 2px; + white-space: nowrap; + overflow: hidden; + line-height: 19px; +} + +.my-list-item-l div { + width: 5px; +} + +.my-list-item-ml { + width: 18px; +} + +.my-list-item-c { + width: 100%; +} + +.my-list-item-r div { + width: 3px; +} + +.my-list-item-over .my-list-item-l { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left -57px; +} + +.my-list-item-over .my-list-item-icon,.my-list-item-over .my-list-item-check,.my-list-item-over .my-list-item-c + { + background: url(../images/gxt/shared/select-19-bg.gif) repeat-x left -95px; +} + +.my-list-item-over .my-list-item-r { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -76px; +} + +.my-list-item-sel .my-list-item-l { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left 0px; +} + +.my-list-item-sel .my-list-item-icon,.my-list-item-sel .my-list-item-check,.my-list-item-sel .my-list-item-c + { + background: url(../images/gxt/shared/select-19-bg.gif) left -38px; +} + +.my-list-item-sel .my-list-item-r { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -19px; +}.x-view { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; + background-color: white; + cursor: default; + border: 1px solid #98C0F4; + overflow: auto; + padding: 0px; + zoom: 1; +} + +.x-view-item { + border: 1px solid #FFFFFF; + font-family: tahoma, arial, helvetica, sans-serif; + font-size: 12px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: normal; + overflow: hidden; + padding: 2px; + white-space: nowrap; +} + +.x-view-highlightrow { + border: 1px dotted #545352 !important; +} + +.x-view-item-over { + background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top; + border: 1px dotted #dddddd !important; + cursor: pointer; +} + +.x-view-item-sel { + background: #DFE8F6 none repeat scroll 0%; + border: 1px dotted #A3BAE9 !important; + cursor: pointer; +} +.x-view-item-check { + padding: 0px; +} +.x-view-item-check td { + font-family: tahoma, arial, helvetica, sans-serif; + font-size: 12px; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: normal; + white-space: nowrap; + vertical-align: middle; + padding-left: 1px; +} + +.x-splitbar-shim { + filter: alpha(opacity = 1); + opacity: 0; + position: absolute; + width: 100%; + height: 100%; + z-index: 10; + background-color: white; + -moz-user-select: none; + -khtml-user-select: none; + user-select: none; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.x-vsplitbar { + background: url(../images/default/s.gif); + position: absolute; + z-index: 3; + cursor: e-resize; + cursor: col-resize; +} + +.x-hsplitbar { + background: url(../images/default/s.gif); + position: absolute; + font-size: 1px; + line-height: 1px; + z-index: 3; + cursor: s-resize; + cursor: row-resize; +} + +.x-splitbar-proxy { + position: absolute; + background-color: #929090; + font-size: 1px; + line-height: 1px; + z-index: 200; +} + +.my-splitbar-shim { + filter: alpha(opacity = 1); + opacity: 0; + position: absolute; + width: 100%; + height: 100%; + z-index: 10; + background-color: white; + -moz-user-select: none; + -khtml-user-select: none; + user-select: none; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-splitbar-transparent { + background: none; + font-size: 1px; + line-height: 1px; + z-index: 2000; +} + +.my-splitbar-proxy { + position: absolute; + background-color: #929090; + font-size: 1px; + line-height: 1px; + z-index: 200; +}.x-status { + padding: 0 4px; + height: 21px; + line-height: 21px !important; + cursor: default; +} +.x-status .x-status-text{ + padding: 2px; + line-height: 21px !important; +} +.x-status-icon { + padding-left: 25px !important; + background: transparent no-repeat left center; +} +.x-status-busy { + background-image: url(../images/default/grid/loading.gif); +} +.x-status-text-panel { + border: 1px solid; + border-color: #99bbe8 #fff #fff #99bbe8; +} +.my-tbl { + border: 1px solid #99BBE8; + cursor: default; + background-color: white; + overflow: hidden; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 11px; + table-layout: fixed; +} + +.my-tbl-col-overflow { + overflow: hidden; +} + +.ext-ie .my-tbl-col-overflow { + +} + +.my-tbl-col-text { + color: black; + padding: 5px 4px 0 4px; + display: block; + white-space: nowrap; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 11px; +} + +.my-tbl-col { + border-right: 1px solid #D5D5D5; + background: url(../images/gxt/table/vs-column-bg.gif) repeat-x; +} + +.my-tbl-col-splitter { + position: absolute; + top: 0; + width: 6px; + z-index: 100; + height: 100%; + right: 0px; +} + +.my-tbl-col-over { + background: url(../images/gxt/table/vs-column-bg.gif) repeat-x 0px -24px; +} + +.my-tbl-col-sort { + background-position: 0px -48px; +} + +.my-icon-asc { + background-image: url(../images/gxt/icons/hmenu-asc.gif) !important; +} + +.my-icon-desc { + background-image: url(../images/gxt/icons/hmenu-desc.gif) !important; +} + +.my-tbl-col-asc { + background: url(../images/gxt/table/vsort-asc.gif) no-repeat 50% top; +} + +.my-tbl-col-desc { + background: url(../images/gxt/table/vsort-desc.gif) no-repeat 50% top; +} + +.my-tbl-col-splitter { + background: none; +} + +.my-tbl-data { + background-color: white; + overflow: hidden; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-item { + border-top: 1px solid white; + border-bottom: 1px solid white; + border-bottom: 1px solid #EDEDED; + cursor: default; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-item table { + -moz-outline: none; + -moz-user-focus: normal; + table-layout: fixed; + outline: 0 none; +} + +.my-tbl-data .my-tbl-item-cell { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-item td { + -moz-user-select: none; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-vlines .my-tbl-data .my-tbl-item-cell-overflow { + border-right: 1px solid #EDEDED; +} + +.my-tbl-data .my-tbl-item-cell-overflow { + white-space: nowrap; + overflow: hidden; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-data .my-tbl-item-cell-text { + padding: 3px 4px; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 11px; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-tbl-data .my-tbl-item-cell-widget { + padding: 1px 4px; +} + +.my-tbl-data tr { + overflow: hidden; +} + +.my-tbl-item-over { + border-top: 1px solid #dddddd; + border-bottom: 1px solid #dddddd; + background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top; +} + +.my-tbl-item-sel { + background-image: none !important; + background-color: #D9E1ED !important; + border-top: 1px dotted #9EB8ED !important; + border-bottom: 1px dotted #9EB8ED !important; +} + +.ext-ie .my-tbl TD .x-form-text { + POSITION: static; + TOP: 0px; +}.tree-folder { + background: url(../images/gxt/icons/folder-closed.gif) no-repeat -1px -1px; +} + +.tree-folder-open { + background: url(../images/gxt/icons/folder.gif) no-repeat -1px -1px; +} + +.my-treetbl-tree { + cursor: default; +} + +.my-treetblitem,.my-treetblitem table,.my-treetblitem table td { + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-treetblitem td { + height: 19px; +} + +.my-treetbl-indent { + line-height: 1px; + font-size: 1px; +} + +.my-treetbl-joint div { + width: 15px; + height: 19px; + line-height: 1px; + font-size: 1px; +} + +.my-treetbl-left,.my-treetbl-left div,.my-treetbl-right { + line-height: 1px; + font-size: 1px; + width: 3px; +} + +.my-treetbl-left div,.my-treetbl-right div { + width: 3px; +} + +.my-treetbl-check div { + width: 17px; + height: 19px; + line-height: 1px; + font-size: 1px; + display: block; +} + +.my-treetbl-icon div { + width: 16px; + height: 16px; + margin-top: 1px; + cursor: pointer; + background-repeat: no-repeat; + background-position: center; +} + +.my-ie .my-treetbl-icon { + padding-top: 2px; +} + +.my-ie .my-treetbl-icon div { + position: static; +} + +.my-treetbl-item-text span { + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 12px; + white-space: nowrap; + padding-left: 3px; + padding-right: 3px; + display: block; + height: 15px; + cursor: pointer; +} + +.my-treetbl-over .my-treetbl-left { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left -57px; +} + +.my-treetbl-over .my-treetbl-right { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -76px; +} + +.my-treetbl-over .my-treetbl-check,.my-treetbl-over .my-treetbl-icon,.my-treetbl-over .my-treetbl-item-text + { + background: url(../images/gxt/shared/select-19-bg.gif) left -95px; +} + +.my-treetbl-sel .my-treetbl-left { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left 0px; +} + +.my-treetbl-sel .my-treetbl-right { + background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -19px; +} + +.my-treetbl-sel .my-treetbl-check,.my-treetbl-sel .my-treetbl-icon,.my-treetbl-sel .my-treetbl-item-text + { + background: url(../images/gxt/shared/select-19-bg.gif) left -38px; +} + +.my-treetbl-close { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px 1px; +} + +.my-treetbl-open { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -32px; +} + +.my-treetbl-joint-over .my-treetbl-open { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -48px; +} + +.my-treetbl-joint-over .my-treetbl-close { + background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -15px; +} + +.my-treetbl-notchecked { + background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 50%; +} + +.my-treetbl-checked { + background: url(../images/gxt/tree/checked.gif) no-repeat 0px 50%; +} + +.my-treetbl-loading .tree-folder { + background: url(../images/gxt/icons/wait.gif) no-repeat 0px -1px; +} + +.my-treetbl-loading .my-treetbl-item-text span { + font-style: italic; +} + +.my-treetbl { + border: 1px solid #99BBE8; + cursor: default; + background-color: white; + overflow: hidden; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-treetbl-col-overflow { + overflow: hidden; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-treetbl-col-text { + color: black; + padding: 5px 4px 0 4px; + display: block; + white-space: nowrap; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 12px; +} + +.my-treetbl-col { + border-right: 1px solid #D5D5D5; + background: url(../images/gxt/table/vs-column-bg.gif) repeat-x; +} + +.my-treetbl-col-splitter { + position: absolute; + top: 0; + width: 6px; + z-index: 100; + height: 100%; + right: 0px; +} + +.my-treetbl-col-over { + background: url(../images/gxt/table/vs-column-bg.gif) repeat-x 0px -24px; +} + +.my-treetbl-col-sort { + background-position: 0px -48px; +} + +.my-treetbl-col-asc { + background: url(../images/gxt/table/vsort-asc.gif) no-repeat 50% top; +} + +.my-treetbl-col-desc { + background: url(../images/gxt/table/vsort-desc.gif) no-repeat 50% top; +} + +.my-treetbl-col-splitter { + background: none; +} + +.my-treetbl-data { + background-color: white; + overflow: hidden; +} + +.my-treetbl-data .my-treetbl-cell { + height: 20px; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-treetbl-data .my-treetbl-cell-overflow { + white-space: nowrap; + overflow: hidden; +} + +.my-treetbl-data .my-treetbl-cell-text { + padding: 0px 0px; + font-family: arial, tahoma, helvetica, sans-serif; + font-size: 12px; +} + +.my-treetbl-data tr { + overflow: hidden; +} + +.my-treetbl-item { + border-top: 1px solid white; + border-bottom: 1px solid white; + border-bottom: 1px solid #EDEDED; + cursor: default; + -moz-outline: none; + -moz-user-focus: normal; + outline: 0 none; +} + +.my-treetbl-item-over { + border-top: 1px solid #dddddd; + border-bottom: 1px solid #dddddd; + background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top; +} + +.my-treetbl-item-sel { + background-image: none; + background-color: #D9E1ED; + border-top: 1px dotted #9EB8ED; + border-bottom: 1px dotted #9EB8ED; +} + +.my-treetbl .x-grid3-td-numberer { + background: transparent url(../images/gxt/tree/tree-table-special-col.gif) repeat-y + scroll left center; + height: 19px; + line-height: normal; + padding-left: 0px; + margin-left: 0px; +} + +.x-grid3-td-numberer div { + font-size: 11px; + font-family: "segoe ui", tahoma, arial, sans-serif; + color: #444444; + padding: 3px 0px 0 5px !important; +} + +.ext-ie .my-treetbl .x-grid3-td-numberer { + height: 20px; +} + +.my-treetbl-item-sel .x-grid3-td-numberer { + background: transparent url(../images/gxt/tree/tree-table-special-col-sel.gif) repeat-y + scroll left center; +}.ext-el-mask { + background-color: #ccc; +} +.ext-el-mask-msg { + border-color:#6593cf; + background-color:#c3daf9; + background-image:url(../images/default/box/tb-blue.gif); +} +.ext-el-mask-msg div { + background-color: white; + border-color:#a3bad9; + color:#222; + font:normal 11px tahoma, arial, helvetica, sans-serif; +} +.x-mask-loading div { + background-color:#fbfbfb; + background-image:url(../images/default/grid/loading.gif); +} +.x-item-disabled { + color: gray; +} +.x-item-disabled * { + color: gray !important; +} +.x-splitbar-proxy { + background-color: #aaa; +} +.x-color-palette a { + border-color:#fff; +} +.x-color-palette a.x-color-palette-hover, .x-color-palette a.x-color-palette-sel { + border-color:#8bb8f3; + background-color: #deecfd; +} +.x-color-palette em { + border-color:#aca899; +} +.x-ie-shadow { + background-color:#777; +} +.x-shadow .xsmc { + background-image: url(../images/default/shadow-c.png); +} +.x-shadow .xsml, .x-shadow .xsmr { + background-image: url(../images/default/shadow-lr.png); +} +.x-shadow .xstl, .x-shadow .xstc, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{ + background-image: url(../images/default/shadow.png); +} +.loading-indicator { + font-size: 11px; + background-image: url(../images/default/grid/loading.gif); +} +.x-spotlight { + background-color: #ccc; +} +.x-aria-focusframe-side { + background-color: #15428B; + line-height: 2px; + font-size: 2px; +} +.x-tab-panel-header, .x-tab-panel-footer { + background-color: #deecfd; + border-color:#8db2e3; + overflow:hidden; + zoom:1; +} +.x-tab-panel-header, .x-tab-panel-footer { + border-color:#8db2e3; +} +ul.x-tab-strip-top{ + background-color:#cedff5; + background-image: url(../images/default/tabs/tab-strip-bg.gif); + border-bottom-color:#8db2e3; +} +ul.x-tab-strip-bottom{ + background-color:#cedff5; + background-image: url(../images/default/tabs/tab-strip-btm-bg.gif); + border-top-color:#8db2e3; +} +.x-tab-panel-header-plain .x-tab-strip-spacer, +.x-tab-panel-footer-plain .x-tab-strip-spacer { + border-color:#8db2e3; + background-color: #deecfd; +} +.x-tab-strip span.x-tab-strip-text { + font:normal 11px tahoma,arial,helvetica; + color:#416aa3; +} +.x-tab-strip-over span.x-tab-strip-text { + color:#15428b; +} +.x-tab-strip-active span.x-tab-strip-text { + color:#15428b; + font-weight:bold; +} +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} +.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{ + background-image: url(../images/default/tabs/tabs-sprite.gif); +} +.x-tab-strip-bottom .x-tab-right { + background-image: url(../images/default/tabs/tab-btm-inactive-right-bg.gif); +} +.x-tab-strip-bottom .x-tab-left { + background-image: url(../images/default/tabs/tab-btm-inactive-left-bg.gif); +} +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image: url(../images/default/tabs/tab-btm-right-bg.gif); +} +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image: url(../images/default/tabs/tab-btm-left-bg.gif); +} +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(../images/default/tabs/tab-close.gif); +} +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(../images/default/tabs/tab-close.gif); +} +.x-tab-panel-body { + border-color:#8db2e3; + background-color:#fff; +} +.x-tab-panel-body-top { + border-top: 0 none; +} +.x-tab-panel-body-bottom { + border-bottom: 0 none; +} +.x-tab-scroller-left { + background-image:url(../images/default/tabs/scroll-left.gif); + border-bottom-color:#8db2e3; +} +.x-tab-scroller-left-over { + background-position: 0 0; +} +.x-tab-scroller-left-disabled { + background-position: -18px 0; + opacity:.5; + -moz-opacity:.5; + filter:alpha(opacity=50); + cursor:default; +} +.x-tab-scroller-right { + background-image:url(../images/default/tabs/scroll-right.gif); + border-bottom-color:#8db2e3; +} +.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar { + border-color:#99bbe8; +} +.x-form-field { + font: normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-text,textarea.x-form-field { + background-color: #fff; + background-image: url(../images/default/form/text-bg.gif); + border-color: #b5b8c8; +} + +.x-form-select-one { + background-color: #fff; + border-color: #b5b8c8; +} + +.x-form-check-group-label { + border-bottom: 1px solid #99bbe8; + color: #15428b; +} + +.x-editor .x-form-check-wrap { + background-color: #fff; +} + +.x-form-field-wrap .x-form-trigger { + background-image: url(../images/default/form/trigger.gif); + border-bottom-color: #b5b8c8; +} + +.x-form-field-wrap .x-form-date-trigger { + background-image: url(../images/default/form/date-trigger.gif); +} + +.x-form-field-wrap .x-form-clear-trigger { + background-image: url(../images/default/form/clear-trigger.gif); +} + +.x-form-field-wrap .x-form-search-trigger { + background-image: url(../images/default/form/search-trigger.gif); +} + +.x-trigger-wrap-focus .x-form-trigger { + border-bottom-color: #7eadd9; +} + +.x-item-disabled .x-form-trigger-over { + border-bottom-color: #b5b8c8; +} + +.x-item-disabled .x-form-trigger-click { + border-bottom-color: #b5b8c8; +} + +.x-form-focus,textarea.x-form-focus { + border-color: #7eadd9; +} + +.x-form-invalid,textarea.x-form-invalid { + background-color: #fff; + background-image: url(../images/default/grid/invalid_line.gif); + border-color: #c30; +} + +.ext-safari .x-form-invalid { + background-color: #fee; + border-color: #ff7870; +} + +.x-form-inner-invalid,textarea.x-form-inner-invalid { + background-color: #fff; + background-image: url(../images/default/grid/invalid_line.gif); +} + +.x-form-grow-sizer { + font: normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-item { + font: normal 12px tahoma, arial, helvetica, sans-serif; +} + +.x-form-invalid-msg { + color: #c0272b; + font: normal 11px tahoma, arial, helvetica, sans-serif; + background-image: url(../images/default/shared/warning.gif); +} + +.x-form-empty-field { + color: gray; +} + +.x-small-editor .x-form-field { + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.ext-safari .x-small-editor .x-form-field { + font: normal 12px arial, tahoma, helvetica, sans-serif; +} + +.x-form-invalid-icon { + background-image: url(../images/default/form/exclamation.gif); +} + +.x-fieldset { + border-color: #b5b8c8; +} + +.x-fieldset legend { + font: bold 11px tahoma, arial, helvetica, sans-serif; + color: #15428b; +} + +.x-editor .x-form-check-wrap { + border-color: #7eadd9; +} + +.x-spinner-field .x-form-spinner-up { + background-image: url('../images/default/form/spinner.gif'); +} +.x-spinner-field .x-form-spinner-down { + background-image: url('../images/default/form/spinner.gif'); +}.x-btn{ + font:normal 11px tahoma, verdana, helvetica; +} +.x-btn button{ + font:normal 11px arial,tahoma,verdana,helvetica; + color:#333; +} +.x-btn em { + font-style:normal; + font-weight:normal; +} +.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{ + background-image:url(../images/default/button/btn.gif); +} +.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{ + color:#000; +} +.x-btn-disabled *{ + color:gray !important; +} +.x-btn-mc em.x-btn-arrow { + background-image:url(../images/default/button/arrow.gif); +} +.x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow.gif); +} +.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split { + background-image:url(../images/default/button/s-arrow-o.gif); +} +.x-btn-mc em.x-btn-arrow-bottom { + background-image:url(../images/default/button/s-arrow-b-noline.gif); +} +.x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-b.gif); +} +.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom { + background-image:url(../images/default/button/s-arrow-bo.gif); +} +.x-btn-group-header { + color: #3e6aaa; +} +.x-btn-group-tc { + background-image: url(../images/default/button/group-tb.gif); +} +.x-btn-group-tl { + background-image: url(../images/default/button/group-cs.gif); +} +.x-btn-group-tr { + background-image: url(../images/default/button/group-cs.gif); +} +.x-btn-group-bc { + background-image: url(../images/default/button/group-tb.gif); +} +.x-btn-group-bl { + background-image: url(../images/default/button/group-cs.gif); +} +.x-btn-group-br { + background-image: url(../images/default/button/group-cs.gif); +} +.x-btn-group-ml { + background-image: url(../images/default/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(../images/default/button/group-lr.gif); +} +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(../images/default/button/group-tb.gif); +} +.x-toolbar { + border-color: #a9bfd3; + background-color: #d0def0; + background-image: url(../images/default/toolbar/bg.gif); +} + +.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label { + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-toolbar .x-item-disabled { + color: gray; +} + +.x-toolbar .x-item-disabled * { + color: gray; +} + +.x-toolbar .x-btn-mc em.x-btn-split { + background-image: url(../images/default/button/s-arrow-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split,.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split + { + background-image: url(../images/default/button/s-arrow-o.gif); +} + +.x-toolbar .x-btn-mc em.x-btn-split-bottom { + background-image: url(../images/default/button/s-arrow-b-noline.gif); +} + +.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom,.x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom + { + background-image: url(../images/default/button/s-arrow-bo.gif); +} + +.x-toolbar .xtb-sep { + background-image: url(../images/default/grid/grid-blue-split.gif); +} + +.x-tbar-page-first { + background-image: url(../images/default/grid/page-first.gif) !important; +} + +.x-tbar-refresh { + background-image: url(../images/default/grid/refresh.gif) !important; +} + +.x-tbar-page-last { + background-image: url(../images/default/grid/page-last.gif) !important; +} + +.x-tbar-page-next { + background-image: url(../images/default/grid/page-next.gif) !important; +} + +.x-tbar-page-prev { + background-image: url(../images/default/grid/page-prev.gif) !important; +} + +.x-tbar-loading { + background-image: url(../images/default/grid/loading.gif) !important; +} + +.x-item-disabled .x-tbar-page-first { + background-image: url(../images/default/grid/page-first-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-last { + background-image: url(../images/default/grid/page-last-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-next { + background-image: url(../images/default/grid/page-next-disabled.gif) !important; +} + +.x-item-disabled .x-tbar-page-prev { + background-image: url(../images/default/grid/page-prev-disabled.gif) !important; +} + +.x-paging-info { + color: #444; +} + +.x-toolbar-more-icon { + background-image: url(../images/default/toolbar/more.gif) !important; +}.x-resizable-handle { + background-color:#fff; +} +.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east, +.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west +{ + background-image:url(../images/default/sizer/e-handle.gif); +} +.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south, +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north +{ + background-image:url(../images/default/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{ + background-image:url(../images/default/sizer/s-handle.gif); +} +.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{ + background-image:url(../images/default/sizer/se-handle.gif); +} +.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{ + background-image:url(../images/default/sizer/nw-handle.gif); +} +.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{ + background-image:url(../images/default/sizer/ne-handle.gif); +} +.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{ + background-image:url(../images/default/sizer/sw-handle.gif); +} +.x-resizable-proxy{ + border-color:#3b5a82; +} +.x-resizable-overlay{ + background-color:#fff; +} +.x-grid3 { + background-color: #fff; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border-color: #99bbe8; +} + +.x-grid3-hd-row .x-grid3-hd,.x-grid3-row .x-grid3-cell,.x-grid3-summary-row .x-grid3-cell { + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-hd-row .x-grid3-hd { + border-left-color: #eee; + border-right-color: #d0d0d0; +} + +.x-grid-row-loading { + background-color: #fff; + background-image: url(../images/default/shared/loading-balls.gif); +} + +.x-grid3-row { + border-color: #ededed; + border-top-color: #fff; +} + +.x-grid3-row-alt { + background-color: #fafafa; +} + +.x-grid3-row-over { + border-color: #ddd; + background-color: #efefef; + background-image: url(../images/default/grid/row-over.gif); +} + +.x-grid3-resize-proxy { + background-color: #777; +} + +.x-grid3-resize-marker { + background-color: #777; +} + +.x-grid3-header { + background-color: #f9f9f9; + background-image: url(../images/default/grid/grid3-hrow.gif); +} + +.x-grid3-header-pop { + border-left-color: #d0d0d0; +} + +.x-grid3-header-pop-inner { + border-left-color: #eee; + background-image: url(../images/default/grid/hd-pop.gif); +} + +td.x-grid3-hd-over,td.sort-desc,td.sort-asc,td.x-grid3-hd-menu-open { + border-left-color: #aaccf6; + border-right-color: #aaccf6; +} + +td.x-grid3-hd-over .x-grid3-hd-inner,td.sort-desc .x-grid3-hd-inner,td.sort-asc .x-grid3-hd-inner,td.x-grid3-hd-menu-open .x-grid3-hd-inner + { + background-color: #ebf3fd; + background-image: url(../images/default/grid/grid3-hrow-over.gif); +} + +.sort-asc .x-grid3-sort-icon { + background-image: url(../images/default/grid/sort_asc.gif); +} + +.sort-desc .x-grid3-sort-icon { + background-image: url(../images/default/grid/sort_desc.gif); +} + +.x-grid3-cell-text,.x-grid3-hd-text { + color: #000; +} + +.x-grid3-split { + background-image: url(../images/default/grid/grid-split.gif); +} + +.x-grid3-hd-text { + color: #15428b; +} + +.x-dd-drag-proxy .x-grid3-hd-inner { + background-color: #ebf3fd; + background-image: url(../images/default/grid/grid3-hrow-over.gif); + border-color: #aaccf6; +} + +.col-move-top { + background-image: url(../images/default/grid/col-move-top.gif); +} + +.col-move-bottom { + background-image: url(../images/default/grid/col-move-bottom.gif); +} + +.x-grid3-highlightrow { + border: 1px dotted #545352; +} + +.x-grid3-row-selected { + background-image: none !important; + background-color: #dfe8f6 !important; + border-color: #a3bae9; +} + +.x-grid3-cell-selected { + background-color: #b8cfee !important; + color: #000; +} + +.x-grid3-group-selected { + background-color: #b8cfee !important; +} + +.x-grid3-cell-selected span { + color: #000 !important; +} + +.x-grid3-cell-selected .x-grid3-cell-text { + color: #000; +} + +.x-grid3-locked td.x-grid3-row-marker,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker { + background-color: #ebeadb !important; + background-image: url(../images/default/grid/grid-hrow.gif) !important; + color: #000; + border-top-color: #fff; + border-right-color: #6fa0df !important; +} + +.x-grid3-locked td.x-grid3-row-marker div,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div { + color: #15428b !important; +} + +.x-grid3-dirty-cell { + background-image: url(../images/default/grid/dirty.gif); +} + +.x-grid3-invalid-cell { + background-image: url(../images/default/grid/invalid_line.gif); +} + +.x-grid3-topbar,.x-grid3-bottombar { + font: normal 11px arial, tahoma, helvetica, sans-serif; +} + +.x-grid3-bottombar .x-toolbar { + border-top-color: #a9bfd3; +} + +.x-props-grid .x-grid3-td-name .x-grid3-cell-inner { + background-image: url(../images/default/grid/grid3-special-col-bg.gif) !important; + color: #000 !important; +} + +.x-props-grid .x-grid3-body .x-grid3-td-name { + background-color: #fff !important; + border-right-color: #eee; +} + +.xg-hmenu-sort-asc .x-menu-item-icon { + background-image: url(../images/default/grid/hmenu-asc.gif); +} + +.xg-hmenu-sort-desc .x-menu-item-icon { + background-image: url(../images/default/grid/hmenu-desc.gif); +} + +.xg-hmenu-lock .x-menu-item-icon { + background-image: url(../images/default/grid/hmenu-lock.gif); +} + +.xg-hmenu-unlock .x-menu-item-icon { + background-image: url(../images/default/grid/hmenu-unlock.gif); +} + +.x-grid3-hd-btn { + background-color: #c3daf9; + background-image: url(../images/default/grid/grid3-hd-btn.gif); +} + +.x-grid3-body .x-grid3-td-expander { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-expander { + background-image: url(../images/default/grid/row-expand-sprite.gif); +} + +.x-grid3-body .x-grid3-td-checker { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-row-checker,.x-grid3-hd-checker { + background-image: url(../images/default/grid/row-check-sprite.gif); +} + +.x-grid3-body .x-grid3-td-numberer { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner { + color: #444; +} + +.x-grid3-body .x-grid3-td-row-icon { + background-image: url(../images/default/grid/grid3-special-col-bg.gif); +} + +.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander + { + background-image: url(../images/default/grid/grid3-special-col-sel-bg.gif); +} + +.x-grid3-check-col { + background-image: url(../images/default/menu/unchecked.gif); +} + +.x-grid3-check-col-on { + background-image: url(../images/default/menu/checked.gif); +} + +.x-grid-group,.x-grid-group-body,.x-grid-group-hd { + zoom: 1; +} + +.x-grid-group-hd { + border-bottom-color: #99bbe8; +} + +.x-grid-group-hd .x-grid-group-div { + background-image: url(../images/default/grid/group-expand-sprite.gif); + color: #3764a0; + font: bold 11px tahoma, arial, helvetica, sans-serif; +} + +.x-group-by-icon { + background-image: url(../images/default/grid/group-by.gif); +} + +.x-cols-icon { + background-image: url(../images/default/grid/columns.gif); +} + +.x-show-groups-icon { + background-image: url(../images/default/grid/group-by.gif); +} + +.x-grid-empty { + color: gray; + font: normal 11px tahoma, arial, helvetica, sans-serif; +} + +.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell { + border-right-color: #ededed; +} + +.x-grid-with-col-lines .x-grid3-row-selected { + border-top-color: #a3bae9; +} + +.x-grid3-check-col-disabled { + background-color: transparent; + background-image: url(../images/gxt/menu/disabledcheck.gif); +} + +.x-row-editor-header { + background: transparent url(../images/gxt/grid/row-editor-bg.gif) repeat-x 0 0; +} + +.x-row-editor-footer { + background: transparent url(../images/gxt/grid/row-editor-bg.gif) repeat-x 0 -2px; +} + +.x-row-editor-body { + background: #ebf2fb; +} + +.x-row-editor .x-btns { + background: transparent url(../images/gxt/grid/row-editor-btns.gif) no-repeat 0 0; +} + +.x-row-editor .x-btns .x-plain-bwrap { + background: transparent url(../images/gxt/grid/row-editor-btns.gif) no-repeat right -31px; +} + +.x-row-editor .x-btns .x-plain-body { + background: transparent url(../images/gxt/grid/row-editor-btns.gif) repeat-x 0 -62px; +} + +.x-inserted-row { + background-color: #f7f9cc +}.x-dd-drag-ghost{ + color:#000; + font: normal 11px arial, helvetica, sans-serif; + border-color: #ddd #bbb #bbb #ddd; + background-color:#fff; +} +.x-dd-drop-nodrop .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-no.gif); +} +.x-dd-drop-ok .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-yes.gif); +} +.x-dd-drop-ok-add .x-dd-drop-icon{ + background-image: url(../images/default/dd/drop-add.gif); +} +.x-view-selector { + background-color:#c3daf9; + border-color:#3399bb; +} +.x-tree-drop-ok-append .x-dd-drop-icon { + background-image: url(../images/default/tree/drop-add.gif); +} + +.x-tree-drop-ok-above .x-dd-drop-icon { + background-image: url(../images/default/tree/drop-over.gif); +} + +.x-tree-drop-ok-below .x-dd-drop-icon { + background-image: url(../images/default/tree/drop-under.gif); +} + +.x-tree-drop-ok-between .x-dd-drop-icon { + background-image: url(../images/default/tree/drop-between.gif); +} + +.x-tree3-loading { + background-image: url(../images/default/tree/loading.gif); +} + +.x-tree3-node-text { + font: normal 11px arial, tahoma, helvetica, sans-serif; + color: black; +}.x-date-picker { + border-color: #1b376c; + background-color:#fff; +} +.x-date-middle,.x-date-left,.x-date-right { + background-image: url(../images/default/shared/hd-sprite.gif); + color:#fff; + font:bold 11px "sans serif", tahoma, verdana, helvetica; +} +.x-date-middle .x-btn .x-btn-text { + color:#fff; +} +.x-date-middle .x-btn-mc em.x-btn-arrow { + background-image:url(../images/default/toolbar/btn-arrow-light.gif); +} +.x-date-right a { + background-image: url(../images/default/shared/right-btn.gif); +} +.x-date-left a{ + background-image: url(../images/default/shared/left-btn.gif); +} +.x-date-inner th { + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); + border-bottom-color:#a3bad9; + font:normal 10px arial, helvetica,tahoma,sans-serif; + color:#233d6d; +} +.x-date-inner td { + border-color:#fff; +} +.x-date-inner a { + font:normal 11px arial, helvetica,tahoma,sans-serif; + color:#000; +} +.x-date-inner .x-date-active{ + color:#000; +} +.x-date-inner .x-date-selected a{ + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} +.x-date-inner .x-date-today a{ + border-color:darkred; +} +.x-date-inner .x-date-selected span{ + font-weight:bold; +} +.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a { + color:#aaa; +} +.x-date-bottom { + border-top-color:#a3bad9; + background-color:#dfecfb; + background-image:url(../images/default/shared/glass-bg.gif); +} +.x-date-inner .x-date-disabled a { + background-color:#eee; + color:#bbb; +} +.x-date-mmenu{ + background-color:#eee !important; +} +.x-date-mmenu .x-menu-item { + font-size:10px; + color:#000; +} +.x-date-mp { + background-color:#fff; +} +.x-date-mp td { + font:normal 11px arial, helvetica,tahoma,sans-serif; +} +.x-date-mp-btns button { + background-color:#083772; + color:#fff; + border-color: #3366cc #000055 #000055 #3366cc; + font:normal 11px arial, helvetica,tahoma,sans-serif; +} +.x-date-mp-btns { + background-color: #dfecfb; + background-image: url(../images/default/shared/glass-bg.gif); +} +.x-date-mp-btns td { + border-top-color: #c5d2df; +} +td.x-date-mp-month a,td.x-date-mp-year a { + color:#15428b; +} +td.x-date-mp-sel a { + background-color: #dfecfb; + background-image: url(../images/default/shared/glass-bg.gif); + border-color:#8db2e3; +} +.x-date-mp-ybtn a { + background-image:url(../images/default/panel/tool-sprites.gif); +} +td.x-date-mp-sep { + border-right-color:#c5d2df; +} +.x-tip .x-tip-close{ + background-image: url(../images/default/qtip/close.gif); +} +.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr { + background-image: url(../images/default/qtip/tip-sprite.gif); +} +.x-tip .x-tip-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; +} +.x-tip .x-tip-ml { + background-color: #fff; +} +.x-tip .x-tip-header-text { + font: bold 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} +.x-tip .x-tip-body { + font: normal 11px tahoma,arial,helvetica,sans-serif; + color:#444; +} +.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc, +.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr +{ + background-image: url(../images/default/form/error-tip-corners.gif); +} +.x-form-invalid-tip .x-tip-body { + background-image:url(../images/default/form/exclamation.gif); +} +.x-tip-anchor { + background-image:url(../images/default/qtip/tip-anchor-sprite.gif); +} +.x-menu { + border-color:#718bb7; + background-color:#f0f0f0; + background-image:url(../images/default/menu/menu.gif); +} +.x-menu-nosep { + background-image:none; +} +.x-menu-list-item{ + font:normal 11px tahoma,arial, sans-serif; +} +.x-menu-item-arrow{ + background-image:url(../images/default/menu/menu-parent.gif); +} +.x-menu-sep { + background-color:#e0e0e0; + border-bottom-color:#fff; +} +a.x-menu-item { + color:#222; +} +.x-menu-item-active { + background:#ebf3fd url(../images/default/menu/item-over.gif) repeat-x left bottom; + border:1px solid #aaccf6; + padding:0; +} +.x-menu-item-active a.x-menu-item { + color:#233d6d; +} + +.x-menu-plain { + background-color:#fff !important; +} +.x-menu .x-date-picker{ + border-color:#a3bad9; +} +.x-cycle-menu .x-menu-item-checked { + border-color:#a3bae9 !important; + background-color:#def8f6; +} +.x-menu-scroller-top { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-menu-scroller-bottom { + background-image:url(../images/default/layout/mini-bottom.gif); +} + +.x-menu-scroller{ + border-width: 1px 0; +} +.x-box-tl { + background-image: url(../images/default/box/corners.gif); +} +.x-box-tc { + background-image: url(../images/default/box/tb.gif); +} +.x-box-tr { + background-image: url(../images/default/box/corners.gif); +} +.x-box-ml { + background-image: url(../images/default/box/l.gif); +} +.x-box-mc { + background-color: #eee; + background-image: url(../images/default/box/tb.gif); + font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif; + color: #393939; + font-size: 12px; +} +.x-box-mc h3 { + font-size: 14px; + font-weight: bold; +} +.x-box-mr { + background-image: url(../images/default/box/r.gif); +} +.x-box-bl { + background-image: url(../images/default/box/corners.gif); +} +.x-box-bc { + background-image: url(../images/default/box/tb.gif); +} +.x-box-br { + background-image: url(../images/default/box/corners.gif); +} +.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr { + background-image: url(../images/default/box/corners-blue.gif); +} +.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc { + background-image: url(../images/default/box/tb-blue.gif); +} +.x-box-blue .x-box-mc { + background-color: #c3daf9; +} +.x-box-blue .x-box-mc h3 { + color: #17385b; +} +.x-box-blue .x-box-ml { + background-image: url(../images/default/box/l-blue.gif); +} +.x-box-blue .x-box-mr { + background-image: url(../images/default/box/r-blue.gif); +} +.x-combo-list { + border-color:#98c0f4; + background-color:#ddecfe; + font:normal 12px tahoma, arial, helvetica, sans-serif; +} +.x-combo-list-inner { + background-color:#fff; +} +.x-combo-list-hd { + font:bold 11px tahoma, arial, helvetica, sans-serif; + color:#15428b; + background-image: url(../images/default/layout/panel-title-light-bg.gif); + border-bottom-color:#98c0f4; +} +.x-resizable-pinned .x-combo-list-inner { + border-bottom-color:#98c0f4; +} +.x-combo-list-item { + border-color:#fff; +} +.x-combo-list .x-combo-selected{ + border-color:#a3bae9 !important; + background-color:#dfe8f6; +} +.x-combo-list .x-toolbar { + border-top-color:#98c0f4; +} +.x-combo-list-small { + font:normal 11px tahoma, arial, helvetica, sans-serif; +} +.x-panel { + border-color: #99bbe8; +} +.x-panel-header { + color:#15428b; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; + border-color:#99bbe8; + background-image: url(../images/default/panel/white-top-bottom.gif); +} +.x-panel-body { + border-color:#99bbe8; + background-color:#fff; +} +.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar { + border-color:#99bbe8; +} +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-top-color:#99bbe8; +} +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-top-color:#99bbe8; +} +.x-panel-tl .x-panel-header { + color:#15428b; + font-weight:bold; + font-size: 11px; + font-family: tahoma,arial,verdana,sans-serif; +} +.x-panel-tc { + background-image: url(../images/default/panel/top-bottom.gif); +} +.x-panel-tl, .x-panel-tr, .x-panel-bl, .x-panel-br{ + background-image: url(../images/default/panel/corners-sprite.gif); + border-bottom-color:#99bbe8; +} +.x-panel-bc { + background-image: url(../images/default/panel/top-bottom.gif); +} +.x-panel-mc { + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} +.x-panel-ml { + background-color: #fff; + background-image:url(../images/default/panel/left-right.gif); +} +.x-panel-mr { + background-image: url(../images/default/panel/left-right.gif); +} +.x-tool { + background-image:url(../images/default/panel/tool-sprites.gif); +} +.x-panel-ghost { + background-color:#cbddf3; +} +.x-panel-ghost ul { + border-color:#99bbe8; +} +.x-panel-dd-spacer { + border-color:#99bbe8; +} +.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{ + font:normal 11px arial,tahoma, helvetica, sans-serif; +} +.x-window-proxy { + background-color:#c7dffc; + border-color:#99bbe8; +} +.x-window-tl .x-window-header { + color:#15428b; + font:bold 11px tahoma,arial,verdana,sans-serif; +} +.x-window-tc { + background-image: url(../images/default/window/top-bottom.png); +} +.x-window-tl { + background-image: url(../images/default/window/left-corners.png); +} +.x-window-tr { + background-image: url(../images/default/window/right-corners.png); +} +.x-window-bc { + background-image: url(../images/default/window/top-bottom.png); +} +.x-window-bl { + background-image: url(../images/default/window/left-corners.png); +} +.x-window-br { + background-image: url(../images/default/window/right-corners.png); +} +.x-window-mc { + border-color:#99bbe8; + font: normal 11px tahoma,arial,helvetica,sans-serif; + background-color:#dfe8f6; +} +.x-window-ml { + background-image: url(../images/default/window/left-right.png); +} +.x-window-mr { + background-image: url(../images/default/window/left-right.png); +} +.x-window-maximized .x-window-tc { + background-color:#fff; +} +.x-window-bbar .x-toolbar { + border-top-color:#99bbe8; +} +.x-panel-ghost .x-window-tl { + border-bottom-color:#99bbe8; +} +.x-panel-collapsed .x-window-tl { + border-bottom-color:#84a0c4; +} +.x-dlg-mask{ + background-color:#ccc; +} +.x-window-plain .x-window-mc { + background-color: #ccd9e8; + border-color: #a3bae9 #dfe8f6 #dfe8f6 #a3bae9; +} +.ext-ie .x-window-plain .x-window-mc { + background-color: #c9d5e4; +} +.x-window-plain .x-window-body { + border-color: #dfe8f6 #a3bae9 #a3bae9 #dfe8f6; +} +body.x-body-masked .x-window-plain .x-window-mc { + background-color: #ccd9e8; +} +.x-html-editor-wrap { + border-color:#a9bfd3; + background-color:#fff; +} + +.x-html-editor-tb .x-edit-bold, .x-menu-item .x-edit-bold { + background-position:0 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-italic, .x-menu-item .x-edit-italic { + background-position:-16px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-underline, .x-menu-item .x-edit-underline { + background-position:-32px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-forecolor, .x-menu-item .x-edit-forecolor { + background-position:-160px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-backcolor, .x-menu-item .x-edit-backcolor { + background-position:-176px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyleft, .x-menu-item .x-edit-justifyleft { + background-position:-112px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifycenter, .x-menu-item .x-edit-justifycenter { + background-position:-128px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-justifyright, .x-menu-item .x-edit-justifyright { + background-position:-144px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertorderedlist, .x-menu-item .x-edit-insertorderedlist { + background-position:-80px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-insertunorderedlist, .x-menu-item .x-edit-insertunorderedlist { + background-position:-96px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-increasefontsize, .x-menu-item .x-edit-increasefontsize { + background-position:-48px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-decreasefontsize, .x-menu-item .x-edit-decreasefontsize { + background-position:-64px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-sourceedit, .x-menu-item .x-edit-sourceedit { + background-position:-192px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +} + +.x-html-editor-tb .x-edit-createlink, .x-menu-item .x-edit-createlink { + background-position:-208px 0; + background-image:url(../images/default/editor/tb-sprite.gif); +}.x-panel-noborder .x-panel-header-noborder { + border-bottom-color:#99bbe8; +} +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +} +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} +.x-tab-panel-bbar-noborder .x-toolbar { + border-top-color:#99bbe8; +} +.x-tab-panel-tbar-noborder .x-toolbar { + border-bottom-color:#99bbe8; +} +.x-border-layout-ct { + background-color:#dfe8f6; +} +.x-accordion-hd { + color:#222; + font-weight:normal; + background-image: url(../images/default/panel/light-hd.gif); +} +.x-layout-collapsed{ + background-color:#d2e0f2; + border-color:#98c0f4; +} +.x-layout-collapsed-over{ + background-color:#d9e8fb; +} +.x-layout-split-west .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} +.x-layout-split-east .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} +.x-layout-split-north .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-layout-split-south .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} +.x-layout-cmini-west .x-layout-mini { + background-image:url(../images/default/layout/mini-right.gif); +} +.x-layout-cmini-east .x-layout-mini { + background-image:url(../images/default/layout/mini-left.gif); +} +.x-layout-cmini-north .x-layout-mini { + background-image:url(../images/default/layout/mini-bottom.gif); +} +.x-layout-cmini-south .x-layout-mini { + background-image:url(../images/default/layout/mini-top.gif); +} +.x-progress-wrap { + border-color:#6593cf; +} +.x-progress-inner { + background-color:#e0e8f3; + background-image:url(../images/default/qtip/bg.gif); +} +.x-progress-bar { + background-color:#9cbfee; + background-image:url(../images/default/progress/progress-bg.gif); + border-top-color:#d1e4fd; + border-bottom-color:#7fa9e4; + border-right-color:#7fa9e4; +} +.x-progress-text { + font-size:11px; + font-weight:bold; + color:#fff; +} +.x-progress-text-back { + color:#396095; +} +.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner { + background-image:url(../images/default/slider/slider-bg.png); +} +.x-slider-horz .x-slider-thumb { + background-image:url(../images/default/slider/slider-thumb.png); +} +.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner { + background-image:url(../images/default/slider/slider-v-bg.png); +} +.x-slider-vert .x-slider-thumb { + background-image:url(../images/default/slider/slider-v-thumb.png); +} +.x-window-dlg .ext-mb-text, +.x-window-dlg .x-window-header-text { + font-size:12px; +} +.x-window-dlg .ext-mb-textarea { + font:normal 12px tahoma,arial,helvetica,sans-serif; +} +.x-window-dlg .x-msg-box-wait { + background-image:url(../images/default/grid/loading.gif); +} +.x-window-dlg .ext-mb-info { + background-image:url(../images/default/window/icon-info.gif); +} +.x-window-dlg .ext-mb-warning { + background-image:url(../images/default/window/icon-warning.gif); +} +.x-window-dlg .ext-mb-question { + background-image:url(../images/default/window/icon-question.gif); +} +.x-window-dlg .ext-mb-error { + background-image:url(../images/default/window/icon-error.gif); +} diff --git a/src/main/webapp/gxt/css/gxt-gray.css b/src/main/webapp/gxt/css/gxt-gray.css new file mode 100644 index 0000000..bc31336 --- /dev/null +++ b/src/main/webapp/gxt/css/gxt-gray.css @@ -0,0 +1,493 @@ +.x-panel { + border-style: solid; + border-color: #d0d0d0; +} +.x-panel-header { + color:#333; + border:1px solid #d0d0d0; + background-image:url(../images/gray/panel/white-top-bottom.gif); +} + +.x-panel-body { + border-color:#d0d0d0; +} + +.x-panel-bbar .x-toolbar { + border-color:#d0d0d0; +} + +.x-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} + +.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar { + border-color:#d0d0d0; +} +.x-panel-body-noheader, .x-panel-mc .x-panel-body { + border-color:#d0d0d0; +} +.x-panel-tl .x-panel-header { + color:#333; +} +.x-panel-tc { + background-image:url(../images/gray/panel/top-bottom.gif); +} +.x-panel-tl { + background-image:url(../images/gray/panel/corners-sprite.gif); + border-color:#d0d0d0; +} +.x-panel-tr { + background-image:url(../images/gray/panel/corners-sprite.gif); +} +.x-panel-bc { + background-image:url(../images/gray/panel/top-bottom.gif); +} +.x-panel-bl { + background-image:url(../images/gray/panel/corners-sprite.gif); +} +.x-panel-br { + background-image:url(../images/gray/panel/corners-sprite.gif); +} +.x-panel-mc { + background:#f1f1f1; +} +.x-panel-mc .x-panel-body { + background:transparent; + border: 0 none; +} +.x-panel-ml { + background-image:url(../images/gray/panel/left-right.gif); +} +.x-panel-mr { + background-image:url(../images/gray/panel/left-right.gif); +} + +/* Tools */ +.x-tool { + background-image:url(../images/gray/panel/tool-sprites.gif); +} + +/* Ghosting */ +.x-panel-ghost { + background:#e0e0e0; +} + +.x-panel-ghost ul { + border-color:#b0b0b0; +} + +.x-grid-panel .x-panel-mc .x-panel-body { + border:1px solid #d0d0d0; +} + +/* Buttons */ + +.x-btn-left{ + background-image:url(../images/gray/button/btn-sprite.gif); +} +.x-btn-right{ + background-image:url(../images/gray/button/btn-sprite.gif); +} +.x-btn-center{ + background-image:url(../images/gray/button/btn-sprite.gif); +} + +.x-btn-group-header { + color: #333333; +} +.x-btn-group-tc { + background-image: url(../images/gray/button/group-tb.gif); +} +.x-btn-group-tl { + background-image: url(../images/gray/button/group-cs.gif); +} +.x-btn-group-tr { + background-image: url(../images/gray/button/group-cs.gif); +} +.x-btn-group-bc { + background-image: url(../images/gray/button/group-tb.gif); +} +.x-btn-group-bl { + background-image: url(../images/gray/button/group-cs.gif); +} +.x-btn-group-br { + background-image: url(../images/gray/button/group-cs.gif); +} +.x-btn-group-ml { + background-image: url(../images/gray/button/group-lr.gif); +} +.x-btn-group-mr { + background-image: url(../images/gray/button/group-lr.gif); +} +.x-btn-group-notitle .x-btn-group-tc { + background-image: url(../images/gray/button/group-tb.gif); +} + +/* Layout classes */ + +.x-border-layout-ct { + background:#f0f0f0; +} + +.x-accordion-hd { + background-image:url(../images/gray/panel/light-hd.gif); +} + +.x-layout-collapsed{ + background-color:#eee; + border-color:#e0e0e0; +} +.x-layout-collapsed-over{ + background-color:#fbfbfb; +} + + +/* qtips */ +.x-tip .x-tip-top { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-top-left { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-top-right { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-ft { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-ft-left { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-ft-right { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-bd-left { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} +.x-tip .x-tip-bd-right { + background-image:url(../images/gray/qtip/tip-sprite.gif); +} + +/* Toolbars */ + +.x-toolbar{ + border-color:#d0d0d0; + background:#f0f4f5 url(../images/gray/toolbar/bg.gif) repeat-x top left; +} +.x-toolbar button { + color:#444; +} +.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button { + background-image:url(../images/gray/toolbar/btn-arrow.gif); +} +.x-toolbar .x-btn-text-icon .x-btn-menu-arrow-wrap .x-btn-center button { + background-image:url(../images/gray/toolbar/btn-arrow.gif); +} +.x-toolbar .x-btn-over .x-btn-left{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} +.x-toolbar .x-btn-over .x-btn-right{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} +.x-toolbar .x-btn-over .x-btn-center{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} +.x-toolbar .x-btn-over button { + color:#111; +} +.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} +.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} + +.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{ + background-image:url(../images/gray/toolbar/tb-btn-sprite.gif); +} +.x-toolbar .xtb-sep { + background-image: url(../images/gray/grid/grid-split.gif); +} + +/* Tabs */ + +.x-tab-panel-header, .x-tab-panel-footer { + background: #EAEAEA; + border-color:#d0d0d0; +} + + +.x-tab-panel-header { + border-color:#d0d0d0; +} + +.x-tab-panel-footer { + border-color:#d0d0d0; +} + +ul.x-tab-strip-top{ + background:#dbdbdb url(../images/gray/tabs/tab-strip-bg.gif) repeat-x left top; + border-color:#d0d0d0; + padding-top: 2px; +} + +ul.x-tab-strip-bottom{ + background-image:url(../images/gray/tabs/tab-strip-btm-bg.gif); + border-color:#d0d0d0; +} + +.x-tab-strip span.x-tab-strip-text { + color:#333; +} +.x-tab-strip-over span.x-tab-strip-text { + color:#111; +} + +.x-tab-strip-active span.x-tab-strip-text { + color:#333; +} + +.x-tab-strip-disabled .x-tabs-text { + color:#aaaaaa; +} + +.x-tab-strip-top .x-tab-right { + background-image:url(../images/gray/tabs/tabs-sprite.gif); +} + +.x-tab-strip-top .x-tab-left { + background-image:url(../images/gray/tabs/tabs-sprite.gif); +} +.x-tab-strip-top .x-tab-strip-inner { + background-image:url(../images/gray/tabs/tabs-sprite.gif); +} + +.x-tab-strip-bottom .x-tab-right { + background-image:url(../images/gray/tabs/tab-btm-inactive-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-left { + background-image:url(../images/gray/tabs/tab-btm-inactive-left-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-right { + background-image:url(../images/gray/tabs/tab-btm-right-bg.gif); +} + +.x-tab-strip-bottom .x-tab-strip-active .x-tab-left { + background-image:url(../images/gray/tabs/tab-btm-left-bg.gif); +} + +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close { + background-image:url(../images/gray/tabs/tab-close.gif); +} +.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{ + background-image:url(../images/gray/tabs/tab-close.gif); +} + +.x-tab-panel-body { + border-color:#d0d0d0; + background:#fff; +} +.x-tab-panel-bbar .x-toolbar { + border-color: #d0d0d0; +} + +.x-tab-panel-tbar .x-toolbar { + border-color: #d0d0d0; +} + +.x-tab-panel-header-plain .x-tab-strip-spacer { + border-color:#d0d0d0; + background: #eaeaea; +} + +.x-tab-scroller-left { + background-image: url(../images/gray/tabs/scroll-left.gif); + border-color:#aeaeae; +} +.x-tab-scroller-right { + background-image: url(../images/gray/tabs/scroll-right.gif); + border-color:#aeaeae; +} + +/* Window */ + +.x-window-proxy { + background:#e0e0e0; + border-color:#b0b0b0; +} + +.x-window-tl .x-window-header { + color:#555; +} +.x-window-tc { + background-image:url(../images/gray/window/top-bottom.png); +} +.x-window-tl { + background-image:url(../images/gray/window/left-corners.png); +} +.x-window-tr { + background-image:url(../images/gray/window/right-corners.png); +} +.x-window-bc { + background-image:url(../images/gray/window/top-bottom.png); +} +.x-window-bl { + background-image:url(../images/gray/window/left-corners.png); +} +.x-window-br { + background-image:url(../images/gray/window/right-corners.png); +} +.x-window-mc { + border:1px solid #d0d0d0; + background:#e8e8e8; +} +.ext-ie .x-window-plain .x-window-mc { + background-color: #e3e3e3; +} + +.x-window-ml { + background-image:url(../images/gray/window/left-right.png); +} +.x-window-mr { + background-image:url(../images/gray/window/left-right.png); +} +.x-panel-ghost .x-window-tl { + border-color:#d0d0d0; +} +.x-panel-collapsed .x-window-tl { + border-color:#d0d0d0; +} + +.x-window-plain .x-window-mc { + background: #e8e8e8; + border-right:1px solid #eee; + border-bottom:1px solid #eee; + border-top:1px solid #d0d0d0; + border-left:1px solid #d0d0d0; +} + +.x-window-plain .x-window-body { + border-left:1px solid #eee; + border-top:1px solid #eee; + border-bottom:1px solid #d0d0d0; + border-right:1px solid #d0d0d0; + background:transparent !important; +} + +body.x-body-masked .x-window-mc, body.x-body-masked .x-window-plain .x-window-mc { + background-color: #e4e4e4; +} + + +/* misc */ +.x-html-editor-wrap { + border-color:#d0d0d0; +} + +/* Borders go last for specificity */ +.x-panel-noborder .x-panel-body-noborder { + border-width:0; +} + +.x-panel-noborder .x-panel-header-noborder { + border-width:0; + border-bottom:1px solid #d0d0d0; +} + +.x-panel-noborder .x-panel-tbar-noborder .x-toolbar { + border-width:0; + border-bottom:1px solid #d0d0d0; +} + +.x-panel-noborder .x-panel-bbar-noborder .x-toolbar { + border-width:0; + border-top:1px solid #d0d0d0; +} + +.x-window-noborder .x-window-mc { + border-width:0; +} +.x-window-plain .x-window-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-body-noborder { + border-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-header-noborder { + border-top-width:0; + border-left-width:0; + border-right-width:0; +} + +.x-tab-panel-noborder .x-tab-panel-footer-noborder { + border-bottom-width:0; + border-left-width:0; + border-right-width:0; +} + + +.x-tab-panel-bbar-noborder .x-toolbar { + border-width:0; + border-top:1px solid #d0d0d0; +} + +.x-tab-panel-tbar-noborder .x-toolbar { + border-width:0; + border-bottom:1px solid #d0d0d0; +} + +.x-spinner-field .x-form-spinner-up { + background-image: url('../images/gray/form/spinner.gif'); +} +.x-spinner-field .x-form-spinner-down { + background-image: url('../images/gray/form/spinner.gif'); +}.x-accordion-hd { + background-color: #e5e5e5; +}.x-border { + border: 1px solid #D0D0D0; +} + +.x-layout-popup { + background-color: #F0F0F0; + border: 1px solid #D0D0D0; +} + +.my-list { + border: 1px solid #D0D0D0; +} + +.x-view { + border:1px solid #D0D0D0; +} + +.x-menubar { + border-color: #D0D0D0; + background-color: #F0F0F0; + background-image: url(../images/gray/toolbar/bg.gif); +} + +.x-menubar-item-active { + background-color: #D9E8FB; +} + +.x-menubar-item-active { + background-color: #D9E8FB; +}.x-date-right-icon { + background-image: url(../images/default/shared/right-btn.gif); + margin-right: 2px; + text-decoration: none !important; +} + +.x-date-left-icon { + background-image: url(../images/default/shared/left-btn.gif); + margin-right: 2px; + text-decoration: none !important; +}.my-tbl { + border: 1px solid #C6C5C5; +}.my-treetbl { + border: 1px solid #C6C5C5; +} \ No newline at end of file diff --git a/src/main/webapp/gxt/desktop/css/desktop.css b/src/main/webapp/gxt/desktop/css/desktop.css new file mode 100644 index 0000000..0013ed9 --- /dev/null +++ b/src/main/webapp/gxt/desktop/css/desktop.css @@ -0,0 +1,638 @@ +/* + * Ext JS Library 2.1 + * Copyright(c) 2006-2008, Ext JS, LLC. + * licensing@extjs.com + * + * http://extjs.com/license + */ +html,body { + background: #3d71b8 url(../wallpapers/desktop.jpg) no-repeat left top; + font: normal 12px tahoma, arial, verdana, sans-serif; + margin: 0; + padding: 0; + border: 0 none; + overflow: hidden; + height: 100%; +} + +.start { + background-image: url( ../images/taskbar/black/startbutton-icon.gif ) !important; +} + +.bogus { + background-image: url( ../images/bogus.png ) !important; +} + +.logout { + background-image: url( ../images/logout.gif ) !important; +} + +.settings { + background-image: url( ../images/gears.gif ) !important; +} + +#dpanels { + width: 250px; + float: right; +} + +#dpanels .x-panel { + margin: 15px; +} + +#dpanels .x-date-picker { + border: 0 none; + border-top: 0 none; + background: transparent; +} + +#dpanels .x-date-picker td.x-date-active { + background: #ffffff; +} + +#dpanels .x-date-picker { + width: 100% !important; +} + +#x-desktop { + width: 100%; + height: 100%; + border: 0 none; + position: relative; + overflow: hidden; + zoom: 1; +} + +#ux-taskbar .x-btn { + float: left; + margin: 1px 0 0 1px; + position: relative; +} + +#ux-taskbar-start .x-btn { + float: left; + margin: 0; + position: relative; +} + +#ux-taskbar button { /* width: 150px; + overflow: hidden; */ + text-align: left; + color: #ffffff; +} + +#title-bar-wrapper { + height: 35px; +} + +#title-bar { + color: #225599; + padding: 9px 7px; + font: bold 16px tahoma, arial, verdana, sans-serif; + float: left; +} + +#x-logout { + float: right; + padding: 6px 7px; +} + +.x-btn-text-icon .x-btn-center .logout { + background-position: 0pt 3px; + background-repeat: no-repeat; + padding: 3px 0pt 3px 18px; +} + +#ux-taskbar { + background: transparent none; + height: 30px; + margin: 0; + padding: 0; + position: relative; + z-index: 12001; +} + +.x-btn-icon .ux-taskbutton-center .x-btn-text { + background-position: center; + background-repeat: no-repeat; + height: 16px; + width: 16px; + cursor: pointer; + white-space: nowrap; + padding: 0; +} + +.x-btn-icon .ux-taskbutton-center { + padding: 1px; +} + +.ux-startbutton-center .x-btn-text { + color: #000000 !important; + font-weight: bold; +} + +.ux-taskbutton-left,.ux-taskbutton-right { + font-size: 1px; + line-height: 1px; +} + +.ux-taskbutton-left { + width: 4px; + height: 28px; + background: url( ../images/taskbar/black/taskbutton.gif ) no-repeat 0 0; +} + +.ux-taskbutton-right { + width: 4px; + height: 28px; + background: url( ../images/taskbar/black/taskbutton.gif ) no-repeat 0 -28px; +} + +.ux-taskbutton-left i,.ux-taskbutton-right i { + display: block; + width: 4px; + overflow: hidden; + font-size: 1px; + line-height: 1px; +} + +.ux-taskbutton-center { + background: url( ../images/taskbar/black/taskbutton.gif ) repeat-x 0 -56px; + vertical-align: middle; + text-align: center; + padding: 0 5px; + cursor: pointer; + white-space: nowrap; +} + +#ux-taskbar .ux-taskbutton-left { + background-position: 0 0; +} + +#ux-taskbar .ux-taskbutton-right { + background-position: 0 -28px; +} + +#ux-taskbar .ux-taskbutton-center { + background-position: 0 -56px; +} + +#ux-taskbar .x-btn-over .ux-taskbutton-left { + background-position: 0 -252px; +} + +#ux-taskbar .x-btn-over .ux-taskbutton-right { + background-position: 0 -280px; +} + +#ux-taskbar .x-btn-over .ux-taskbutton-center { + background-position: 0 -308px; +} + +#ux-taskbar .x-btn-click .ux-taskbutton-left { + background-position: 0 -168px; +} + +#ux-taskbar .x-btn-click .ux-taskbutton-right { + background-position: 0 -196px; +} + +#ux-taskbar .x-btn-click .ux-taskbutton-center { + background-position: 0 -224px; +} + +#ux-taskbar .active-win .ux-taskbutton-left { + background-position: 0 -84px; +} + +#ux-taskbar .active-win .ux-taskbutton-right { + background: url( ../images/taskbar/black/taskbutton.gif ) no-repeat 0 -112px; +} + +#ux-taskbar .active-win .ux-taskbutton-center { + background: url( ../images/taskbar/black/taskbutton.gif ) repeat-x 0 -140px; +} + +#ux-taskbar .active-win .ux-taskbutton-center button { + color: #fff; +} + +#spacer { + height: 25px; + float: left; + width: 0; + overflow: hidden; + margin-top: 2px; +} + +.x-window-body p,.x-panel-body p { + padding: 10px; + margin: 0; +} + +.x-window-maximized .x-window-bc { + height: 0; +} + +.add { + background-image: url(../../shared/icons/fam/add.gif) !important; +} + +.option { + background-image: url(../../shared/icons/fam/plugin.gif) !important; +} + +.remove { + background-image: url(../../shared/icons/fam/delete.gif) !important; +} + +.tabs { + background-image: url(../images/tabs.gif) !important; +} + +.ux-start-menu { + background: transparent none; + border: 0px none; + padding: 0; +} + +.ux-start-menu-tl .x-window-header { + color: #f1f1f1; + font: bold 11px tahoma, arial, verdana, sans-serif; + padding: 5px 0 4px 0; +} + +.x-panel-tl .x-panel-icon,.ux-start-menu-tl .x-panel-icon { + background-position: 0pt 4px; + background-repeat: no-repeat; + padding-left: 20px !important; +} + +.ux-start-menu-tl { + background: transparent url( ../images/taskbar/black/start-menu-left-corners.png ) no-repeat 0 0; + padding-left: 6px; + zoom: 1; + z-index: 1; + position: relative; +} + +.ux-start-menu-tr { + background: transparent url( ../images/taskbar/black/start-menu-right-corners.png ) no-repeat right + 0; + padding-right: 6px; +} + +.ux-start-menu-tc { + background: transparent url( ../images/taskbar/black/start-menu-top-bottom.png ) repeat-x 0 0; + overflow: hidden; + zoom: 1; +} + +.ux-start-menu-ml { + background: transparent url( ../images/taskbar/black/start-menu-left-right.png ) repeat-y 0 0; + padding-left: 6px; + zoom: 1; +} + +.ux-start-menu-bc { + background: transparent url( ../images/taskbar/black/start-menu-top-bottom.png ) repeat-x 0 bottom; + zoom: 1; +} + +.ux-start-menu-bc .x-window-footer { + padding-bottom: 6px; + zoom: 1; + font-size: 0; + line-height: 0; +} + +.ux-start-menu-bl { + background: transparent url( ../images/taskbar/black/start-menu-left-corners.png ) no-repeat 0 + bottom; + padding-left: 6px; + zoom: 1; +} + +.ux-start-menu-br { + background: transparent url( ../images/taskbar/black/start-menu-right-corners.png ) no-repeat right + bottom; + padding-right: 6px; + zoom: 1; +} + +.x-panel-nofooter .ux-start-menu-bc { + height: 6px; +} + +.ux-start-menu-splitbar-h { + background-color: #d0d0d0; +} + +.ux-start-menu-bwrap { + background: transparent none; + border: 0px none; +} + +.ux-start-menu-body { + background: transparent none; + border: 0px none; +} + +.ux-start-menu-apps-panel { + background: #ffffff none; + border: 1px solid #1e2124; +} + +.ux-start-menu-tools-panel { + border: 0px none; + background: transparent url( ../images/taskbar/black/start-menu-right.png ) repeat-y scroll right + 0pt; +} + +#ux-taskbar-start { + background: #000000 url( ../images/taskbar/black/taskbar-start-panel-bg.gif ) repeat-x left top; + left: 0px; + padding: 0; + position: absolute; +} + +#ux-taskbar-start .x-toolbar { + background: none; + padding: 0px; + border: 0px none; +} + +#ux-taskbuttons-panel { + background: #000000 url( ../images/taskbar/black/taskbuttons-panel-bg.gif ) repeat-x left top; + padding-top: 0; + position: relative; +} + +.ux-taskbuttons-strip-wrap { /* overflow:hidden; + position:relative; + width:100%; */ + width: 100%; + overflow: hidden; + position: relative; + zoom: 1; +} + +ul.ux-taskbuttons-strip { + display: block; + width: 5000px; + zoom: 1; +} + +ul.ux-taskbuttons-strip li { + float: left; + margin-left: 2px; +} + +ul.ux-taskbuttons-strip li.ux-taskbuttons-edge { + float: left; + margin: 0 !important; + padding: 0 !important; + border: 0 none !important; + font-size: 1px !important; + line-height: 1px !important; + overflow: hidden; + zoom: 1; + background: transparent !important; + width: 1px; +} + +.x-clear { + clear: both; + height: 0; + overflow: hidden; + line-height: 0; + font-size: 0; +} + +.x-taskbuttons-scrolling { + position: relative; +} + +.x-taskbuttons-scrolling .ux-taskbuttons-strip-wrap { + margin-left: 18px; + margin-right: 18px; +} + +td.ux-taskButtons-edge { /*float:left;*/ + margin: 0 !important; + padding: 0 !important; + border: 0 none !important; + font-size: 1px !important; + line-height: 1px !important; + overflow: hidden; + zoom: 1; + background: transparent !important; + width: 1px; +} + +.ux-taskbuttons-scroller-left { + background: transparent url( ../images/taskbar/black/scroll-left.gif ) no-repeat -18px 0; + width: 18px; + position: absolute; + left: 1px; + top: 0px; + z-index: 10; + cursor: pointer; +} + +.ux-taskbuttons-scroller-left-over { + background-position: 0 0; +} + +.ux-taskbuttons-scroller-left-disabled { + background-position: -18px 0; + opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity = 50); + cursor: default; +} + +.ux-taskbuttons-scroller-right { + background: transparent url( ../images/taskbar/black/scroll-right.gif ) no-repeat 0 0; + width: 18px; + position: absolute; + right: 0; + top: 0px; + z-index: 10; + cursor: pointer; +} + +.ux-taskbuttons-scroller-right-over { + background-position: -18px 0; +} + +.ux-taskbuttons-scroller-right-disabled { + background-position: 0 0; + opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity = 50); + cursor: default; +} + +.ux-toolmenu-sep { + background-color: #18191a; + border-bottom: 1px solid #858789; + display: block; + font-size: 1px; + line-height: 1px; + margin: 2px 3px; +} + +.ux-start-menu-tools-panel ul.x-menu-list li.x-menu-list-item a.x-menu-item { + color: #ffffff; +} + +.ux-start-menu-tools-panel ul.x-menu-list li.x-menu-list-item .x-menu-item-active a.x-menu-item { + color: #000000; +} + +.ux-start-menu-tools-panel .x-menu-item-active { + background: #525456 url( ../images/taskbar/black/item-over.gif ) repeat-x left bottom; + border: 1px solid #000000; + padding: 0; +} + +#ux-taskbar .x-splitbar-h { + background: #000000 url( ../images/taskbar/black/taskbar-split-h.gif ) no-repeat 0 0; + width: 8px; +} + +.x-window-header-text { + cursor: default; +} + +/* + * Begin Start button + */ +.ux-startbutton-left,.ux-startbutton-right { + font-size: 1px; + line-height: 1px; +} + +.ux-startbutton-left { + width: 10px; + height: 28px; + background: url( ../images/taskbar/black/startbutton.gif ) no-repeat 0 0; +} + +.ux-startbutton-right { + width: 10px; + height: 30px; + background: url( ../images/taskbar/black/startbutton.gif ) no-repeat 0 -28px; +} + +.ux-startbutton-left i,.ux-startbutton-right i { + display: block; + width: 10px; + overflow: hidden; + font-size: 1px; + line-height: 1px; +} + +.ux-startbutton-center { + background: url( ../images/taskbar/black/startbutton.gif ) repeat-x 0 -56px; + vertical-align: middle; + text-align: center; + padding: 0; + cursor: pointer; + white-space: nowrap; +} + +#ux-taskbar .ux-startbutton-left { + background-position: 0 0; +} + +#ux-taskbar .ux-startbutton-right { + background-position: 0 -30px; +} + +#ux-taskbar .ux-startbutton-center { + background-position: 0 -60px; +} + +#ux-taskbar .x-btn-over .ux-startbutton-left { + background-position: 0 -270px; +} + +#ux-taskbar .x-btn-over .ux-startbutton-right { + background-position: 0 -300px; +} + +#ux-taskbar .x-btn-over .ux-startbutton-center { + background-position: 0 -330px; +} + +#ux-taskbar .x-btn-click .ux-startbutton-left { + background-position: 0 -180px; +} + +#ux-taskbar .x-btn-click .ux-startbutton-right { + background-position: 0 -210px; +} + +#ux-taskbar .x-btn-click .ux-startbutton-center { + background-position: 0 -240px; +} + +#ux-taskbar .active-win .ux-startbutton-left { + background-position: 0 -90px; +} + +#ux-taskbar .active-win .ux-startbutton-right { + background: url( ../images/taskbar/black/startbutton.gif ) no-repeat 0 -120px; +} + +#ux-taskbar .active-win .ux-startbutton-center { + background: url( ../images/taskbar/black/startbutton.gif ) repeat-x 0 -150px; +} + +#ux-taskbar .active-win .ux-startbutton-center button { + color: #fff; +} + +/* + * End Start button + */ +.x-resizable-proxy { + background: #C7DFFC; + opacity: .5; + -moz-opacity: .5; + filter: alpha(opacity = 50); + border: 1px solid #3b5a82; +} + +/* Desktop Shortcuts */ +#x-shortcuts dt { + float: left; + margin: 15px 0 0 15px; + clear: left; + width: 64px; + font: normal 10px tahoma, arial, verdana, sans-serif; + text-align: center; + zoom: 1; + display: block; +} + +#x-shortcuts dt a { + width: 64px; + display: block; + color: white; + text-decoration: none; +} + +#x-shortcuts dt div { + width: 100%; + color: white; + overflow: hidden; + text-overflow: ellipsis; + cursor: pointer; +} + +#x-shortcuts dt a:hover { + text-decoration: underline; +} diff --git a/src/main/webapp/gxt/desktop/images/desktop.gif b/src/main/webapp/gxt/desktop/images/desktop.gif new file mode 100644 index 0000000000000000000000000000000000000000..f305cb643378b5cfc5f447f3003d0b904d23fc30 GIT binary patch literal 63601 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 EI~KPF_W%F@ literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/desktop3.jpg b/src/main/webapp/gxt/desktop/images/desktop3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..daca8bc5eeda549ea4240df77ac164986bbfcad9 GIT binary patch literal 158508 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 z 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 literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/gears.gif b/src/main/webapp/gxt/desktop/images/gears.gif new file mode 100644 index 0000000000000000000000000000000000000000..2bf6bd70d1b128eace0a50b610df5b7a30c5778e GIT binary patch literal 996 zcmZ?wbhEHb6krfwXlGzBvobcau(hOmwsW+xbF_5Vv~;qtcCfQ?v6hW0Rq~J1 z@QyKb^t5zvw|8>2cXqdM@wD)Zu=0A|YbawM{cK3Glba3(Tb@lLZ@$z#D2=z;H z5Y6b4O=*)$Zxha3DOR>Xv~rb1$v%_1`HE#*e2QD0>$U}SX~eXe6|U2&+^gd;J-B>p zLd8*Yjh3}4v-avt*<;nX(R#u<`Q8H(6AnwyIwLptq{zZMQj4$3F1;?X?wZ`*XDW>c zwE7MyPCRKj<&5>D3u>z_>aD(`wBf$xniJ+rt}E<&st44}U6L{cLpXgZ;6u zN)LXjy!`LdzR0O#se8}f+_`&8*KYP&blQ2v&A=50A~xUj-}WJ3&9l(8PjY4)DqnQM z>FodL!|$UW{ZG97zv$45+5=B2ul#MfsMLQ|t>=zj?=7qOk8GCTmt6TlzxlXl%aNeo z8y-`R`cJvyI{Rqt#=DujzLg*T?=W%ml^KWH*4_EF?eeQFw?9ArKk@bdc?_d~1|gvM zlZBaqL7PDbWHu;IFmN1X2Y%2Ns^3i7Z{S%~LX#7#@D^w@`qoP-J3Z zMxc_b<&>C<7Y|=(7ZrK6VCTU$k5;qbtRD;?4mdQ5YUoLMXxvEf=u!5aV{mX$qauq~`lAB@2JOtwjbb@25rz#1 M(i_$N*jX5?0UH(+od5s; literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/gears.png b/src/main/webapp/gxt/desktop/images/gears.png new file mode 100644 index 0000000000000000000000000000000000000000..6acdc989ca7e6bab78a2eb41bf136cedee9191ec GIT binary patch literal 967 zcmV;&133JNP)D6Yd#Te{PSeVs1O=rjQOA1i2-zNe{bTy^`t-Bh}~qil11 zZJ9Stq#-oSqvhnygN9a-g=Yh{SFgp`j#m?r(W&D?RA6>3 zbF5s)6Ug_*ap6`zbg~;++DrTkb(brq=X7i=-wIht*@ykn4i1z;)#w-H;YX{&!3cM} zz8v0?LZpcWFG>PVpZyj7R6eG-IKmzFbosL!<@r8-UcK*H_%06b9C5F5@^2@mlCawr z;Yw;T+S;$pJm~!;yuR_sbMlfraDx+Y6n(DtetK(f=OnKFSi>F|>85Q91T1=k($L&A znX~3rJ4)RQ>nXrc>*=PLb8@GBN%hfecY#%m$B;?9LTqrnB_%u<&MW46rpL9%hIoU( z;i9%vA9gPqiye}RT(;RF8#1zsOEOlzyvORzTcKM`5FXE<^!3era&R6j)*jC z2g$VmEeo7!nlS%`8wbB+0gm@OikVOmaP?UVd7@@Li4{B^Unv?Vm)-@#BR47 p>bp)D2CT{4WK6&Fw7@+PU;r&Dbx5XGi$?$e002ovPDHLkV1jdt(?tLP literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/grid.png b/src/main/webapp/gxt/desktop/images/grid.png new file mode 100644 index 0000000000000000000000000000000000000000..c4da495db39a9a876e89e67371fab75f3f7ae504 GIT binary patch literal 513 zcmV+c0{;DpP)t9vP*jK+QU@{Ievw`G5`|G9UAhK!5(Ei42tkL`K(N5b zXoH1F$XnnsJb3k#yXx-DH1q8y2wn8j2gApkW#4<>n;C%ruCdrrZhtW-U$hM7V~p=m z3XCs83GWOj$KMp3m|jgL>kwr!Y^=ip7(`Z&0}0#D_8U_1xHb5Ilo zGeQEusAs#dG0*z5IRc0K_5>vJE6S0hj=77&XSkH>)$ z$2lakpKO$hpO(G%DvdG%CXb2`Xbcx7DP2o^je4ts5nTf#~05I1Ur~m)} literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/hd-bg.gif b/src/main/webapp/gxt/desktop/images/hd-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f35a53f82493ea6239432ab719ff25150b5a8444 GIT binary patch literal 992 zcmZ?wbhEHbWMOb)XlG!Uw)WiSV-GeTf3W4)gDuA&Y(4RC+lhzUPd?m!>fw%44|kq^ zxa;(z-KQV#I`eop5S@Lz``qI_XCCi4_joT5oqxRV+~fV{pX|Nxc;AI5`z}7&4?<7( zJ^Xaw{F4KhpB}jU?9hd$hc7-obmjSx%g>Hpes=iEizC-w9=-nR*v;3+Z@fEp`^||v zZ%^KNd+P4{)A!z=x&QwB{SS}d|792jqai?-5K#Qd0<`BpgAT|xP@Z7m*vsI_p<=k` zL5Bc`b3+8jqUOVVVoFgf95xnV521bV;9GJ=6aGoKk!%uK=NlycVH2^_X&&~h< literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/hd-tb-bg.gif b/src/main/webapp/gxt/desktop/images/hd-tb-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..f800edb1060ccf85319d181f7af402d5520b3fd9 GIT binary patch literal 808 zcmZ?wbhEHbWMp7sXlGzpyZiX18}}GS!DtAK$PiHc$pZBEe+C_p??HKjfrFKSk%fbU G!5RRz*$@j#Hy$CV15?!~RM130>0j)7aSVyb z4~n92q-)u+@8@%`6~WBtBhdtK9H)_L+qP&0WXbv#c>QGLJ$NsNC}W9M^OaV zb!!eR%YyIwCCIRPC{M25l)*C>RSnQng@f0}6J5(aq?BeoeK_UeAT@JIdwRSplBUiv zpWAa$>OlrLyPARI5}-uK7EEii$9l~w2Fnm4dBe-oEiP{sqSgc2%^*LYLFwZA=GF2i zLdfL9%#SXvu?c0r9;7Sv2SD3y6L06b9Bu~WHFwefJ)>L`=zRici#c^ai_rlv8Uu&p u7QjZC=SdRC#}q}WS5eO=kFvx)Gja?~dsYXAyy z7I;J!Gcd><1YyR*nIXYIL6&q!Uq=Rpjs4tz5?O(KKTj9OkcwN$8Ic7~*bYB`zdzrg z_Rpu;jh&1fGwS}QHf&P3^WWf_y})bz2`vTxn`0p@x|LuAEZ_ht)d%=O*iw@pia_G*|!*`Y+zO(YkomEHg ztT}dP-LX6CkKfsN;_jxCcek9pyY1B7?WgbVJac#VnY(+=-raZZ-tMa}c3*vY;QYOV z=kFc9aPP>)dq*$bKXBvy@f&Z?-FklF=G&7u-<`Vk?)2?2ee~(t<4@P0e7f=E^UbH9Z$0~b``MQ}&%Zo-`|UXp zy#u1}FW!B7@g9i2zkL7w)raq|f#~D+Hy?kz{q%!j6pV%dDIuWvlZ6?iUI#>g@&p4% zF9YKe2L`4_eio+=1qP-A3C^;-g)VbC9FmT28IHG26ld@iBi6&N>&Ch4Vdj#J1eB|B8xx2 wglWQ-hCn7ab_w1Gjtu@hyn+&69wx82y}jV^skz?U*TwEM|HO4eT7bbC0EYhGKmY&$ literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/launcher-btn.gif b/src/main/webapp/gxt/desktop/images/launcher-btn.gif new file mode 100644 index 0000000000000000000000000000000000000000..a9a72d7c979c0a2ae137f4c4485ad011b1e3917a GIT binary patch literal 1247 zcmZ?wbhEHbWM;M z|KQ8T2Olp!{CxT0$IFjCU48uV+QSdmAAh*@i69L6V3p(dm zJ0=VKP1wXNswJ_;?d+E$!NM#_=l86uwQk5`+{?~jZXnb6k>#YgL4Lv^-I$%l#xKOr zCVt|0qqRm&fotvDf|;BfJsobdY!6%z&AK;|;STHJ(u6teCu!zEs&i77%}S{t7T`50YHne2Gs=+(>q{4Ay+f$pkXLxTNXO+!P& zQ@4hO$G4h>MW!#^dW|=Cujus{!IZM=+?6{wh;uV=MLcMfSh6ynO=`=|gR}oMDx`Ci Q{0f)kWKVmR=)hnN09lAN8~^|S literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/logout.gif b/src/main/webapp/gxt/desktop/images/logout.gif new file mode 100644 index 0000000000000000000000000000000000000000..a4f3738f95d10d7f5b03e994bc7c843ad73b0543 GIT binary patch literal 920 zcmZ?wbhEHb6krfwXlGz>_3-(-nc?p~hUeSOZ!B|vzRT&^{)oR96n|c``+Lp$?@N{E zhXbA;E&Ka6?)T%uzaMunjDpb+7)BwW_>+YZ5$9Hk7594ZbQ5*!;j7zGkO zEO^Mw&LJbAFd-n3nU$MMDq})Jk`oh?RK*sJgeM1Bc-4eV7A#11W#Uw@n$fAyc)Fic z=~79;0B91o=dBt38P&tK$vz8#h^R}lwOL1{c90>2K^x(; z1AV1|(S095-^+-YL3R$V2Q8e+i&_2Goxj`I(LMnK41@!3iG!$S5VDpC$N-1jL5@2psHe+TUJwx}1ot{m vUtn<=8KeVcXBh&fe5FKmMlwoD_z_?L$jQ0&rodZ500000NkvXXu0mjfF-6sh literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/member.gif b/src/main/webapp/gxt/desktop/images/member.gif new file mode 100644 index 0000000000000000000000000000000000000000..216c8397f09fa0b92bfe801f38a6e13ac50664f5 GIT binary patch literal 972 zcmZ?wbhEHb6krfwXlG!kNH(v|vZyGtbocUh_3&}^^l|m_ck}Xb_x5%3_V@Jj^YQU? z^A2$H33Lzi@(c9z3J3}da}Nyl4GZ;(j_`_!@CbfTssc6Yt~y)`yZ=Zij{ zFZy8~>x%_~ub0cbUoHP>p~R<^l3&-!|J)$^bEE95rK&F%YrR;d^l-D)yGW6jO-?!@h+^YI>tNPEanqRk?eBEXIZMVs{J*NM+8~omB_G_or?_HLEcUqlY z6L@c<+ubehx3~D;*%kA0tJ~Xs&Tsd*zT4;WZJXPly-t7jx&7Q7@b!qt*P|Z)54iq0 z;QRl8@4rJn{}1{6Js9x+NYLNI(SMIb{W}u#?`YirWATrVWW6|*{ql6ytFzg!&g6W( z)&BWrFT*Gp&=64k$->CMz`~#das?<)FmSA7;N+0mp}^9`!7Qw1a^TQ;d3_-fEf&R= zvr=lRDrzc@PdX+l8JO_hnc&(t+g#g)YmdU?o>?k#A!RodpKH6>x!~eH-?r*U zgQT)UQm>rlsR@S3X(xG9_=UncoFBJM)ehgF(P^me;KXGX#j;Sz^^}OZUID`di$z{i zdQlg0DiwoVrdXA{xbbq4(~}nY+;eR@6%GGKq>MOD3ziF1yMdxWPyoBg&5<)opEW5x^U%2V`8E)(YO)OjmE?U zxX_IWCMJk68jZgoC_z4{givTpDJ}iC@6B^sftKn?Zr;3^d(S=h%zH%BG$e8GdLP!H zLd2Qa<)X?edQr|b8$HC=D^=G|Vl{UShuWX<%vC6wfb^Q?)YjF!tZ(aVW10+?{r$;l zLRu-I4rF1S;9TkR^-ZSHTQ=RVHY^fQ-qe)vlofuPf2ep|M?pxsdT$1S%|Eoh&y{uv z1u{g>7=KAJQWUaqhntFo*K7Y(FcND9Ql|te!)UY7*~ARhoJ@tB^d&MkjO8C1*Mv-p zb%Iz!7s$#YYIIJ_`b|ak;ST{qE3|MkbVkW<|-`voS1=R^Ar~RU7-7FOfBWF8{ zKM&H{BXA}Fhu?#^wG%d)cb{qMHNxj3>~CyPka8cwu@>XlgQb89Q)K~{Z{)#6^M-L> z6xI6Ns|!Iyxs5mfQJ@kDUBZi=xNDlb5P`5V0WmNEImn-W9$El_h40v};D$<2tdT4N zo4bFHwX(_*Nl1_)9_SS>a#TO`st(m*WUl@pfb;KmVjl3sN?Cfvb* zPuNm!DiRan)KF`E3Wyq0KL*C-;6-*a9tsn|>Tn#g7lsW^3(>_!wjmX)YO$3$G&-H5T- zY5dIe;L*-k7!K9pOStJy%ry?GEP`W50cV-^@U7Zl0Onj*N)k4SRmsUESeRkE2mX4o^4mzj!Iz1DUcop=u0E+m81= zovQuRt-ft6lr<^0qT-!3;usGM^hox`UGZ={7TaOnnsib7BftPct~8qV;yMxl0000< KMNUMnLSTZX33?g; literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/powered.gif b/src/main/webapp/gxt/desktop/images/powered.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ce74b8685a44f9249ef375299eee77377bdf7c4 GIT binary patch literal 2291 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 c>AxcV8}W=ub3z|un;N;@AVBumPzkrCSnD~UG z@W|--3l`-U7R4tf<>cijBqnEO=X7@WL`BECxOq4_yV^N8l~-1!XJ&bL`9#OWMMlTk z+B-6Uf#OdVFs%b3L3T2*Dl1${n33!dG>y^mi_YO~g(7$F-Ytzhk{Bx5s}`8RVbOI` Ig@wTy0E*)@@c;k- literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/scroll-left.gif b/src/main/webapp/gxt/desktop/images/taskbar/black/scroll-left.gif new file mode 100644 index 0000000000000000000000000000000000000000..94fea4821e92d335128bc3400cda17e9b78ba098 GIT binary patch literal 1405 zcmZ?wbhEHbRAJC&_&$|^iH(zmoy))>dBy5A1;u6SHf-#lICzi6_9h@|^^%RxWvhxZjO_}E8 z;^yq;WnpdG($=Y}uGKeTl7W$luD(%vR<5bJWm#p7qqFOqx9_Yxyx1i)Tf6%BWR00c zRNR97Q}fG`b4$3S446gKdZtWj@0qaY;M$bD{DH>RIO`M=< zZj)D0wQBw1rp|6YIqj7E;?lZ?C9CGQ_I8M?nb)-y=U3E3B*#i=8e4gIa7gM_Hnp-# zsMoYMNoktZwl)`5)rzSZb@Wb*&noDfGC3kS+buXwP{A~(EHk61q^v$KIyE;qF1@V2 zpuC~Et+%(TsWmb+YvuX{Vrm9*y4Lj_&D_$Ovlh0AsTr#pTd_-M#b)GY6<6@d=`L9{ zcgpNZeo@I;C8e<$aZ;M5zLCkQCJuJqK6w>&b*&xqmdtha@Nstc?&#`ubar9po9ln71c zB_0ySSywnTn~(M?7?+)CC~P=6S;IH!OUK8i)6)%N*Qw0h^z5XE4)=>YCnu}>iRmhE z$a+o5;1+X`)QCMb^b4XI>6exS%uQ-8e}8Fz{r~&>l-TB&c`RAIT;v)5A_?tN z{WI*7_I~;KA$x^F$ccSlY)V%wbmILrF=0XdPDzUg$_y_)9uegDcc7J@!RF8d6$!s4 zg*H(mj$^X1I~4EAMM`{fmJbfdP-Kuy(unPrS!Z#CFZG3hdtQ#lr6Y=sZwy@8bq>vt z?wQOW>BLd@Vc}sh%NGjACI&EhK2fn0;9SBUQPt?GjuFE5|ZuP@7BWNH!1TCq?pB7<>3&###;l*N1$ zUM`su^y|fAq-5?-&} z@yJSh^~P_%UaeEGPdBy5A1;u6SHf-#lICzi6_9h@|^^%RxWvhxZjO_}E8 z;^yq;WnpdG($=Y}uGKeTl7W$luD(%vR<5bJWm#p7qqFOqx9_Yxyx1i)Tf6%BWR00c zRNR97Q}fG`b4$3S446gKdZtWj@0qaY;M$bD{DH>RIO`M=< zZj)D0wQBw1rp|6YIqj7E;?lZ?C9CGQ_I8M?nb)-y=U3E3B*#i=8e4gIa7gM_Hnp-# zsMoYMNoktZwl)`5)rzSZb@Wb*&noDfGC3kS+buXwP{A~(EHk61q^v$KIyE;qF1@V2 zpuC~Et+%(TsWmb+YvuX{Vrm9*y4Lj_&D_$Ovlh0AsTr#pTd_-M#b)GY6<6@d=`L9{ zcgpNZeo@I;C8e<$aZ;M5zLCkQCJuJqK6w>&b*&xqmdtha@Nstc?&#`ubar9po9ln71c zB_0ySSywnTn~(M?7?+)C_}FxEvW9QcmyW`Q)6)%N*QrDM33(o zg#$Z_`_3&$pK(EFQOQevmm(7-rS!nei{=>#Gkj+YsovU>d8b2`g+sw8bW+4d+0;%k z1;-L$kBtj=7T=yS$K3y*rRyx?fOR~Zl38{wFbugD@IPKK`3T307n(E8<&#+}UFr`l zY42OYJLj8e$OHvL`CoNHT305_mnwa7aei*AfY1YF1|Or7jeJ%d2b6h!9XQI*F88rT zPS{8yvE@Rog=ag%4+B?udx=R$fZ z&)KBu!k_&`!DY7W1dWq(E1u0%@8tUO^7;JwvW&)gEsru8Tg4O>yjav@RP{o+SH>|y>`bV zEA7>MUtYalzyBSV)4C(~cCA)sR9XFI(`hRw?M-LgX0O>i)gtNb)*ETBI~;D6Rp&ZA pXw!bT3VtQ&&YGO)d;mK4RprQm%7srr_TW@Y2p|26lkz4o^RQY`6?zK#qG>ra@ocD)4hB}-f* zN`mv#O3D+9QW+dm@{>{(JaZG%Q-e|yQz{EjrrH1%DSEm%hE&{2ni3rHGbBFz^oEL) oMr<_-W@=pvH?Ew?sBnPc@?rMyE%zCg02MQMy85}Sb4q9e09f)XiU0rr literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right-corners.png b/src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right-corners.png new file mode 100644 index 0000000000000000000000000000000000000000..b6833018582b1a2a9633494b97791823b89af727 GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^Yzz#HIvhZf;X%)#H9(3b-O<;Pfnog#bJnhxK)z&& zYeY$Kep*R+Vo@rCV@iHfs)A>3VtQ&&YGO)d;mK4RprRsA7srr_TW@YUaybNuI9&Xm zlEdj0*jCJ&EB_}F>7W1OgknX22Kx&%a7WPgg^>CUHx3vIVCg! E0J-l+KL7v# literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right.png b/src/main/webapp/gxt/desktop/images/taskbar/black/start-menu-right.png new file mode 100644 index 0000000000000000000000000000000000000000..e5fa2b8c24f31dde305ae002465dc6657c11ee6f GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^CxDodgAGW|-v96skYY)9^mSxlSbxHtwd*C2FInOm zQ4*Y=R#Ki=l*-_klAn~S;F+74o*I;zm{M7IGSvpCNZ!-MF{I*FQb|GC|04!mZU;3S l7&jUQ^7Q(iC#}q*&4&eH|GX)}JtE?Rp91OP07s zlmzFem6RtIr7}3ChDJ|&5vDKKe@gsNL-V3LQ>M#DfJo&`y=3I`YpZFtPMbQbIc>SgeB^>bP0l+XkK D2|F)$ literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/startbutton-icon.gif b/src/main/webapp/gxt/desktop/images/taskbar/black/startbutton-icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..8dcd2d18113e09c9f86e9a4509456cadbe1ac172 GIT binary patch literal 748 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 N*C=k-xWSRZ8USbmP;3AI literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/taskbar-start-panel-bg.gif b/src/main/webapp/gxt/desktop/images/taskbar/black/taskbar-start-panel-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..9794880da17d4597bed347cb956cb11d3b52346d GIT binary patch literal 890 zcmZ?wbhEHbWMzEZ3~;S=EK;^E=#JAcs5@RI_mMvvBdVaPl#Xg3%BdQX!!D zlLhQv9S{l16AT>T4B{Ly2@Z{ptn6|cAsGu3o!JBw-DX%6Ho10-8l_D+Fj2XsU!Jjp zN1%bBk%gI!L!e=SLnE6(V$cjr;pVfmEsCG*Ik0*8`T6$79I{?pR$N@{B&!iBCBR?} E0Q!(RH~;_u literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/taskbar/black/taskbutton.gif b/src/main/webapp/gxt/desktop/images/taskbar/black/taskbutton.gif new file mode 100644 index 0000000000000000000000000000000000000000..df13974b11ed2cf774b9097659374b741de42c47 GIT binary patch literal 1894 zcmV-s2buUsNk%w1VFUnB0r&p^H8wacJ5-yVp>T6{2pTh4Wo-r)Dn39$fP;pDh>df0 zc}`JPM_YZBmzf|VC9STnFflWAczbw&g@=iXgocT0ZgC$nRh^)se}aWePErI02|z(Y zGC*C7j*&-HUlAih2?`5{ij5T+9zjDzDl9K3J!32_E+Z!^DK$!Ye1EI2v8k)9Ph4hQ zU}Kh=otc`Oc7KK?Cn*F95JE&oKtxC_J4hNWPCGn40|W*P9ywZDT_GVNFfufppP`nU zo&p95EICFtI64LxEh;xoY<7M=LPjPkF9Q@MLqhb9v>wpCzqL=jgOL+PNae7TzV^3RTeuj)GH%N_; zk~KtNB`PjhV{4n7o>5g;QdCuwm6%CffUmK#cY1v$C@Uo}M4O$TQd3nRB`G5=Ly?k{ zdVPS7kdvaPsiUZ>FhFBuZg>X?3@b1+EiyJII$&&ed~J7pe}RN!ZFFOAb|NGvLq|&k z1qT2C00000A^8LW00930EC2ui00aO~0RRa90RR1arR85A9mqmdDh5f~2uQ=+%oxWe z(uhQx_#AL0iGq|K(JHwcLJ)}fK6D|*i0fKm>D1*z-oE9kn4cNjcMuiME%TS@GVHXuF z8Z=Rv7n;g34g9EBLQTaAYbUIYpoT&Tb*x*cvC1nVVhIx`lbF!>r^JasEy%UlS#GC} z^Ez>&$ALo~j+*Og+GuaHru!N+;L!~K7(bwl`7$lix7fmdONRFuWXPXSzrGAA`19-E zPX&tq{{Z@T!hk1eU?6JzBq)$61+lTn9UZg+%M^Nu5k(k!fN)0`efaam7p(Zh1s5Io zBZe4!_yYg{qWI&57Z~^h0R*b}(?u5%_+x?z3ityC7-RU;Pd`BpStOA{A~_@(Niw-) zlTBuULqDV}kw!m(oZwFy|13a@1_H@4iWY1L#Kjy9{If$EgiN5w4q|+g2PzcZYU-$`W>HE%X~=^}8vdOBP>4K+obeASnH-m#KfLO=qX`=XyFnPlhVkKtBaV3D zi7T%7;)^rRc;k(~n(*U~LuRY(w%m5>?YG+Y>dzVE+WOBSFZ|;mgc4F{A%+@q=pl$A zl4v4|DzfMzj55+_BaXiI_~VfTCt2{52>0Wp!ck6H<&{}(+2xmEj#=hEXQsJkn{UQB zXPtNExo4k$20Cb=hbFqHKaD;b>7yuqWjMTsce7%IL>&p$_Boy z;07M2Tp-B|D)=DC0q@ZNvBnM1yn#Rv&p5)47tP#5P7(<)GXM!N6i`7qdt3v|KGk?& z#u7DLv3cj4PviL#(-^QhH9~Bj3jv!4ki+J+5VQFg; z<5)K^NM;QYmU$4*O-BIn13&ri-#`D^*q;Fc$PXc)V1EP{!v1m)fc<@-7W=aS2T%hK zb?gQOvG~m-9DoF`SVC9G!Gj3#@PG%r;uRN2;RSjifEN0|1u&$8443hS8ot31IF!I1 zcDRQ@_)s4O2x0+4SU^M;c;JX0xPlU^pu{Uwp$Y~t02GBl#VQJc09YhI4z`$s4|wqd gPYB}^EI>vJ)T0DwWPmuEZ3~;S=EK;^E=#JAcs5@RI_mMvvBdVaPl!=0L7myU@;vK z39^%c)!~7XUR#pZ@x`mcZW|fMoc)|~J9M764gX*J1_J>F0iotbhXxH1sQ`^stD_O? aZ{&PC^tNjM{hkURz1ioJ+M{Hd7_0#pA~@#& literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/images/winbar-bg.gif b/src/main/webapp/gxt/desktop/images/winbar-bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..45295a6a674c22f557c96ac3de4c357f030ffd5d GIT binary patch literal 888 zcmZ?wbhEHbWMNQcXlG!Uw)WiSV-GeTf3W4)gDuA&Y(4RC+lhzUPd?m!>fw%44|kq^ zxcl_uJ!c;8J@FJ(jXZlv0>0f!aYsH10RhK8MIyY(c`N?Z8Ojvhi z;<{^7*It~q{^GPPw`Od(G;`zSncHs9+x4*bz}Lx#zs@}Nb^gh(OV4~=eeT z&))xX{=t`v4?bRe`1$gqPgfs*eE8<)^AFz{M!{$ZkQD-oKUo+-8g)PfC{HkO{AXZX z!eM0KFoD6I@0Z1m#}E3Nt@xfW)KQW>U1m+;1-7G2Ow9r;2?j^` zo9%eM8SFT`fUnt-=TSyxK+qhNKHthKL_ynT{_YNC}&5h@{9LyzR4{l+Tkqc_^V036H-IfyjX6?gr_XqE- zc%J|F=t=&_aa=`d`huKCpE%EISnX%vO)lZNY;vOghW-V2E_p774u%F!h8+wIJPbb= z8Uz?57#oBbEEpR^7%CVWBp7BeHpnpCU~G_Q;5byz_2s#|_di8}1SUp30R?78I{^h2 zMmK>4ER22v3apHA0t#%5X#xuDjAa53*cqDy5*q#ori;dKxXe5-g*)WrfvNl{oCl`~ zmS`TFF5KdIaEADl&Vw^0mz+E}OLoi8gR>QmtUNF$?CW>=P(}v9$@41Ty-c6q@JaK< z{AM<<7jxBu+(Wq>0ZUu5U^?% zvTYN#?+|tB7I)}W4x90B6AT>E42%vH4GazpjLaM& W1_cU@O{_dp7Bf6HK04CCU=0Ai6B!8r literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/desktop/wallpapers/desktop.jpg b/src/main/webapp/gxt/desktop/wallpapers/desktop.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8e1fcb0d1a8b8dd170b02502ed19a148d0160da3 GIT binary patch literal 84237 zcmbTee_T{$-adYxbLI@gFyJUh7!hZpht?uW?isDRcdTY464ddl5V8K~VQM{r#qbX|fTi_)wOtF>RB>wW0?yuN>a zzu&SV7|yxReZTMPy586OeV-pL{4mPQg?Hb3H{*DYmEv#qLzqoB=z8?Bz)ffTbWWJg z{cw>rGEoq8f*|U2I#Cq$G4X~N{AG?a#l|O^rNkNL88c=k&zUtdDK%-vjFkB)sdKHi zc{XX*f`zwO7tXQStQ>wVMjtcHV3=l|Ib-Hb>;Koke(2*4GRBFV_80r{FOC;<7>*&< z7-wcYCkVVw5HU)8atnUObkoHdHrFbB;@a|v8=*J<^VI3SNdLe) z@BVRU_}pL4|MkLujl4fL{=t7=`S7EOk3av%7n3)>{Oap}-sG4t^*H$V)C2uLo(I#< z@j9KLi=pS?_)Yjnn649TF8z#EYh%i566Y-m7^K`i2VOrJJAY}>XEQ6FJZnt4#r^(* z&*_o0C;ET)K=uE>p6LHR(Eoj&A4Zr-;1D*#baof}{FU$6KjoaKRng6QnU@Q)GWwUD zsiMj&M&^>^=v(Z8Ad4wv4^6VlonAf=;f?(Ja@j*C{9Hb7L`bd;$Sm~(FCXP(eU>T? ztYd7DWtzU1ShdJ3S!#@zYpKDHB5W~ZwW@e0{)ZbMQj#Thr~`Mq=@qtdTR!4WtSFYH za4EBMvZ_;81)0~L78z4QJ}>XJ$!bi6V$z1k>sls};z?y^~@KOG$YjWJz zUg2eh>tJO?A(2UVra*q!&ecY_<2w{ij+0|wT89yrdHD)FpPj=<>}*Ui8JQDL%`2v0 zt+}_PJYR9iB4b{DOi7dsE;%70;MT_j#v~=a*R(9k1?3Do8}W0p#HJ52dntyBL5ux< zuI8GYzz3Sef~l#qvk1dSFBXWrlKjLmW>Live9xw)`7I$;7ghycNm7#eyjgrVvJE~9g^VlJL7V7B>P z^zX6u#zAINbG@!%lcD6qoZC ziC&?DkY7f7u03g&DMX2qq8L##Qx-DTQYIf`ox!>9o7fImf;&Hdm(kv7Ye<_cqVoV(-xp z%W=oCWNiJHKZbN!3OyHAfvzSF)Y0tzc;O0#UrOOXpWMOL`i#t>Al`Ji>w4`sFoRx1 zg)!FTb%t+XB24TG1u?=TfI%+%ChBqxS|x4Yyuk-z-%%^WgIsxTG%2~NtGeecf2d^H zH)pGRLI=l_TJa0mFvk^X8p5$C6c>~+9+eMVDDzqoKlZpLuBPT%LHX`=Y;`XSx!Jy` zw!!RNwViXxv2si)%kyBD*3LXVkzYUV?17#_CL4BqmMGbxy_U($LIK2H&>v`Qgf5sV&C87GDHrO z!XD!yF6h%?6LNC={5MsP)6O}zx#ZL9nQhdoUtIA^iM_e9jUm3KqNT_sW9#)|URv51 z=9?xP8@4`|CaaP{D+ZfC4M8F6U9u6oa74kZWlgF=Dke15%OCla0_`MXFBuVpU7i}{ z$4@Z(Kq}bjze2*pM{i%x?BN zr-BC95V@ilb*zFSfCAj2;%68~GNDTc1qE9*sfww!YDE;|Xb9>pQkgh#BAGBjyW{+z zt}#v?cqQt>umVLuDQ(a9ub^kaya0g3bpBc={tu5b?vB@w@OrkejyX(rbK{q)e!t!P{Ff@<9@~(w*by$W!H?)# zD#yO}jOr-`A`M+Y#QoaOt%&OHsCZmB$`)%dOb>-=-U$Rtc&IH_nbT{~xJFwPi#y?c z+Gjw9V_M`KI*dsdUf=hq!g4<1^0jLmq`3foNX+-4n}x2)dhGjZKUNJWC4~)xPN@i2 z1J=kfM{iRS&cz15bIHxcmWp=3HboxAq_5*gs8$64MhIcceXN1f0AVvo1;d=k4|{vd zusA<1d@?@i!@wCZPJ0S^bbQuW%es64&ne{4 zHR?KN0)o~QF%Y1{-r916U6kYAAh_kPeW|j9Dkp-uG~XB_v356x%#S^91A$jyEfd;; zYy++miyI@R2i@suc5?*<6vD`WHBSYgb@RoXYY;22wTq>@WX>Ipk2sTB<2$+4;E9vF za_r_d*3iLX!B4;fkhIRt&S!SpRz&$>^9Wlr*^FHsZ>{iJ5mLSEP#5qL@kJkNBQ`VC zMbmXro1Hs)zFl-C^NOpcWOnn^WU{sA1B^Dw6%ZmPw;%4}HCk9J$3-wCP)d-=c48Q9 zAGF{p&Val=MpzkF(C=W0!9qshA}tO9hozh4Cvi`1Uh7Nn_rwvYvu^C7EMVpkDeQS2>tY7k-+t+)lCM`Gd>ykQ_l+&;#Q zz?$NViX9pwWqY}ulWJ}gm_v}ja2kaZcWHW}RL{J&8aeiBFZVTJ(<$sngPJ=Q!2PQ2 zj3N<14xtobvuotjxSblao;LUNmNwURjbR{Qu#f~~_?H$Xn5JM}s#FwWz{($SgL`90 zVeu3zp)TNDGq3dYmSk8Co~*&|kGA&WY}70aK3gw-I?MB~XD=;LI#7<5L8%SP{*A?DOJ0zc3&(txjs@!))ksc+*17$EV64<)3 z&0shC>Ocj+`pu+dlOWp4 z2O5wbL?rwq5anc*IXZ>5y0bM0sF0wF?asXB0YDSNP&`M^+}Zu%Xt9HRwD zM;vzOEyxQnz1R+gV0h1?iqS93nGCOKV+npnziykQ>N2m(F~{jcB1G!K_lZ4RLBGx& zwsTwEhAg73FYq&4x3Zo$>X*CETJxPmM9dTAAyPqFd2$pn0CDTy7sYaym9i&hsUEv| zIAThI_32sL5b^Eh^h)>{t&L2R<&-St>@B1q-b<+(M+;;mzes0SVOdL;0 z8f2w@sBo+UqQuJ}k01W!Q>u{m`gv%Wi6KDL%xB!}*R5+XL;h5+jrOf3JG8kMRor|W zN{G}3gcI%X1k9QR-xrQB+7~Wb3dldiB18x7fx#yD&FyL~2x$aq&NtCy{`Zr>iwt|} zj}oOy&9Km)2PkzR@k|hAgmA}qB{BRVVrX}v&VEuA5fSSd^ou~-h)JeeM_G9=gAd@b zSS~PHM~X~X&oV(wtEb{6hAR?Ymuc%ArwIrk^hVe+jbedsasoDYBbc0o3jTu$q73E7 zZ&)#usJ54JI}XBu!UEhxk~5wyQ_R>!@xQ#%-hK&758c&@u)uVTdO=c7BBH&yX8c4b zP<7WRWIpleD13%2N{7z&iQMkR4YDLDJxlet>|Y`wcoJc)!# zW5rH9xO=ugbXqcaiFi)6H=MAVgQR%z(YL_MokIN(8*oSCj<+K=1?Ah>+_wGe;ZRv#2S0kQ9=?WW15vKedmBk5JC_oOKkQ4y-pgg! zpu8&KeG@dGe$hQ;cC!3RTgHMMoGDJ0NWMCe3&NNXQYUdsInkC+HIqY5;(5 zyjF+~yJRW@5C-V+Lt_C^NQ^nkODTW~<}J{G0}0+dqEKQs(2b_Nv8u?eHT=Vd)q_pM z+ms3=5kOcYi&kT$7MOes^#0m%tf-eCjXI?nX%nvIEVUv)JB;A3QwVqR(=T_hh!Zy$ zy?-aj64%ecZcwBkTMHKllc!>yGCT2sY6ojqMNLhciZPJ132X#&6_^=IX6IIeG?2`T z43vW{z|(xR8>$rO+9d&4D!7*ZhRSy^x1kCMfP}8dGUVrC;hNkTO}E`4r%q8#yqiHC zn1ZaTn;*JmJ=2XTDXVEKB{}r|9{hRDmWk-7_4hR9AV?c_4l_#AczY-|U-3kpgItaA ziqi8`_w3m7t&dyOMU{ceue+t4Q6549Mi(Q@A5*4{sUkExkbBw`6kDXJ}AU1}6c){S_dC0?CVM3PV^T9A<@8?wMO| zMtMbKG5g!t)u$x(%3U_uRQa3qfJ-v_xydldBoImG-WX8;Ga;I2uY+AJ#-tzi8Gi;F z!9*UM2y_9)Xj;oK765#f!XwZk$IJ40U{FPUemLz23%jv}2!F1^pCKe;q!luxNiZrEP_Qi%DtqFV>&j3AaS^cgi&D3f$L&w4+_E7z-$+v7ykFz<~=8CD-J} zi0y#u6FCw`7EdymOH!U4$>kjf6e7w5zOw>85IqVeKx&6L%NRz^<;R0L5xQ21LPZ-F zkuCrU*<^MUf*jsn`mOcv4=JH%!H+?<{(lI|#w#iLEN#Uw7b}HxV^#f2YbFi3*uzmJ z_8Q0skv5EwOSjMLpH#`NDdOT?@p#~N!`;xw{2XW<57$r(!qXUNLOjM0uyR!jUW0NY2U|~Mm<8P z02>NFIxLkiA-D+Pki`AUxQHL$SIkagFWR{}FJtM7X-U8lb3 zV2|4qK_%6to4A_7Q4M({N}>!oRqW7F1AwWUYmkkY^sp)-0g`D+v0I@!HMxEf&_ zW!~iYUh%XfM*96`a3{P#0O?z+Mg7Pl80d<0+i5#PB zpVN!HXG-W)1Ue{0nH^)Pc#g~MU=Me(bnI60hLbV0^viy(V4x7WU|3{)E0?K)w_ik{ zA$l5yjx5qW8YpqeCAoe}JBCaSOfH1WyNAommgd)wrFQUR6+4>xveK1MQ+_skVZ)kJ zq36{Mn`E+chuwWho2n^uGB<5LTfS@Mx%yGZh1}^_pA~D%U5=*k&ac#r<>0<|rK`yT zti41@vZ;BidDG^o^IAb}v8;Ra#b(>s4uj`P`)SE|GWfGNz394-ckecYFbKNprkBAA zDPr@3z6DywUS1$qDebDM=6uf`Nf_-$$|UTX0YdpT#3Ic)%ZO))n7QQgSO8c#4wd`s z%71o46tWly9XC6uBtPzFIgq-83|y3izfGGo*R|qXQJvA4PG3I*& zIv9#512-&-GLTSe%sSm2Z@K~0z{7J`q9&{gO>NleD4{I%c8NU_<#*nU+G^xa8RX4+ zuI6ucOQjpPl)ScI8QEP%u^fVkycrfk;xi$~HORo+UIO5~VOKu=al(NYv0!U`J!{J^ zAk)nz_yssg1$tAs_aJBlPh)vms>&yG1;Ug z*Q@^3y`~3y*;`d?)E*L(v9V-rBbvOf3tf~Snu@tF(t%5pondfD69qelis6Bf2~@~> z*8x>u*aANt1PCzk=;ndN;nqMr1G*r%A%kJ|&4YZ3E#P;s%adWpHj$rwS&{3!-Zr-N zsJmbo&I@yYUQqeuYChrX18h0c?Q^XCO2B2fE;q~vVXnmgLZE!^(RUa_FT(bFtcywg z>6u;Sv8!)m#g_I#T5DwO>``UL-ab6N1gy6K$ncfoDdvcW3NZLN4yBFTx#GP3&t;Ff z4G=X$%Cs()kx5AlOba}a(1kezu+$)5W|3^x`zklo9=Ef$8!1pgjvf9Csc*tLcsw3T zir@fSpnVa216p9g{Ru%)3aQ__*`e1kAq{fe@IRyMNqb`Q1d!&QbS2^5fi9N)+gY8- zQl%AB9Zqk5HUGV;y?s2wYDC0iM%=LwyBk?*#dU~@@XzU-R&OI zFRWQ@D5lcU<;mC`=L4oYy~w?Z*SdvO*a-mD=uaEn(Rz@e9}jAQ`i3MAGK5RyHsdKH zE6&p|u<7%i_+Ft5VzskQZsvG%g^2?5DM#fK7;n z3bHc%Zu=dP4dWsE z5J7}OR2xOT5uQy^FXK8aalJzX)d;_UO7e|AHTE1=U4^NbN;WYzS8k9qN=7|&rw8&+ zPj)gx2DTJan9h$DLB0?}OOSFP3-Lp^97t$$Z+(^L3d5)rlnDDaQm*tW=K&NT`=LnZ z=RlCp?BCxj_Fd_SYjSOe1WGhAPY0V;NHs?_w?YZ+yE)v`IREkv*1Q8|p#F;v-Gyh} zWf`{d6UlMAZaG^WYCv|DZ!o7+CLZJATRpGl&UsqZ!S7=5(^A;uqSxd$#dFmM-={y_ zPQ=)3nZp#2Jjgo_!cBsBvtdb+S`GQmMC4BpGJwqe11FqG_L1Uacd!0Q%I){exR{Xj z`1gOApVe~ZcZV1JV7H3BbftY4Kh32M{QE^)%!9xux2uLD^@CP7vx1RLyY_#s_ij` z%nCA>=oD0R9Af*ugnM0$LxoJb`E1ef+_ENVq@8aX1Mc`8=4fT2|+c{yb|AQ-ih zDguZ0m!6zLFSi>}3LtV7Xf;fH8`~G7OX0@?1>#5*JFuFxsFqih0ms~IGzUBi>E{u7 z)IvA0NHQR$3ZFoA7h3=>Hp2=JvYGM%U>LT1>;P(3sCx6r(d}`&-0XQM12{l)+M*Oj zzE$qn?Q-KhMHudK^N*p<*+yaVQ`W4QC#eMS@zMg%6Llzy%IO@U6hO4HEne@~S*Syq zT#M9Ne0!6-M7I$CsQL~#1(-W8mz$y`u>egQK^O8y3~ehJweItT_K~%EZ@E;;H{$)CrgHn6sjO0 zR2XFAL2MN)INT)!em=`4<4t14DKMF_te|NgKgYTP9iO7CeVwK+zeiX1Hy=7Q^1s`C1yWUZT*m<$plHMA(yA%&^A^HTyFBTYw zU)tZMR7;IN4%7r8D64+MHQAWlLYEQJUZ&y~Mu;{O+@AyrENBczW!SLmyBXzRWJIE@ z(5`wsQR}?Gw$=RX4i?Xx!2{drC#X{K$?mAD(`)VQ>&vmr3!K7rIX+X>?>U2{(gQ-N zLM&aA+xN~he~w;~Le>01l!u`8m+F@v*ZlgtLzIBWG@a7 zIH7pjH>LHg_Ej5+O8yC}5~6VNqN3;@g8wkL2C3wgz$CQsmcF-Q## zKt7dBpiO5U>gw8T7E<=u0j1<2w98>M*tV#0KTGmobbj>l(p_ zjTlVdzzOUozB-;aH+&-Zf8o)kD~SM-^mapyY_R9@ISyrH5n2OihfSwv0p$R><*3i=>U}pMr^zR^~cox zM*Q7z*YS+~$L8nB5!<%vtZt-QY(q}|qa`PfU=bO_4`%NKERQ4X`&*F#0-!KuUv(pm zp0;k0(1SU_o&t@as8dG?aW<)Qr19`0TP~x>4+#)JT9n~j1HGXBs)^l>54c)ZQCLXz z`h0Mt{oPLx1}wGm@9-`+ojGddE(~+`=v$33g{=DhdnImev7B)6euM!ssfboLom%!d z`ScSfxbm?PtVbS=K!lcTpMp*? z0>*qiyQl)GLb~0~fO9aZpqGgD2wQ<(3MzPnPL>dbJ-S2Sk{5I`t*+d;`KRoqrgZdo zD9fRZn136UY8Fz_XaBa=$S!eJ$WLs?J z!LWPhTA#@`oR}zyrza3=2ETp*p9pAUJN=yc=#f1rSe^LDl6updoO0h0vkTE`l+ zwwOFpT)KWcyAn{Z1a{pV3T?l3&2xBB^`R3#saW*-!=Zil@2cWW^Ywupm~vG&e^O0& z?D5-{L}(!n!lvxz-Z>by&l=moD)*iBrDnlXWmj6EonPZR)P&wJ7L{g{;*je11)~T) zij0JA#e~Y-@4xRwqZ_Q!OcYpazJ~n>kJOtr@Ow-qvPzV5zdvC$p>W#tWj7z#|Kiuk z8K5}2DLzuaIIqkMSyX)>Sb<&)G$M?5=mwy)A49p4G6gzXz(tmX8*3JEHS zY;ID;Y6gN6%v_^!B$1x>6?kxp`&br|TCHnn)o~EqI-*xLx0J>6z7 zw^T+l7--V8cc6JhXIBLsJ!P^4GmNY8o3&bg8Kw-~1gQT4d*Iv&BRiDP!O@IMlLtrb zWwi%KGq*T^e1v2u6(JiX(SnsrN4Uq)7I|^Pnd}C>uE#1`4zS*EA%3hfRMf0sFn&g$ ziJ$(mYN>&=LQ@WkCU82ODd!AN)NxJxjQYkLzjCCCh&&X5_TLniH$>&=7dB8=jJ*eS>lmp- zhooA`?B=I?_#Kce%O(BEf{cSSwAC{%?+ILm<8D^saM&5hqt}zXyEmcY{@|l=_K$E#p z3V|>0z3Y^cd|8p8QCjTWv&eL=?e8_LfbV|&Nm^B7j9YnVGiadS&jubYC!i@S;%Ypk zu}gizIk;Cl330gH=ao51;!Ax|q2z;(3gj?sBQidOhJH%BXWpqH5*7pn4ow9?8$?u* zC=d53LwgYQ_y8+mf|H~Yz^0p{q=rtyVaA6*umn^fCD}rqv#t&g4MIz<`A`UT-$`{j z?DVA8Q|+h7;Yk|fXoSce3pB?wG#0f(GGRI*^O|sZWOpe(3;I68ss)XgtAc3S zGvscNBP7FBhM_;D=2eru2uFRDs>9BJUgzz261irC>NAgv&O|68(o*rL!EkbTCn|2b z*D-Jpw0Cp6F@MS3V?=_;E@Q8whY_&^rX!1sLGKzmU3T`0+}r^rfl9F#U5)N=UV(mm z->^R8Qk1G)#M(TFG*RlO1Y^u$c-(Fw#h9C=Zkpcw^fk|{M=zgy?9Z+Len@?}BKyuGZE=Hc z;Yd$x&_^o?#QO3Kj4X{@6Mi7g#DsHo@Whtl8Jj^;PpP@+?2rpG$n z-Y_yM?}}%iVw=%gt`U6t5&t3 zfv-KG6FB@}FQPChprn12X!4>%5Cv`aP*rR&KN-c|u-6e!4d!80H}41rUL!lzRp6$$ z?Z{pSx#}xQXscW7JE>;Gz&s?ncEgo|hH zD4$YZlYooh3K46lvAE~8XYl#z4HK?l-OIYxg(@T(c=QS|p( zjk3GtMnSn8yK~>8f!|!amV5j2&RJJ){a5a4fJrpzm>rHc^`(bD7 z+?Ozh;QA2VwC||Qbfr}hqQEjBo&3%_C`0}g=_K5dhqmAw<8Bt3b>^^JDMGTITH}eS z+*kKG`5ZYvur6jlb06q68*ujrB%Cp}`_{3!vyZUIl6(Qki-prqmE{P5qYR#R4V2y~ zMdIm)M!UI}sVRU-CbH~QjrxFw^ao);B?dfOFWWF7b1_2!*Rl@iDys&In*0;=XpuH| zrob!EqXxmSOYn=JUKD=ff-y(owW1U`Plu#z( z;&t1p@`AseplL1v?kY38=^`pbk@<~V=;PAWRT>jpicypRNz#Dn z1puvl%_E}w#yVvg_(ds0dnm}BY+0V7TdLa+Uqb4;HHy9{ z%t0z;iU(Uo1K1NCykC2*2xRckHw3n@2tycfjHZ6@TTDfvnk{r=kzr=2B21ObKpeUR zgp^FaT?QHqTXCfj%n zK2y!*I?#NDcD_XBb;73#Y|H2QTa_p3Sb~FHN~si3-P7w*bT)lEc=H!VU4NASUb^b) z-oY+C5^X$f>9(O`rj1SSU{9P!w4m`}4}8{Qu;TM4yPF#qy5YEU_Y~&(s+18{s9zRn zGMI}kDGb00y05M>l%-TqNW!o0><}+TZQ`W5z9UzZ6oJzBJVNGyN_5o-3%uK^m4h$WQyDVoLb#BS-8`6GQ^?mNjik zUc*40FJ@0r-tdR}4y1A~!oW+q&2W0l9OQr-SanXtr+KHT!rRtR+T z<8m_OoB-F0K!oO8rmhP_g&ofiB8E(?mL!T`eh3hX@QuuCkWgIb(+0Ynv(f(hzdas! zWEp>7Co``bi_-*`1L>aDM2wD6n~VVjsN!MB>U0jcab}^?v>83$xK@wTUD6sSf2uR` z4_ji5^x>vdGKx_lR&F!{y^AO)sY?DKHc@m@ygb`-naRDedr!8zmTkuuv5IB;{z3lDX{mRUzk+yl4QZIwN z@C3W{AAbN{p#eQ$^mC#$HOn3LW_9x8N1djPo&1;G%s~JoeCtpu5t>HXP8i9AJLi1s z~6oD;b=KYX(<}PGf={Tiszo2 z3WzB>Lk9z`A~K5^v-2UOMLy7iAfi5KpdXHloeIb$hDqp!Go=+=07?3I4~)11@!}vP zim4Q?y3wH~wKwv6m0E{_LgYp0k|N*iDy9P5uz!ps&eYmY?^}Klo<*%qqK0ceYRmls zimx&4Wij$!`F&_=3w@e#X>IkT(hQhy^%%4leO`!P9+n$D(QV55K^%U`57)Xps|rt> zrxh;32^lmvbY}-*Am1W<^5IhUxZliHQwsoEAoAo`#cpm6Y)31)Cy#o&VEM!gxhdSX zs%^x1%&k;qb_;%{dTwpBxyAktH=Sch6P@Ov9!&_kf5Nq+|AU^Kd&p72P}b#2GuBGde}-Q-1oIQPeQn z-2>GVawCk;G->hD^$+(Ah5q!)cK(_t@zS~D*`}N-lhfbxsV(gvRcZ)4mu^|vyM0D` zY)jpc9b3wBb+t3$Yn6Sl5or$hUd!G+6`I=4aHwboz#gRDQ-0do5yd?1b6EMmD%G8a zq@vdKKYUlms?&a8Df-)wu~Pv=A2`qgWGG_SJA5mY1Wess{R&%JAWnSyGGI!a4;w=s z?*f$Fj%Bz;4P?J6WwkjFPGq$}Ts-O&j1M zNtU8Y7OO6k06#RIFf|eh@aj-V>f{wlP~zx_l?iDkhTH@(L`^#;l=2(=H(s_hR(3HV zXF~b7!h{SMI1AfB_(WE|0Q0ABIbzv}#xgi;5MJ&p9cBOwl56izkckRJE*||JBo=*Y zE=>IiS&7;@L4eP%lG~fxmEa!3mXA2cfo*j^1>ZJ$;T58aw1+N*hF`>QT+BCgmXXBYZXd_7(p z8+7XX9c3{WM|!WiPTf3P^PA6J&v@qthJ%}T8IAHiQrN*7AA`z#*P?n>Y*gh3cG7i? zxuZ`}DWj0BoVe1;MX-^wK7OZ%x~CU2T`?gOHEFcQy>Y_Ivg?LJ`m_1ryggyn1G}G; z(x=~2LIxQ!PPxP*U#e^lL~zWkh&63@sn7E6SSt>A@qx?j#x3}~fTNsn%TIT&W^C@C zD^TOg0@Xf4*&t3!UG?%Wb+KD=(nRS^fI+T>(J?=0KMQRI*Ib7 zaJ6I{8}C51a*?Y_YgXM|2VMw!3&0!rEL^>UayrC9JvXpsanCvD!YErNbR##IB3S4` zFV_oksWsNzri3KL&`pgMAYZ;2y+Cx_#ns`9f@L*2fAGyt0&ITDAxWYWVr9U^d%CR2 zeoAir$Wmzo0BJEsjk%q-$}U-S|9DuCBr37_vN8OpO4VIK15R4qaH6?|`Wlfg1QF2s zeZy$Kk!I7ycyH|NEZL4xL!tzqF+RM@kVwk3_LfchOnH*lm6@ z?6NhJ5}G@zK*mf5!dvd<&iw4(nwMZFh6gbz911zv3Mw;jE4cz}Ne0vXDRe1a3{qt> z3~mYR*ts)mLa#{P>o_4e#KjzbA7ai80cv2twCrD9=oG*;{Xm9F-4BNd9y|D_qV({ls z5DE?^$YM$@uw_Ln^>X2%TJfA(JCD7T{1J&yrGh3T9AXJ^0{9EHkH*`XUpp5!-G-z}Bjv+g(iT3DS!5YgE}&brYz0tL62s%E zu*<%!+UD6a(#qW!6g2+__DVcgeY4oIxoFlI?&od70aeTq(aRC#(Ho5iL6fRhZ;*tf zKwOL8%$-*fQ;RK}N7yr@qybVMLjCf30RS)bPQ+=tvGVO9?pIw*3U4}$Qm0zXpxTmu zyYR1fHL;8YcrsTX`GC3uxeJ3#P;rZI5v@lVhMKCsdrPLoUUjOQ4xXB^!%*r&hlHQ0 z8JQIUe4b*TdJ7Sd)JDqtFq}1`XosLMDJ!;@{>xT$jzFC0sqGY%_S}Fc7r!Be!R6$S zP<{%G!#E{I?>j&)3EKtSZm0U4S~twqBBi8l6QR5U*G1^Un5OH4QE}*4`;xs2xr#?x zj|-IXfdf?~717&}f10%2p&fUzJ&n*vr~ci$(H05ySF!#>_f+X551=8j6y_o0rV6KU zA)WZ?aFkQ(qKZRltWeDG|08U^SGccG1p?wa1-giCTfQ@;3QW0S=!g!2L5Dsaieb-& z)dKI>=J6)aXgx&@*D!%2ZlPotr(1ANC>8Db7B!c4nvJ8Pgr!p`1i3+{fa{VQHUzW;VT34C%{f#|7nj_=W zA9yLYup}HE(D0J$fVl8lg?&-zlZr|>F@ihnyob`5ngWq^_$*gi#u0wrFU zSg5lPn?v0sg1}`0(mX^B$s))gsc*4$iXq48ti5dMcI8{8$J~9l4s(B*54lq+R0pDs|NzXzC+H9ywcpXO4e3Vj(O&~?^DG4bttY$3cL(uG*Mh*%L zTN`)6wGQ~XT*_9BC`YxHxK^9WiYf#R)FQb7INhbm6&Zuiy z)P~e3MW0Ub#yWKAc1t4;f3a?>YVlg>q?DZQz}lwx6BARTws;0_RZNh=_UorV!I|+lpIF!W+CQiLxo%ov^QZ2d z_Ba0-61wiqb9weWgCrp{)u^8(nW}zZD<^S&^QARy%s1`dkrg4CfLTG+udt^AjSk@bG3YP;LmpPc=tb)eYP^EXUB;r}+^%^3Xje5G)afL41-92q1&yOer%Gkg2y+UglE!dttf zi@+uWbkQM@jfZ^Zo#@h7TT|vKw!p!Kor@$3J&e-{Ma9N>tqmxA&c{Ff{vJ-Nf!fAi zR6HFxSOA+PuV644?=#>e#{PWq{-RK_E#RB|g7^d5`xBq(-VbhcW^c{;C~jBz#84pS zA(2^yF2Tr;q5isNl24q|D>fWPCy5+`+B?ivbRVG(%hXNgs13b)Ctn@RRnkTjbfYCH z6S8SsEB*~p>kLGQX571~lw zH&pKKnwO5Uj3rpWRIhOSO2C*5V~9PS^LYn9{-3p~psK#i2{|DgGa+vk7ycFvueVIR zG1TZ%YrBP48Y#d@g(G|jVIcBwxJ)hLPGjt9E{zBV2Z0M7M*AeHrx6!=2H~?nU)>Ig z(Tn}SC>2ALC$D#+ia@7Qa7}zS=z}r?E8;CI=yE7vyVv`2O@+gpCj8GDrbA%yR)yFftK5ziJ@kx-Sy6O!=wd3?o z5iB%lkE#X9GnA0xP1gg3grWBMdF`i1lo{=14ntmU;%sUlGCkVCx^0J1tAzMsU`u6v zDI8qNhXF=;d3xJKft-&X{;8P94)f~eQ* zM=K;KRjbN^-5ErS&MVZVuv}NJ<;X7Esh!dAf9_fQpWMzrZ17&_f9|>GXlZ#BT#=E=s!JBhH_Ez%)6gP zZIDPRcN~$WCnG&VQas)uO5rTD{F@q(C4?#R0BNQh*YQf0bxi-O71Zr2P0K@op_wh~ z8qQ%qTs(ngPWyc?Q!9C8CYlmPvu;MMY4`oX%?{5U3aCPd{&qm^C>#InI$cgo@r1nX z%%AV=-rB>-TYpNzo!BffEvU2WvAX)EPA7cf#e8Lbl)ok!oOTQO3o(_1T;ASr8Cq-B zmIq@{BJu!$OmJ>{v6mn0tw#gxXubfble>|#5)5KV0LKt=UMko}tO;%5m{R?U0J@{X zp3OK!ueIvR_-rbtR*d2$Sg)fN2o1q& zf42k5IDH_t7akj`-t*|QAT4)#x?`J@en?r}GN}9LC9lcQjbD5<-ESV6wvHc_)r^IO zemb89JVZRn@ovQxlxO;ZVgM%%%u*KJhSo)DdlmFMSV}F@&JrEo%tPgdLRp8EXCPa; z2fF-EwZ{`S>xf9nM#CZD#&;(>x%1DV%^2W~7RoQ~RY0LBIMW8B%2JBP>#Ai-#$LI2 z;QkN3x?{QJ()a1DeeN$4x#14<Xqx$j7HuG5R#4gAs)gH=(in9D8ds z63JZ$m1$ipV+C4o+vp85Mo_MO*7x_b_lM|(6ivckvAw5_(`#&;h`UVmRBru4T%g}S z-69M%3deUB`s{P|$^aE!ksec3&supa&hs|oL{cgi)6ZsILrW`y9Rt{Ch0~2R^1z0C zGF(Gnc2%>SBcV9ZgOUBT6Nl^Y4jDMh%c3l)Jt2-x$cH*{LK-*&q#L6EV^tT#k}_n4AHL3M(Xd^ys@}oD=y-r$co_b z9U490lxVMJs>0EM6ZGy85$0lC(1;_SvFNhJE1doX2avQ*?nZBNBD&_#G>2$Y);rBt zcCgJIi(t@khmT^KN0`T`vkkgp9rsszXeG4JPqkJOx z?d>SP@lJGs>}YC`%Cti`<@t>Ze;MVudzGy?5{^2~XW`*DQWLIp|MxAWT*ZUi2VU-a z^JlYU&f@+h)31o8r@IFE#NTGp`6p>%o$j=7lp1?=$nTy|o?IOpJ_>uwF|BJ;2=25*+caK?>XZ|qo1Mt36@(wjrf0}Wps+9;)?=!7zq%L zVY~+oTVmb6;8aswi=6{}DioFsH;08sSK$DxIJyTYTTeeYP^BEGGD2llrw-e3O{n|$ zWAijzqLv~f0i*+J0sZ9hK&B8*y8r+Yc)i4nIAkCj*~@I8OM6+KOa3%9icg{@W}-eg zg5fgwD-dSX=VPF(ak$5@3e{}ah%)Vz_Fe$DutuwlFW)~&j!P^&tRQ;= zW#+o5Ew-DjC`uFnWULwH1l|L%+O6bGc4u#WpQisX_*LQkcvX>sV$#xB)T3-Xz@}>$ z35^fTaxffs)j+Hh$5_;gIc)%%w(xy$Q^DZq?*&KlbUGYwzp};Pz-LR9Go{X}YyDUE z;SDDH%b}A0__L(j-8A>8ZCCmJ7w!46XS%o=&|c#H-q^tGkeX}ShjVlFucc>utzW5& z5W;AU5|Lvpk2w$6^k~iGHuZtTj`GlSxnxZ~Z~g~fr&S~*&wTy}_Z|+}QpVJaDjLpx zwD>KUf&`3AaorCD(AJxY%w8-T4u4%^x;?>90+pg7&sCu3kuRq zjBD^+p{Hb^8e*zSA>^c3r*?`?8*qb8jZ+jtb9sM%F8pAxg79iUdWZu$I=uBS4^2|G znnA2fCv`j5ZUdL z;PcyniIo)D3sqoxb}{=Kpr{zz~WbX5c_gQ(zop;{Zg zLe0;>7}BdrKtaN6a2}G)Rt^nGDRlT9!36%w%O$HM)+1CM98I@}4D_-aI3&bU_~L+A zU;yXsk1N|XRDEnw?1R7iM+=)Me)3f}is1F_%I9+Ir&Vk#Ui5e059~pv+uueyaZaz) z_RaAY-`a58fjZth=g4G7 z(pF1tGqAV`whkf@z&g8fxtjY?zY9=DkJcLt9d1O7eS%HRKBV47JsjCyI()00ff{wa za}%=ZpIRKO!eNi`!zWnw;ok%M$NxGZ>$YOIuktXXpI%lGNKj##;^+o?q0x$qaHUS^ zAMfp3jFXN)267^Z_=*6Eb_PDII6CISMf@~+UE)^Z>_e)1rO}N zb&+mD;|W2%=HtR%r&nqqI!w{N#WuuL@_Io=9aDRO0CGws1`|bLK-RT`1Zfmli-CZs z2NNu5QH2}vcsGXmMyGXNdxI23m7M7v%GUko;A+lDzqNT`sjq>$lel=k(vMhL0K45x z31BnTf?Tl$5La!{2D}=nYGKz@g;CWH(^W4~1sAU@GUVdLS<*mx$`KqjiItsQHHM`m z(=p#<^X7&wd6R_*Jb(Q{9NxtptY#_=Goony9#2JzPm8Wys|9lr>ke!KF6O)<|4uv} zzU8^kW-i_}W9e^lGOwae@LUwBY&W+%PgcMI`##)Xg}|Qs8s6tOgfNV8n|?8^kj@>V z;Dz_~fr5vaJ6y=}3aD~mxM!W-_F=$NkpRTS`z9;TKY9>#8y6J?^mqlAKJ5s1pG*$F zb?qmz=xTy9gnSFIpy_=StN|9-cJQk3f``y2*Khy?9aUvD1E@=)ZL@MGB^G=Dy*xO@ zq}fh*14d<9HqJ<`eeb?i`AT_q`%8a(v3~sJ3q0b~Cv@424nwtebySXy2jRBzfot+K zzLlX2M7|YX8BiA$LY*95ClW&OJ2gs}iSVM}Mp}1uvsOhK!fI$l-g|27nkwSVbLh%* ziKY~pf3cr3MzARM4B7hFH88vIRCtPu@@wG9Q3o2z@VzFy#1mo?X+;{M3)N*ahyu=A zMm*~62qhqehTW76QdO-1?;+9Q9CE(mKzEKtK|qa7c*{gxY|7nL3SMq|8rAWIsBWVT zpANd2is{WbeG>&4C|u&LjNQEV7&oo37ACvFZ*Er1IN*+!pQzvmjx8)?cyUD*Eb@?= zu^`DjGDBxOT;7Z_hGO37J-M9@!4$$KV73B0L=vI`s9g3_v#UGgck zJ=t7%nb$k7?vlOf6kU+RC@7&%HmJ*ta%YdQh!@E}tfUtBTUtLg&^vOwiq;psm^FceD@3zp(Mo_JOt z*p79C$#ALI(u=^JExQbzHV5`ziccz`wy#3wFgUj1ok^RAQh2+i`T6-(l5Xk>%l6d&wz%j*^8BX7{RMyef!*5NH-Fiu_m$>v+W>4asCm!az&Q$G zHQsu&{Ie?x_bHk`*f3hkv9DKy@A@UvnsWvK+IM&dPk|2aWq~*ZWDNqw^@FbM9eUdh zsS&ov&OO0DpZlLTHNjm1{w5&X#Gi<3N6?o!4Kj#U?HTwHL_t$oJ-|hH9nFNXrVSme zdf=aQ7<8)jB6J-YVRqWUsxu$rEe_ARk)@$_W1aEPTU#94mDHaC6(T6@6l9>MWig)$ zJwB_GLASV3)COoM)XWP|$pyhue;{7d#1lqTQ{#3ff@nX`iPTQ5eP$S9+lL`{0`x_^ zzzuS)0xu~*0E6HVNP7AbqV}~6dmK6p9Y8rvdo7E){;2mO18hBw-J=;|z@BVGq*7Ld z`N3N=sID;0U;E>Ufq-w!23JhHmTpH*XmBY3lGG~B@Vno>D?K4AGA_| zHbh`nab7O$p{G^$RHrT8&Ew2APlcLv2YSyuRJn=Av>?)O@dmtq3jg~@bI^xI2hrWw z+`2)Ikiq4l@S!_vQX5Bu;k*|^WznntaNe6*ex6wOZ?O#>cxMhqw5*kz1w#uht8=^9 zqUzo=$EuczkyY%J@~`KASDErm*2n(b#C>?9&>B#(%di1b3E9Job_RKi6F1O%M?s^r zshqP#N@eRx})mGkIZ(RPLefCRrgTr~+R{lzLJg$=yAi^nIiR(Ky0O((LwmUw>V zJ(aSNslNNY>{g`~vWP$ir!XLym~Nk!-wV@=va94&a31V0Xq!Ddz5FQk!^f}{s3RuC z6tV|T_}NXY7Q50I-nnnz@PeQNjZPPU7<4(r3qS@fGo+NR^24NlP({EYlyDJ_@q^Ov zRuLKdggy;v#nxXZz)Hh?0^q1p3>wr+07&&f#3fk@9L!J$-cO>e@AOh^1nA{CriuVn zvyc&DfRNiG0IRXa;Am{N4JSKp>wHLfDp0$0u#R%yNYXhFt$V*<2F z9X6Sc-VY%5q1EdqD!6(a((aoDk@Q%jp>Y)@pM1QLL{}rnBfY>k+SA)XQ-HqaJ@Zgyl%xgJu(@2X#Gm*G+_RAccw5OL z_u29b;8@b)&_%W-Rfc##A1lnqo59)?^k9sk-N(|1x5%9R*WLluOp@-NZnhtaWDd<{RDI063F4G!aE+UFHOAX5Hvlz=Xu#qd#Nee&FJD8CyX& zfnvveRAda}ZnhOK2Ew)A!4G0@;h4<)A>_53YEo{SFAunBXHGT`2<>=hI1rYohMr$qlmx|vm#fH^5rn{Gd@6-L>w%R;7E9T z1E7pfYlLfuarO+gV~KUvp+PwYmOe!jkPXKidtrQ$AEHrW&Jpb>8uB&z-+{`@tz~P` z%7g7*3uX2u^wV{yKciUP$qzAlW5AXwH5u7=yBp}EnrT&zBt_DKb+@?5`c6e5NfKwMOcPoYZba+(-`VM_V&dV3{`zK?6ee&_4 zZwF7EJ8t-oHOUp9Ii%*wV+Ah5B$`@RzI4=-yLrfhlf7_$nicJ3ET|h-p{l)k2q2i1 zibP14gJ#<^2;=|5)VaV%RbTsl?>&zslLsRiAcO>G5W<9)iA<4~x=DO%r5YWY@oB z(-;wDI0Hi{=^u>NoQXKRSugKJ10Y9lr|4lF32?H6jga8s2>&@5$v8n#MwM8PmpX6p zDYd`vh4gIrb6h*0V@5c90-X;tNZF%zKfl#FHD~wM^=h}Fy%fD&$=`v*U+Hcas06g` zHe4vo?z$x5ZfGb8zoSu|9VGi>t|p~{_u`f&nYjZ^i#1tt;Z|pr zyNQlOW%X?dui7NIOFQ?YGsveeh^&YkM}nG!YX)wgE}xOgdk_2!Ger^VAS*^roUXVeBd{nYGXH3z7e^e8lFz$V=ooy}r`K4p`UN&CZU zx)x70`sNkx2+ze*vYI0xs^k*IH_q4qG+pZs1GMB0YWQA*etP$q^DwtR4780 z3H1((F7kengCujL!Vx5wScU?kxt?cchX};{_VX?Ul_(Gl?;oq1#89<|U5(6cTCX49 zIl53eyJgq9iCe$%^`URHPdwuK&d@J^_oFG_Zkpy^O8*QLs!zr=D=(ecTQ#uF*ALSjK$N|*DtN8+%c%7{*7M5?r52prsB*1*9eOl=RHoeT zrr&KA)qv|yLUIbIzefMw=zU%xy9sug4 zs?e)%BakU08uqr0iZ&S(>@|It!1E+(hS(G&!k03;?XfSB%q*EfX|whCQ&eFvP-v(x z`#j5>b$p1V_0DeTg>$V}*9exXwrTCi`HJE|8!S4y$*fw#dCK!LwD#ARkOu~2qP|JS zo9|?aaVm+>DG!pctqt8Ta%(J#?gq*uJe_1veq+h8d7gb*COq*nJ3rOkxncVfI(1zN zQfZEg_v!N66q*gp)+BQ{3Y-{L!fSEe?qxa&|F`(9BL$ilwdz!GQ>V-;0xIu|L~C(x zCC@lt$0i`Z&2ivB5L;8U_*PD`!EfK2Z!j!A=#b>R8W-aw!^`5FN3a>;-izvt#!d9D zj7wQ3A9CGBLoYK`O%Np-2A?af2wRTYzYv}s6x*K67ze|QjIRzH^EDp3Sb7J;LC6hJ zS{Il06<%L^V(YA#n-&ItzWV9C!}}sv6@KGFY3cFg>|3NN*pF#|R1t(uo zK%?db&p;VhZtllKgg!q)E+Z>x_K64lhDJ4B2NCg23{WkCkXin*wk&AajT0hxdU3k$? z|B>y4%yeFIL`pUPI{3QQmS4?9wTVN)g9T}o*m!MOG)a=}jOf$#W5f=v|U!ic%qF?DNnXS$NqtK_AF_MNEy(u&O{ z@3T1{h=740=@SZ6d7$p>5_@~0cP>vfoVy>6hLt7nY}j(4!${-%B2 zTWfj6tj>|bni3L(jiPCP12#84zv%72b*+DtI?3#LEeC(LyvxSgUn42{G7 z7-zmlKbrfoA%$o;xJ=Gb&X(`vQzp;?HSGTWIX(67%EwU~-U0jjNxTqQIL<8=^*3<9>)t6ZFB4$*b_6 zSd^27Mw-G6;3t2}QefF60XD=KR++;XahQt>lg^bGkP5k_kGM$r`5n5wNy!u$x--Hy z3X{k(>r(Yk=2t6A!b2I1W~p{8353w=`l^L5U`DHWa17j@Tg+8cMCJyTV#OArFt%eMFR1eu;Xb)4{PR zSIB)|Qykk^{P(t>Ywq-0u)$7>QY!1_E^$Mc%CKy%s17-Wh{1 z6Gj9P);^BDOm`id*&SPO(>?d8T`ykq=1p&$SMK?1U3Kl+6=&C#yE6}22xHE;`%fc^ z=fpWZ8FnEu!4Tl3ry^iqx=pxK3LL!5G~F$YPJGJsDlKLFiE2j7i+hwZ)Ydr0gO{e> zWH|Ks=loVi2mea@p-=rS8l*>}HYO5y8uSr3DBy`J`L0XHT^ns5x+{V+aweZerp@$F zh6!4XNv`;a7HSEJ!iqq`RJrA*S7~?)&jR*pv9B~x<;N`t4Mty}`$)>oZ#nw6kH07} zS}TG%`K?tpx-)EOl!+tcg1Y&RXP5&_TM&#{ZSJXO73jtK*(W#J7_&k0i1UE;;EVBC zh?H0l6Dks_ggK(t_r)HQjFWX%KtQ})j2gzC<9xUwDYiHVGlpSJXHq#N!-$#Y)#K6k zJBLOCQvUgOxXygV%r4RgB_`5*B*+YEGYvTev*zJX1*<**H+3e6|AY@<9y2VJktUn2 zgn5`h)|gi8*8$h4E;%X}*MSHD1M0W-dE~msnNux|btL1~WkOJBSMba%5_r9!ZeLSj z`g~t=Rh8dU-8-IJF}kaik#lGpmF|IW!0rV1LWpmPV*H^ zcI)-*>ya_W(#}NOUUQ~B83K)eXk#ltFk`wvC^Jqg{j2qAhWJiLgUlSZBWqNy%UAY1 z)~98DcUW+rvi-sadwAMT@;@olM7PMS_ZetWm|Kwp?&=B$W#oCq#nKc?VD#P$eaQHp zx_!!QrZh=Kg}ZM;AWr7)r-*`o&_`Hc*02{2Dr^29iE%4tpN(JO2eS5jHKsCTvpz)B^`0;N8Sd@OkjXLYTFjS-L%A7l&4=+;%dnTr1pK4FZR~= zo+D~-N@32D{}S1!Y-O{}gg?IndShaPfm@?Ovo*X^{~bd&bA=m1SU#o7x>!+apC692 z+`L(-*vlwB>LfQDk7Ufu5%5kqV~S2`T)Ao8TJB+O#$g$jIRxjhZUVP~q2PFMnBp}V zx7cl@55^cFaQd_GkYh#n#PUk#1m2?n-a-@%(Dq%$xuC9mu{e|trgo~&qqCAgm^D87 z;_0bm?twldXF4}R7JS_#rg_J-k#|alCut1X@vno%zX}T>uT}t>t#;_FXF)ZZ^|PXRnJLP@#4AzFO9?#`rC#P;7#&OoDou^p3TEk^{8pSoWS=*S zma{0?Dby-dIn}_ca0tD)NLVExObQj8Q=KUs%M{wB*Qk3|**Pguf1HH%~*!F$i+zf6lUrz}WVpg7U9iO5Flcq+m0ok)vvm;P4W>7FZbi!py!~bmf%cW>?>{6d67FZ|~cViH()KQczBWeTK zv_!f3o8zLLrlz|Kk*E`PArwh@qZ45wfwfB)R?W1QKx)fY88Uc!zYIx@X2ZJ+myR1V zO99Yk)Re_KCBk7zAp%4pcgdI0B-?-Y5b=RX{Qevpg?u~&o5I!op;D28GT&P9W>4>r zMzvj;jvJfg2U-a6IxGY@3y;8)We|jv5@`q2)>GW20@G(fE4FkUhJ%qIIo47bAMVdy zG()>CJTRWAwI3s(Og-kKeyl`$1aEKK*m2BUj8ao-CYQx}yd$lM_$OWp+|s9QlI)LL zT`|NHmMLY{SQ_GbqYRTowoE&wNkrhvLY<8yZa4h&mwgqX)WFcUZjEgyoq1JZ?fCO$ z-!VdwR+1foP0p|48jOig+48PTzDqgNp0cYn^e`Ao7S)J4HJ=2vn7=AMX!T;VE{I@< zdeEtMDmIuC^D_w5&WEFRPyn7$pEZ-r zs2msp5>Oy+QqV-?L{Lc(L`W?jM?`ibv1kY_&7`nCVlj~sxB1Di5~=*~Ec?@(REid>OF6|I3&~KBNdmQ%9iMnO*$HXF8PK@LruhC3;{xA} zR3}RT|Iw^Y7gKd1RUheNmJjq__j}I?2gJlyIr*k|M@dh*S^1w)L73#T>}IPA2N z868b%afGh79lMIn2p!WwV$DEw)(3LStP4AzX8bPB$Yt>Uv|c2C!v~^Ldn_9RK8@ln zznXW=#?D1Y^!LWBRc*fu&iwbo7s}q>xADc*C*M6kFg~IH)_KiNX{}}EqTivD#qGv7 zz+*s(k;64do{O%L$Rs2i{;I}wLMhUJCqS+kzN+n#v2IY=j>(M{$b8OH^rPza5}Xxi z_+k0HjMFPuOC7(8OASQY7bO(ffV;$>96IXH2$Y%=X-N_~fezqvzx5sG4EzskX*isE z{$Cve62%L*{#{vVz54IUtC44)|6{b+V2j6Q3i)PfS<{pL?E$a0q^b+%i0On4`gTWF zYN^(h4c8Sh(Su`|4PBER6Tn6Oa=hf0Rd!`M^z zqj&o)z2bq?K?Z1;qr;-guYCPdEFoM>d;oM_ylfnj+orBv`^^I@r{GO%l&fkvp zovX>Xb$(Y#^1BStYtWlTA2+TyGPVZ(OFZ4Waw69(#`O~8Tndo2_yWV_p^{5s3=-DF zJ(d9FU&s&U%g0YHacg0d>3pVc=*S>87z=jAg{Q;PboNQBQqv z#dXYMf)F`5m#eeG^gJGpl(QDT0DFsL^5{n{`n8>Nz+-Sg@C9W`-T4EB&$mo};b7~O zs+})B^1b5wYCo>4el7j_4kHOS6;^vDBkEU7N}ZbbBuEO*q4ZT1{yJgLIL11%Hue;O zZvF$k!faxg5yoZGJF$*v5v6)}#wF#JZD$|K_3A!HFyUmv&W{DHL@9s}|H%0*qPLSCXnv1_ zaRI&s?Zg7wd2?oby|~9zIH(=veeIult3oc2wNfWt`+Np84|IA^)Q*gZx|APPKO*zI zI^hEL8588xTz=wRM5=`*Ice5dg7E;_LZ)AqwsWx9Nr5<_X}XDf2&8KAK88n_j-inb zzyP$C8B@d?FmE4B#Oi@Gb>y1j16uZDvS0<3Q1LHt2nD_rwxUeULsX<0Bw?q>bJk~P zZynEqmAP>MWx%N7nilNQa9z&;%DJ_t8b!;(UJ#35>qfjzNS?@VkYGC7ID80%LILfn z-pm5En{ie~F&RtMquR#%Tfe)s{)HL&b3(BtCvzN*qO?%^G4K!10q_%lyObLGr)2EB zBdlDK$s|By?D^taV^3Y0e~Z5e`{2XYL?~ec_*#P3_PR5+oWSk0om6%M#eyFAfP7_p z?oR-JR)~P{Qn{!2Z0CKk>j{gMKx**RML^Tr=loi;ZRM}xoM64w_d@0&KPz5;Wi~q` zKIp?m(KSEC;+vZLKW5E$#3G4!TBUccNWVul7agVqGumtDrKc_MgewKOyTWeggKi%~ zzh02bQHqYi4|xNOp=Y6++ux`FPx)la6KVZmM$9IC@X8j9S&A-Ved(IZLMH`m7{La; z7Js3tTp!K?aN$&VlozGopQCqR01e_s>lwokVtP$8n$N?yE{U1oK3oWBJ0r}4%-&wx z(b<=5BfT}Y=?v90hc=l1mMsh&bmk*fU$kn+V|{XUN#Y0u0P#+r!<-)f%p1l~Gv#4z z((J+Nh}#NNMk%?ga{!;X5&bg{k8H7WH`DPx_=&dcW}5uAe(5{1%0_W+1|4&zWj^Z& z4Q%h#LX}P)i0g6Ki7!UHz^8ODwZ?3#(N%E=SG+4Irp`Fa(Lw|?`Wiixoyl9)H=OR8 z^^NoGpI<0B5!$q3qCP+E-uo(*i9lh`ZlRo2azvca5D2{mbeD(v;WI5qf+;=)t>~eB^$u$ixZ5HEd@-Kjm>|q{B~$0gwGe09Lz=IqNP8>tXa?Q) zuv3vMn~v{PE{+)s9B+Q`^pE?riMU&!HsS+FV@+ELyzzaeo!6e-Q9t=?(+NjN7WIx; zVAkb;GAQf`!;2FkijYWsXzBt2o?q2RD{9hC%)X>VnGK_k0^rjgHfi%{QbtFtqSO|Z zO7?_2Pu@uYKAz8;V2_k~DtVd#td_rmc%KyBP6bfJK0oLq#E620WJ4JPyE9cbe(hAJY6n*<9&|-ddbNJ? z_>Y|qk|D0D;GdBwg8-ZGDh(7%*UV`vQM?yWjZ=rMJ*YRupk$U$#F;acuFbYFt^XtS z^xI`TEu)&;%#w8d>8S0)1ImK5FZ9lD<-TpOw#ehK6((#U8n7HR4>E}m7VsRA(>5(` z#6-8|uQMp6v}orIv$$+J9^y~D@OJSpD|gwKEVyyj=Hq5C#6Kq8KWXS_3Pf_rZgsQ> zYQs*yO-j4svP>|?$)_h6YOJwC5nrbmsEXt28+hRiQ^h<-Hl}8cBr`3F@=uUv?srAR zT@5E&W*?4lW!;>-`H$9xzka$`@myT9$V>l8V5#no)|M+27gDhyv93%i4y1tr4MfZw zAf8R*Mk!KIuqp3kCwZZFpiId()vp~UN5tTG2Muv-J|fj?kvn^fA8`S&mJXP}p-gAX zvQ*9U$Z%U-b!wescxmh5TOQ3%{;vntj=Ig-3uO*S)hShG`m{SvS(wD1tr{Mv0W?xd zICy*v-$pDw87uz7S{5iG#}cx#M`IGHW@NJg)kZaiduW{Qm9U5v(5{Gs>ajctmB??w zV||8{LmC6xym#!VF*A(H~=C=Xwcvw#S%9|=(3<v7*mY!cp3ns+6I1TEtn>)DC|UOau`>k{Dx#Z;U0(w;dxEkEYoU^k}#7t z0kG>%7iBNPnXf>Y!G&&+phrn9-%ufS+b+qlJm8D0{^HfrM8v5O0>o-Nqt3=n+Zv;c z2egFYdHc*(WZWFQrsUMW?^@>k^SQcNmRAns#RjI;l)v_;!<+5%*#xyZu02_2P|7!t zwMaIQVHx2E)?UDw%|g(gOqvBzXgGqgF-*Q}-@a@ko08IOf#U25qj$4UCNnF0`c2n` z8RkbpKHM`>PIDqV3_>OLC{OM;FjSYahvaOSK&sL_5oW&INBZr`m){#rx;l@Pss?O9 z;XvXY=QrXHgF{Kz1NLKF%HMm$=VrOtr zmA-IKf6{?f$u*Om+cRE@);3vY9N;3qAKiI6&qzRKoK0(BIum_D{D1&u}+JA%UqPaj6imr|t+3u%9#oHnEJYx>%GT*D_nfQp60I41>;K#~D-hh!`i(J}BNec${lL(cOP$7g zBx!k6Ie&nA!^1*>gk5bj2u?WM9);4_ruOgUm8dnV#nRMj~if>F=O|OKyGOmP`$u8{&!Ise%m#d|< z28@4~b+N^4h61CGkYh+=@W*KCAQ6ujmMc*ZecMn^tol5o02vx(Ho~1$LdJ|FrfHBo zTXLW3P~M-pxu|yTiY*%q9Wi|DQ`22MjIfd5)j8pnipF~;Wtp%W+~PS2b>f#y^n>4# z{>>Ah6_7q*(9GRsO#G`}&=aZ?vv&tigiK)-Gy?=W1s|Y2D#|xOv}9If8^(N~ctl8v_oP38bdH=SK7E$@!urws+yboqsB+rZV=zTc0HaM@sSOu;vzQ;l>WZsy9@2Z|q-1jJ?Tda!(#+~r3gQZo{O(YrCIfo@hFj8! zV}9%WgHh{O+yW_Muny|VFZ+Q0QOoxQ32|j4fftK+j&X&kX?Pe}Ab*n!B9Z~6C~33u zTIT01&EZ?x>X zpkwLM#<6ICnkV9U_H9K5Cc_0)Gw_Bc`NlL(z%=qoEai$8QfZsq_%ox*UxdQB*%b@_ z$^7p}sZ2>=iA1CK)m>cU5sVQBadBf)^RkOgimtoF)|OP|Prc%u9shCfdtYs+PC9t@ zK_Lch%KSqb)9jz~QHKdT2|iQG)O7Qif_@ZtU+Gh>W;)_#Wrycdh{G=J;}AV%Q3r}o zIcnr-W(_U0%#Ke{<;#n;rxz@poOkQjmMwWd z`e6RXq<$ui^)|Fn+|=o8f&IsR2@ajnU_kqRUPShm&|kWC;Y}0EA6!a`J5n(1!JFq8 zSIS^(pQOZF^y<4V*-kvP;(r-8{Gc}RXm8B}H*bI?Y||ozIvR1ynMgI+`Gk~l!`Tph zVq42a8<$AHHKF|I51`T%(c_R&xD(utAs@qGD{Z1>oO+q$TRFBFxg#SWb2rwuf)lxm z`Ca};T~j#OpFYvW3QFpsdiBcnsfIb?1CJtDM-qEXhYR5TU-Ph~%0tz@rCS5sABOMVy#r{Is z_IWBlYV0edcC9V-oUtuzJ(P2ccK)>uZ%nt(J$af|Cfb?oXepiX>41}2DTwo?v237M z1EqbfNzC^sU%};J^y00(lCAHK&$5TvRR>|otQQar+Xa#dTlek`C=iTZDc16-dNlG# z*`bLoUbkOy%5Rp^`iZLU0wF7Nr#YsvnAW-21Hdf{X)3sl#Dd?hl1BHp{2vP? z&(iRots4rrZ*9MFgJE70oIdHxxixblx<<|LBUJ#(FE5lUhyS|Yc;zHZ!zi6!#0>=D zpdl8wt6wNjZqbuJoIkrG9yi#S8nxwyGi#0L&Xc$RKonJdX;;J|a*_^7wuC3bUQU}K z1wOg%^dp@2J7M9rV}g_!Y=?t^6#@?vjnL5?B#KF1MnCBC4C#DQq!N;y#ylx0`|L|K z=Ni&YKx*$W6Z6ZCrx5_Mh09VS+r4bU*KiU1G;x7^Nm2dxrMuVY$M+s8C9?)U1}f7g zg}s-uHGxcRvO>9|`!h>dU2;DrTpEFcnkdA;1@i^1sLSQ`iX?O?ZQurhs=x(9eoFN+ zC=`nj1kQLtpC`lS+4t+BP4{K&`S{M6_uMvT*80zV-%(%r?T-$WAJ1FRBJXS^7bG&? z>#}5i-hg(KZ`<`T9&dJV{UGKIFcPU9k9Ay#8j8}+w7nJNQQ@SSMN?ax;CJPb0%E}Et z*uL*f!9%VVAc2c4WsGOOTT`Gma9Q$(c z44lc^5@5*hi?{z>xhvu*#CVRED+R%Cg^SbwqeE7Ye2Ewk^O)eCgV|vmv4lcQ605-< zMFaB7_W@G?Bym5YwY=?#I99qL5DP50k-tuuW!Dn|vt?r5cJG(6qJc-xHs#*>e@7{# zqS;_MuKPGkO2=?<;%(ULC`6!nz%$Xe0;Xl5UYYz%Tc6b-zuCqmNqKtRuw#*X)GgGi zBW&#paH+O!L@jBZ8?e-G5vvfG)G7Z$0;ta`F!N@ii>J1mW~tnqP}Xo_NSVi|dRnqb ztKQ*|)`b;m1|k7IEU7TTf*9B=g>EqiX0B4zz%BKq)n(1htxKPJ^uD{_|8v!MI@aAf zi}tayf#3H|Pqj^VHosI1La)M#c*D-l?XS4pGs(SiD7ZCKRZG#Kw=S{Iw@KoO0MR9OTe`}?%lHi zjX0d0sJKd2njTfRZw>mMs1y=xf#J2RzM?Xad7&)!Y+%_P@AmHdR?E&dXby>D?DD3Q z()qstSD8e4j$DhoA9CoC<;+EQG5>$a9LXz7j;=#k@r&pZZ;$7wtGejN!{=Qw8jdE! zbriztotETkP=OFOBbe!V@CqatZPKirh*6g5FASgG_Ib(hd87MWLwJaASB+pAnVdkL zN20GeX80PHoY5x#=CW<4l~;@?3E5*GIhx=U!kQf$O6iIgVnm`bx!e%dIK`(qTLTC~B6hF04zvDc)Gs54*<$K*XFmlBR|{|*Z4|<~l7hb+ zQEOI$p;MdGhCyL(p3L6?MJ!3ul*4NMkyje3Z{2G52p@<$%*z+hC6a6ABPwSk@q)gR ziXb0!V9i zM&~r8?rOQQ@z}Rqjvfuw;gk`LJ7WS>EE9I5UV$^JpfYk;Ato)4CW#h%ewP$+sd64L zr*R$Gys-(qClE@Mlri2YVTKPy_r)4Y{W!sDR)B4ox+`ANPRS-FZwZnRK zS&?*C!egF*QGgzgu32kzw~NYYTcnB07f@y#R;;FN;DLQHQh9M5;te=+D-RG74v%5U zdWBM$^Cc#w1~HFLo7-|>gU779cJL~Q-wFvpHYKSy+4`!Qj9q+S;PHik>ofh4K%8&_ zuNUF~xKyTv$tFvyn4X5X|1cQE1TM7{jpV)Ih$GsKW6PAuUEUw;IGE=B@YD~7jv^p^ zphKJ5d90@(T121&dqYl_nTMIKS;pD{yO_cmF4K`UqJcgXe2uzVcjoy67mt0m$3|{-p4$%rleX;x9Xb>9o z&#GrzDu{qN93^rgy1KLE~GJMjQC?tY(?>W(M)0Rq4Y(0J9Jii50Iq*N`7ItCusJU1CH;8IC1rIZ$9ZwT*n7 z*b~r@l}AH&k4+n!UdF-^6S2x)kffY8l11dXc6;p`y@pLnI z;hE$KVm5+*6@ZXfY;z|T-C=y4mfiIO%oo?@w%B*=iuL^0jpsMN{+r3}^Bfq-2e{jn z1`&=k>@%D)eg@efVA~`9q}d1s+^fyiS@QC1c_;XVNa-ex%-JWE&LoqjY~;CKJ7pO0 zggxu^EXL`iE0}DDk?x*FS$|yVp77+1sjnQsu@KW#S!>|*T9$v-w7E17!3s(%o2L*RdvA76GAZef2@avx8_6&Y(8Ftx_Hvg}MDsFl2+$~3tZ{9VNJ1t!Ui+To&+Pk=^&3xJ z_u8@(q4mE|>K8mvNNb#RM6m|t!5-*BWr|PgAL+h~$y%4~XzoX;JLtfHZ^R&!t9w7?b9d^S*z8Yw_q19a~9rwq41Z97vL^X%X)0NoZo0c zZp)%;HfAKdI;S@;$jLcb`(24+%?~g2~wkc zQA}e4Z?61qnR4&Ds}9$7->hz6Tis%1u>!sYEs2f-$%Vt}@S?2%BFwgvDZ=^0Q2sQO zCV40Sk%5zhb3DNP*ScACRvAKa~nOoIy0N#Tf+Pmw8zBk*Ajzz)%bNI*KC>#C3_Nlk#y>Q$Gr^g7PE1uu1 zJV4&Y*SLN#ZQWnZD!)jy)}0jT(LDJ|$@zr`(=`-DYPOO2{jLAV;C*C#1fvnL8#c+y z;2bVy=NaG>WzxO^ncu|+U7#29kPG}Joo%{_x%cuoCOX%(diC6oLbX-x9&eWL0rBL` z&GS5Ff{5qDp39V%TlAIfj=^|FpY~etbA3i_Fn0TW-TqKJ81}!SwmF82^p+%@x*JyU z)SxnDt98|Eq$1qkR10ntHLLC7k*Mv;kAL|4!cOBZUZ}u?DVeRd50V`4liul9*Uf1bO4(V2W{JFPCYkf3=Gblp0m_{`?Lq^sux{H zM+PW5gB+^9`~1*gqxWJffh?eXQ8Ikgh%RCXjnaKIcXXB#dLdSEYkeA`Cz>2Fgfzjww5;=bStd#IYRnw66pSl3T{ff?Rz8)5hPZf`o)TbBawY_VD29NB zHpY&0npE0VzU1N&Mvlp*3@KL&v4Q!DEnbBm3K^G^U0MsNbIR>(!eumuG8&tt99uZR zzdDFn$asdV4TA@oayA_7soHqziW768+frnZ74cFf&qp*8q;SCT9#3Fa6QqzRLI~sJ z8W|hT`vSU0lw6?DUjX9{`~2K~1!U~|hl%AafE5@Ex+2f$qOctH0?<9UNhT`fw-%q; zrONcRI1_rypoT;s@36|ROB8EE!pOke7Fn75N4jt1p1eysQ z#16%UPBcga8rEfyi*yoDYXL-XJl9qWfW|kfEo_t|Xu8F#Ztuko$hzSZv+K^*@O%-O zQGhKV=f>o4aMnDuDkgQX=W{*fq*&}pN~|Lm_Nf>9?H`J3<^z#h2WMdQ?qjS2PXP+Kpn4{83PDDdTldNuP zx24IrjXbGSl0qYrb4NpTUvXjO=N?HzU7z5vm@xzr+ zgE@heG%O@*_y$NsU8NC693uX#=h!h~tgOMH1i#I2P8v>vH(3v6oIWZJmOLwre?;yf zZCu!|Jd{;;j7FQ&p1cKc=KKnB=7lAK8@ayV|oT|cg`k2DME&XG+E~Rl!oYj+1O&PKN4}9AoH@d@7a0Xcn2@ebBXbVwItATc;~XRNOsCCe^K49H z7tA#CukmZ0@j#x-xL=$D-ealWyn8&W5-M6Wn8z=_^8JAnU2=L4Hzl^%Xabyc8rc~^ zP>|q~5k(R2s~$;BezL@!S@)pgdLwmuZBuCG0~;%c#-_DBe!~m5ELyYo%T<=C5hVO5 zK*!0yZOfKIo^850xr5{OLBz?*r+PhbtQ)?=GWi88-- z?T#|%vB`caT0of&Y!9C{OP{t`uU@_I%W=^_|1#GMwB|cq+@+XzA?yC!MQQB7Uo9ML6SxwdIA9^nR{9V5t^YLn{NaU zN#Dso&0{G+henug0EvQnhRs=*Xv`K(aey8=Ev$N{p_T#6SaXCpVFz%tH?{e?k0gyy z#D&OAPYF^`;sk&qsctd+r-%!!B-souWuqwnYz=8hOOa%&nMi@ynRA@& zvoN(pt|L9i zAQDq7OU!GYxI%wrY9tyKagRhV+@VAzFo@)Iq;rkjK+>W9sIx zR1>@kH}idQ>p`H&1Fj8ktje754)1on_~xvqFRslv_k0zz^~OR1786HLtaw%Fp5Q!F zv@fdmtAm(o zz{3}|OG?d)`4GjkAOhG*A*={CqJ_Z-VtvV!(B?$WhND?mR#};zRnnYS7ft&Mg#@Ec z-hdG^^AAl|S4160Wx5GG>cdc+j_yW)>h%2Si|@=WFP<6R(8^G;s9AH?+M9r&=$RgV zRbRP>AVqIh;c#T*gUXs*?-euW(!3Y+!qd+1sqPBU43)e0MRyUfY-dTY%)TcDs#0#l ztt>RooqE=o@D63D<9!74fBiIY1XbtzYy zA|BF{fBF&3)u%L=J+G27U^+zTX2X$eI+~E=dz_zgq|Yd*+d-!&*GcjK4wgj?2_Vcc zCsanvLLr=ovjC=W+Yb9Y4FP8%98TR1oJTY$d~XYn>NK&deXo>uxEs0WczR~e9~a!2 znmO{oj1RZ`8RT(e&)+l@r`l{LBkQ8r1PRO@OthCT>sKB{qRvM)1ETZua^?&qsn$76lkrKT!%c_mbCOxzP^Ek?pY{?9 z>V$>Jt3ZuJfX|nm8Y%qtuIT=IJQEubJT+SmxUXC@hy3A`k?{MoUkEPFD?IW;GJiSP za}s+<9x#f2&P-@v&Vs=Qt0H5O6b4=VFMnrd$vVnbVMy4ifvX<)G+K*~-hx%Id zB{r@or}}(ZxX58Am;}^Pnny6BB0CV0<`2UEOk^N8E~&TOva@tx=iK7?FYdq3_KOEf zKj;ZzX_muoQj446RyWH*a^@Tg!(I86Jx-a4MAK~b+YU7N3q9k1(39ZO5-M~tB@u_K zO&;J5ZucJtE~_9VYetwN4N}tfjXSyiWHQ}^7|xe?iq#^#Di#J7xx9!*B;;ujk7#5M9x66Vj;{-ZdEeu|+G`e0SCSX=$M` z<*vHq#~4@tn5a-5@eVjp)J!Vx-KM z6Y(kvlBmSdGEGBSTFzZ$N_cEol30c|6i|)29cZeP5MG#btCW{qpUg-jvqh(w^P6P2 zc&jVT3^1686BI&r%wZScXkXjmuN<-i;nFzjJ`bEHga<&yVP)u25j?)eo_7+`PKws+ z23bG0;+3G|+tFmwj0NA*zLu9#{Vi|yx+gY#F)cLwYIOKy;WN(zTz>gW28lt{2|*94 zrO8$-1K*PlWD$`;Xb+kT5C$18%RkjZmbNTmW!muM`l?ocBC};iCwDfX0N2Ol0`+AU zr^6L0bwXaG>@CE=CBq$63O=W@4=Rj|v%I3o&|SQ^;iJu)M!B1knLOsnU9LyT!5#~09GVGPM@ zM2P24iQczt!M}uu_N?d+u5vXimFoF-x0P`5;y}Pc2*KYS^sA3&QS1FG(0J9vp~AwX z)!Ct3op`#uqJH+vxg;t%74^gn7dRAggoY7DZJKcrV?!gBA8#obSlt;=@t^9rbiDwt5gIphnQiR z>ml8z9; z?678jy5s2`F*%LIdr@>?JO+Z9PLQZ&i=KX6SiQlal-W6I6MMe0Pw?y9dDwv1{fB_ z6??g|q=2xIR)2BLoYvN^u>Ies6&Bf>MIUlgibbm3mO5<*<*@&6h(=zj`x= z{jH`;Q9mP;g~m{1f*^pL5CmKm-=Ti!O4!2;pCT1Mz(oM>bD=UOegAUXvn)>V@9>iex0vt0Hx>Sq1`TP!Wex`)=n(I9uL7eb#)4jAT@gTg&-6{LAW3`u+yOuhNjSKm5q=~{QY_N)3u)j!I6x$Aw;Cu{#O zvat1jH)cf#5vG(R|3Yw2l0%aEv;T)SBuvfPAWbWANF5iIA8t-Ql8=59JMDNQ3Vc_b z_(eZu#O8*N*Lf`;KOuy`rsk$wER3&!A7RJ4SuCccywVh5wb*KYHco50)lMQza6llA zf{zvnF(D_MEcxo*OHyl=Oy7Lt1d2f#Ixw|asguqpF^k)K0_WB~({_S0r@}(IU^dZ{ z8r=1GcdY8r{8?Kn-&~Z@`Mo!1(;&deaV6#Lh&%FuoZO~U1pIw=(x@uQaHSyVCFg(x5zFA^I1<_HgZIF; zDAh(+;_gIclASG_CIj6q^ZI=-1g+xm%X#(NZSXEvqS)E2$5x> zkRk%dYj;cLGtUh*OE07t2EDXK*(15l;{zKDW$=7)xtQKYpb&DSzUF30Ggd_HZ-f=M zbTa|}CylAQoXw3E#us5DtX$+@53vS^fm!|7RS#E!AoD!2gHyNqlGjm@8UZo|=kt~( ziGq|Ec?hJo&95gFF4Z!>bqWzNCW3FoL+1Bd6RMZdrtZT{ioRzFS+a7AKPRxj?AOZtZ zB6{kYwbg8(%kVm1KA@~Ztoslb5qKQ6t#+t8XxNX@$Apk@IuxoX&t=T9m;z^P{-H#% z(|H0Ju)6by3o_eIDrR}#5oXI~${R)+xM5-2FvHphaw-}M3%i!MW26Z&dXCLlBG;7N zF5L3+8gn8dyKbVE=FOT47T764iTN(1xIA9cj#+*i)cD>P7B@Z9{iCbDI2h|W{YklD zcLld@Smv9*rifJo1EGLhprAw1c|{2(9|8~|>=JNBPT4{`NT2b*=4P>(v@ufEsrV5p zCP0E>lTM+*9n9gTy-bWEn&TZ^&LW9;7yrpiX#CdlC<0uW zFaRqxi5d^^@e-#Zcuc~USgB2uN8>B{ka}W1mIoJnR^Y4VQVf|t_G)V7s%J|f&`mxJ z*Dm*RoHbZ?wAH2kJoAAyf#WyiY)GSXgextu5cR7$uW@r$=WlQLTBS48Z_|3vHSYXR z5n@lfS*8nl$Z(JLDoqk3yxFsDGIN$e%(f_k6+N{}xoex@643HjZ@yzNxr%AU?NeMa zz$kBTW<>Eco0f4>JkKB?hvqQq0DPazAi|cg2}0n~HTYk`i6lT}3bzZmx=)RiT4We# zQBc%A^A@6iQ({p+acLm=rgDt@k*Ttp?^qUHfg=h`dYmk$ z`gOfCt{}QDlt(z9_Sc57BlV?$mzhmJz0&%;?XB|Sdpsvrym#`m+qM}4&5cKE3O9I! zP0=t&`JCMQbBtL>Cfn5u#p*wKCQwEg{bAskPwD7{M!|~0is%OB(W6=nHwwU5Iw~nn zG0do)hb!J7vykVB^SFYtp!9Hb0HEclslO>Veb_4w;m2Gh#w(NEmK13D$~Jye*H>7W zcqKA2pvCXJDySVlj8>g=s97|Td9j)4M_yZHEZH*fX(pWQ$AHy+2z+m!b|=t;7TTH8#! z2?RbnIn^7@I{cB9=AbJ#E4SsueXB&B$Z$$Fc&)kWBkpb9?PkFc|5oKF{&uhCdbsD9 zclkbLq7F;ATvkz|S&u~Zm5ib>U4>(1B~J-1=3<*jgV>cOLBKn0#KqSNl*>h^s!bCf z(Vp%mgKgpUi@TH+ecJfYwr365@1V*SCiB0YWA}YsKk{YIjEs)qi51-wS=|%!W;i?h zDEnpw)UtCm!u@?xer*4b*R(A06iU~F>Gm5dYPK_gNL(~b+A+^erUox4y8A->;hxiD zixw=>@4v{1h3gMp<-F9_ysdd5(y)%WdVxlFpp5tg{EwIoM}i+=2(ZNA})kVPEQUo|x?@EAt?0gj14+#ZsWX|)J|#oNdul2MvcwA&!g zGI{exu-`>}N)NFmto|p1ef&0BtNOKD9`XG3)tM!~etPVOwZ;3V4ZM87=czL$mg)}K zg;v~oZh3U(l~p~SHwR;s^^@Xmda2EF+90iJO(+q?f!yXw&!DC3ZwS^A0z;p;l+)8 zfKcVKJ6#fIP!RPhaHZ+cox0c(KYQI}8|HP8W7s?GQx2%XBVVE{`cu?0`%-eX*)CHf z`JXgvNbArG#U?w_II=L~T#J(5)JPtx*peA{XyeY3Hyjmsh(Fuw9oqP!H|71GYrd^v|wB>9?!)eq2Txbf*l3WDsoeYP~d?Uzbl7 zmx!^OxpA4%C}z~5JjeLO-*Zo=-Nf+xfvA1=SDYU0>Us)_CJ86`$tnNcXW59N5g>2k zR!@#uMv)H3jsy{68XkNgjsj2`$Iftq;e>q%jw_PC@>&>?sv9l*L~w~j6#=v3tV&8$2dc#FX`UA_Pfo(qw{^ zZA7i74ov(Ch5kW|Sby#HHE|uNBgH_lCqhl1Xs$UY zP7Li5VZ%}cWK2kc6nDs&)hfORF0SZab7wcXmWgQM=KG|Z{sPy7O_7y|=7ZQtVMA~* zkP|bI=|K636$;i#S=K2>({d)e63O>d1jIiigAt7% z92v*Vmc7AbULA}=%)sMn|DeS!NtC#C9%AnG9bg?VkFY6;M$ri_Fl&a!ryXUP%qZs~ zE~a#eco8%Cog|3MYh@sl9%l{VMsHR{O*K>O@xbPwO*ADg*#ugcK7%v*eE99R3i6lv z)=dj#t^1Edi#ytbCyh>0U`ZME zBY1RsT$8>l{0qSXgW<^PsQD(BY&-@+mK*vN$%y$m99)l^{aBqeYY7XA^IuIw%pp{SZ+XJk*HDm#2zNi32IKlca5qnlMDQ z-J;%HrmryF_`}hp{yxiogM(#_&1<8cmQ``zt@pjN?z+0tp6Y%IwAq!whPmT&haunI*P0j(JwQ%78{FHH3>TF%^04BUTcOJo08P4xDyUzjjB6@GBqQH zgbOK}L@j(#pp6+|la{cudEfnWhZaE1lM_RaN0 z&b=o)j~#z(zqf1FzfV4O-K%#_duGdVCAPnoa$LWaKr=}dj>}1@O1YcVhX#hk;R{#7 z3--goi$li|wA*3jOF8{)Wy)bQs7uL=imd2JRBr+Teqc5fV_VZ|P0xWnUB2r(8tu|N zHYhFe2_FzocrK3=4Gbo!P-j=MTvL|}q(s-c_BxqlZF!uPcpsR)BKahR0*VtI3adOs zSOc4C7S*CP<;tlK`e`CXU}U8N>M|abOtqw7_Mkf_-}nT6yL}^KQ+3obxAk1p{DJD9 z^$fiA^<@?AoXVjQ%a4Kgc2Q*H#4UI1@5@`26Zgcj^{aFDN0D$zh5pJjk?3)Hj!b)jOm^XMA#>ypbL6ln@?w?o|=Hp{< zLlVEc9+Ab=5=rb5JGjfE*8OU__y+uZ308i_q-Ej9{cNtXe~TbK>x^Me-I2g>*(l~Q zoB@>*u?P#7bwrYUs}y4oL1|h&(NHGlQI3;f(<7fz5^f}fWU!l+qQ^zrPbSiN>^iS~ zUI2qo^=YvLvb3Q%7n7h>>$8(^d_s_`r;oS_zwKV(-?XoL=QUHl-8I@;--oh+l(V2i z`3-YG&*@D^E_MOM7^PxFE9z(D?Kx5N#Cp;Y(OVonkmspWK8{L`S||=d)L@8CPhvN( z$+S}oQz!=c%b@XaA<}v1NcrJ`WE=j$;hi-VrbH8o7!N@Y;gdh|TvM0m6rL({V8f!t zs%)oATLrg`7+wmK0@HrX=mY%tv|}H1R^RnRT)oue(W61Tm+>Clv!dG&o8YttzEiFS zN7Uen!-@a*Fn?h9XaiWe}YO!FBxB&A(rkev5Z#dEzZhag3iIwJ~S2?>^;T&1t z&Zn>wZBh5ILwBV!y@Gp>X{UNd5?aGBX`2ZrI;U(+akcJ_Gd^RntqDxB%^-J+@*Tw} zy2TlXol@>V(V?Zq3;y7D4mRh7$sOc7Uw#;3JUIfPotOg9ILBBs7KzO4VF^w_8ajME zHAfvykF31YdgTrOR@Qu?=5N1y^#S(v%$rWM5MIJW`OUkm2v1pXXvSu9y@VX%JehgQ zSxO*6HjmJUcPd_MQrPB%33fVP5Y`$6Ff}?}jmQw;k7bY!rKz_U_F+GOfqx*sj=}Wx0~js$YC6yr#lu!P$%G0BvK>0y{S2{B7cxw4E| z*~$5>%*c?X&Dv0ZZWF^q%~5@U!mV-3i+hf(Mo`5W>Exy-7W<~pHO_r}cg5q6Pus=X z?!x128`)av{I6AxaL^m7-CkzR?N?8anj>;d0LWaxoWW$~EiE6@y|0m8!hLaqTI2#Q zIn;syNYH=(17pT=j@HtTB4;@kP*meD`oNgptd`nbZ_>e;SeZEGxWTZ=q{CV$zK|By zo2#^m28u+`9azDREopbW0r0&A$DoA^v~>ck0mh@%7FXQlj-Vq@|oS)VVdW~VVU79 zfhi?dr9ZG_m8en&()-kM4aMZyb(gqzI@IKTFU7E{`sFZ@hT4}i4I61*x5zkM)XDs{ zyP8LD(Jp=S^^#4$F6}@J?sa~?*7)tr)sOTU*Y(e9qtYG%5K>9+0|^IBnTKUsI8#b1 zRnAmdP2VvB_yY_(!jTuIDv91E3P6gR@1DeU8U%1RmmD$C`T#i;~K6^1w7y3XS_0L_* z7xQw@O28@h*WSu~^?zG?`?#p@EARU^kHGLCkr9xHnK6n(RLbaRG-^6PNsyq9V4|he z0$Ls1m_m#uF-`Xe0_yk>s3c2BOa?@JsAjRntGKNxLD00hNG4!h>!w*B5)&U9*Tyt^ zrPtnjzt4BZbi1$nzV3hSS5tvu<~PIdobP$~oX|WY$g?PCWV5!S;Z~90=D#H@Y$Opg>ZhU-?qq@*b_n zp<>R9-q?Tlr5IjknAz|D9LySvp*Uv5nLx}+rchr(YlL^+Q>=06;HGWxX;X#xRy5Yi_tUdtO;0g-3hEcZ_Z_bQw2xIYs7(6SfO+rof6KDGUpeww}?`!a;t< zove|JK_nE+X)`;8<<)Liu(r=LNgK$h#m7keC#vI+>Xu1h2WX$cO1ZF!Ih7J1(lwe3 zw}PszfLevxgFS58u9tG!0Q!Vk;PtC~?ifmi)J;YVF`b5H@8->elDV-K(}V3JlaW#( zL1=4865_^SJ6s0_-9H7#NOJ|7`{?k$()3&7aBM=?qdG(Oz!v&^(+Brfbg!N0`CjUr z!(X?|S?W8NpsimJ)BO60K}dNTCBvU^=kW<^xCpymq4%cxoVO`p`@OR%c(TISbYP++ z9npZ1f0p9;#;PC&^aF>p-8BAzO10b%zr|yTJ)dWfd%q_3U#)sBR1Lc+0kzoG!ftoh zRTPA#loC9TBddLM!l@BUbx1e${iTuBo31c?10_2$ffG zK1dBgKxuhp9*G{Go%omG$7AlT|K;S`lA6v(UR=^JX4;Dtd*@eaJ$=x&e1_ueuKIok zIErD&^&?}+Dhrz%xR+7;JaI+00+k4mdNzefc;H85j&(@hNyQy4h(v#a`7!iUBFDe; zC607QEy>rP@E7)t9dff5St^@}EtdL>?Uv2#4$Sa(-H{vy{)ruGgx?QVh zZqw?fGA`fX{&1b!fVWw6+tUAH-6i%P(Vo0AZLtUJ6eA++mcDiFtp$VGN!4Elqp#0R zsd$I=jv$G{*!$CLs03D8a<=xTw!Gw*^K@*8z3{JHXPKFZZ z>Q?>Zf6I&;bN{$+dF~G`e{J@6{(i=fPyO8W*qmS|gPZy?qt`J9$j#1hd667y2%DzG zl4bJ?t)+321Le3)J4rYXsR}}ESR|xDmAZQ9pJ&cOMw4nbqdDP4Jr55usxSz>D-S{* zEmuk2R{T>IVM)D*(M8Jszb(-xp}?MonwXB0z4dAvgQ!^u()_%?JN~0LdzNQ8 zn;1m-MC!Z#ZtKPC`Ss44>u`kmPA__)bgFUH_}j}XN4vVC#`oNC&fZ_KwLo5dZ#u93 zFmrkC=uy1s^eB1fPrlq=p4h9d{cs7_d2zB$ZDxR1*AGgqjW45R??oLmC4P8M z;nafHp4+&$CF}loYaVvRPd|RmpE`Ww;g7mZkK9vI6m$LF9OlA_LrilA3Rq@s?LJ>WnST zm+)dQ!vI6Zz*N(L0!yi+#!I-P_R$Xz1Sjud;+2j65?tpjG-CGcF6{69*$}A?2~d?r zC)8SfuFv^SF-fEsBs>)7n)tkCPp0ahI=-iGMU}Q5OYp4{%4m4J9KM%-1$gU6#e9aF zMH0|hz}Nb!)i>BPhbY{CQ@_cj<*A*<^}AfXhv!#j%?Js3xX+ThMr;cKY4oBhy#@Uzix=gUDQXJi zjs~q!8M8nafGWhMqqkcICW7Hs{Rn~PP564GJN}DhXSXL@E;@Mrb=Mo7|LOW9cH5`6 zsVQlz$G4z4t?!rjj=0||#H{@8jOEnJKRB!R{;T^x*4AhIdH!eJq2W)@Hs_{1*rOM{ zcD&1Z{NCgAb$rfw$60>6)I9kzg(wb!-C7$jGjau+1L?u}5zY|))LM*5w}_>`3|73y zUgX_qBo%Le_W<1xGF}zOOcF+<)!XTq&=j-K2=Hk0PV%+hBTsA)Vb!bZ9#HNwhf0*_!nVXkP z^eoyk(^9tVFFpF2Ifo=E)bcCJ&_Wsu11NpRrIk-}gq5gPQf;5{LMS;d&DgILgP&14 zQzGQp$+h0m6LTJ1edQO&AG_zLn|8TUnO1JicQBg9YG=$^fkZ*^a)oe|Bg_)s&-yW; zPrf6`6NiVoBHPr4H2Vz`<^=v9L#RBAXS$R&_3lOtNj;k)*3fZqjg{=@az{sPn(BV# z^pWJmk^4rv-*C3BWZ2e@`^VkhU*6le^89ubr4&V*?!LLGzqfzr8oO>5U^XVd={LkD z8-9ZZlv5ux^iV+NFss!2wC8i9Ez2{juHMr}bS^Y(7g0A{MTYG&k;_^S)ZY^~N_1x( zU3W70j|{4uV0pB%>#*$M1JG+`aHWaWmZ(lrtGn~-qxQj{J=Un-TCiRk>U^D6xt#|5??i?MGILcwU8^#OVbfYY94JyHQ7v1C&ThYV}IqCI6Ms9-$8G9rwdBtbp1@YY$E6xI>xAEo_rsCSK4Jo?QE(Bn>^b3;4l|u%0k2Sun75_-EDL!vk04o#4S;CYBW z0pZEeQx|(0$40bigo)c}3qg^c62nS+-MkIKyOY@U^o+0G{YlQh&h&cTJ<(uFePaH> z&M7-*++Vse{nY>3;qQLq{`KOyzBs#`c>vuy1hpsV5`!%%d;$r}ROCx)1S|e3#*h7< zj_~Lb6~>V&*R_Vu+e`%MR@lc{i=O#Y%qDY2(SX|aQA-4)mqns~qdEMPxve&s3;78C zNKB5Th*lMBZ8;Lg|2~M8*A)5lik*u1C;G;2UQ)-O&py16{ZUZ|f_b08I6-p87yC*R z8M@z|uN7pvwa$zOTDN?wP@bmO6mq#d1fL8k|d$FD(7=XQMlv&pz>H%NuhO{?NRmIK6(*c}@_6B(KF1 zbH467UA63tjnqpb2^9#wN%B?$c!~t2@k7~Zi;pC0ZxhhOuO8pC+&XqCfk%etf6jMx zH@^HrPQG5z{KBRm2R%o>Jy7*0y@h7=8%7#aIm_F1VzH9mvO+qrK0Uj=VPO7!PZ$|2 zx92nQDhj0$zX=ZoiI*6p%|{9bJR&tf_BH5Za>ge|LD%?n1aBFLtd6FaX1FnU89^P z7e90kjo8Oj^d8EME1{)Ao6R!UH`jZ$i6JsEM;D+zQ@~2i57gzMf26wRG#fuHEc_w1#5S*^6WO=5j|xxmQ$sXj&og8u;bnEUw@7$K|(mJ2n| zfQ4E_6I7C3NW3M%jzGUkWg@DhjE*V>dZR9SM=js}@FC^8SFjHzc2)DiJX#?>$OE$Zn5Y1?1ToVK*m)|g%*l-!5Q zNM=%hxa6a@oSL1pZ)E;yOZJF+{?WxPS?Z*WbsJ6vK~qc6mc1Y!u+CR8e1fo^SNao*Z?F8@0|hn z1O*bh(i?(PGfCuYnF#27toEEMR`xdz3STu0!|_~Ow*;kPf<)58G8wI5S|8o%MNNnP z^oO-~PqQs9pWW%1WXe$hnW|Hh4*})wMj=62zU(5Deko{QYfP)MU4F9aoO#;KM=S2? zIrQ!Ap5;%ctug7D=a!|8xUVjHtES=HR~`LHa|kzL29piZUv<^nLjxY<8ZAkhIF9&( zn)CrH)JK*2;1>|9dcv?<1_XBzD;e1&r5XGNAEaLS|KM`416_o)RoOy`H@-XpL*Ny5 z0+b_|BcU*(8Hh;&6$}EZ@qczW3@dDRGnBCSl>XGdP-pX+>Ra!n(E^0By?tra;k0}Qmij&6wZ@kR% z%DUyf9hYp&vnQn(l+g9lD&PjUB=7*wxho{ zi8Tz{+NP#RPl0A%u3f5)&uEQ#y=2ip$L`G9dyuR%``r$L(3x-D$n2cb{BqfUYGWR4 zs5w4=$fJ{J9pXkbfwZ%cyRE9HE4ke=?a0a{tD3q*%&_7$E_=LkPjd z0HzWBRY|mq1x3%B11H2;>6zzphUV(m%I%s>oBbtnjI($q zx~>)lZvxRdS^T@nJZO(zK`ogSN6f}TO}j!)0{tzn*pSn%JsRf&e70+EGQmixi9{nw z_8Jr_izSF?K*sAvS8Q#y+T@!)N8O7UM z|8CWX6r_ktH6A>e-saQ z5dwv6fsf8nDLn1pC%;kDv&^0G!Jt$u*JWTKTuBTB9YIw@*(AdFuYv2Z_!6R%a^|G0 zs+IUQElBN~go$!QG-*#b2#WSIRaR)%Uo6OpxFJ>95=$lP zgYpKo2T3ddU_zz_M{>Q#eu_L~OF~cd^AqxgZRWb7Pc2QndrVx<_tw@mj*x2}3_>D- zff3ba&O%lJe`3eW-l#dy7Xfk%#1{U-ItfS0A?#{BK`ez~~tCHH^KUSWyIGiJya6B^cr+%bS) zB(@iB0<)UU$XKc%kr(CGMSblXg_@sekDEFFZE$vBVGmubGeG7N(gL zza)YR%49MjM!ky$Xi8+0R0x5mY4c7ZL$UB56$t`YbydL{(I!!L*Q-!_m3K$nN05%8CN(h*W{8Rb=h6WRES1?KnDBh^t4! z`Z3<(uoEdZ>KnS;zvEbM20L(Hno{ggK87l8>+Gs z_(%6;&_qjKQ}@ftd@Q?eu{1O$M08}@$)@+1YM0vS2$nB$ zc{8q+JJ>TgG*^51bZM2=aN^dZ<-I5G`^QadCmg?f(Q~#pmXxh57+Alk|L#{ux}%@n zUjZ@xu_Tr%*41`8gB1h;2K<~k$gC1iBz{l_TOt8K=0Y!J2WQWzNd;1qAams~bFNK) zt0HMZpe?y%IJ>DzlaRg;=Hw1Vs-=tMck1`nPOC*yQ+&3d<*Dc*aaEq93F!X*5`o zwe9CjI%K`2C{kmoTXNFs=W@qf{ z*zJkA@Z8zQf3-E=2!_UZA@;c%yqkBFBw13s$V3K9wPFU>FiiDSyvNkwW`Cu?Bep%R z#ET#48WZZ(G^?r|8#3aS4A)~=@^)t1DI?Ne@{r$vT>^|_UeJe2yn|Fal*`i4R>Q6t zIa4hV;^cohITaGPWT0HCRmU!a0_f(#9@Ex6Lw(O?y}qq8!8sRxckXjuWlSu=zMb4%P%at?{Go?BO5aI z)LnXXnmL0ejJ8*pD4{RhPnQn$1y0Gj>|{M{5n^J_v{OF(s8ShaLlUAy93%6ERSz+x zY6c0(r~~M!OmFB@frK39u-{QyAwdbu__dOPoW*tFJ=FQfFc`W_RfOLRewEk!)uv3S z2fLCgs34M^PPxo1)<_9^I-6*V(PhH+;4!Fu)odq{S zcmz6xe^=di=IGwMn-)Nm_=(x9U-esLFtfdW{JE|S)4uE?c6SAg7rn3aUK}(gw;6IS zwGt1UHk>ZC)I9rTSBkxw0c(`kU|18ZqB%vCfg%bEqA1`YD%a7`t^{}|k&2{?$V03O zfJ;EL#)z)`i+yxojrZ_eyJfR=dqYFV!jOXgFrD z<6?E!%mbB8H&Q{L|E2Ik*8Bv2@9ECx-u%k`hWS-j-$yvRo;Grdxjy5j)$-f^udjHseesk@B>8h88%*v#I+0>lJ+JHPp z?NM)AXA1Y3bGOCDL0_$HfZ8JN#SV(0B2t8^{KI6}i=sD#7D9jX&eHK71?I_;14UQ` zXh+PeA+bt+!zg=LJM1#O%x@qDhEf*?*-97z=cE)%5n1(`tjFOS!)nhQE zfC-_pQ94A`&I18Z?ii~{ia2(6fp(kWMcJd6-ivB$Pm!fA{k^w+#fcgTThtBH?Gy-+opu{KW;101lVuU-Cr@YR7S zvx<}923gWGgMgjw+4kre^h^ZI@YOi_cG@c12!o3gZw;$~FtYPWU^COv{L|G}7hH3G zbS4z)XlG{jtLE$Pjoj>5Ed8U6q(>>94@bso-+Pj-V*+W2L`zs#5H|@tA zk5@G>JGlRMQ<{&R`pIWMTN1lt&FY(YpOK;Dj7#hGSCo~p*wk)sbapvT`BV2iz$y%G zy-9J;z-_Rkil|EMhaWVk^4J0utI}MIVdJ@Snjh4WSXeRg3P^|e`yo)0?pP6raNY1T z;sGKC!;Y2UHcCF`kta61cIliMYV|MXG(psjY{OZv-!+gsl-WC62&i0wF-1l)y zqxljV&;@J2R!PorlW3}U*lt_d{cEPiv{jOcB)2AXzSZDNh-xb**kEK4;W5(vBp9_+ z-vbHuL~$x)xQ6RPT7xX(6<#*rh}AVgypA5$jSfAX3cCgc>OHIxF2(S0x6Jo>y^MHO;MZtxpx&+ zu4J%*G9{Mtrv?KuCpTZ;Fjq)yoyI_7Y*CQ>0G7hbQ#<=m+Uz9$7;$ca<;06(pMIUETV*EBMmq-`Z4Z2idv88ur{T=fI#9 zntf)_@-^YHAf~}$!%5uE%ttC3s1=zXsNIf2NG8nkGy&vUTl*3QXdF$ceAE;+!8vZ> zk*+fL@T_kCagTQ5*-pn>L%1R*VS$Cxz>AIc<)(jQdR~U!`>W@xw75^T)i0i|xVGmU z-FMZquMTR?wU1RMzP(B4zqzQ-4xo=Aw|T?; zrihu~(N)(Oyb|#p!JK_s{Y-V@}Pf|uZNobr!Vnsb=CCMHL$m2yo2n#Oxh z)#Fn{ekCYtr>bQu?-2%2m6;J;4!;)|O`*Au`B*Vmz5UG-(tGb~EUDWyJ6T;-1 zYnicY)1Do2AN2$agI!IYrI;5REVN7S9 z_fSUM2B$@vvry)gEM6<5nZ0e=)2vxtV_!a1$~CQJDo1|T6}yXDC_3VELu8q?o{B2xGCKom^-3O}O^n?+C zR|rLcLq0Oh{G6s3+`c3&G4fB?(r}%|Y0L$tRrA!&9&B zSPSFHh0~iL;)sXhig+8@3N49_(dRoa7Ea#e8?_9p3ZLd`K}ECou=5bxEY?{_k2+5^ zvZ}kwn9w3-&9IYSG;i~|d+P1l)9o?rIY|A6u<)zzCWF5V6#jtDE!iyd4VlRsOrIduE*f#I9!!|30U{vcI~wyzS}O#yMSk2BO+34Yk92 zbc~^B8KUAvfAJYvd%^Y#U;Rk$jd|MU zuBy@tvlg_BUwmV?I;Q^?)pmt0f5Ys{Yq25P3AA6@*tRi8r zK>n>QQiu`7bGagFG~#7UqSw%gIhw^r!ioaWlv4~;FRWy$UdTs&#Cr-`j5j6&{~$WP zV4$-v=VpP|JLoYj9z(ojiL)vb7u)~ysp=fl9^=81^ypBMhd94g-pz~*fw3nd<5*)}R zoFW+uZPblS$)W_N?8IuZ8F&R5+-lB%9@noM$trb#QEegHiPfTRPjqHnF4G-5wMAHY zyaWL$NunHMDd2!)A&bB97|J6cc*N)#k-cgv>+xEEQ3y`Lzcmn|3VZixkFJtr7G5a# zQv~-m?65}HH3}vRh?gkuLaRDOW0lj?MnBu-hQ?8nl!SJZ)sXHeehJ#9w1S?bM+_FH zp-ZniP$h2#@y3O)McYMp03A=2q$A3p1y&KC?G;#+6bGqykhE2-@%R z8erqDpg;PIE~!NWvD(G!-sQBBvSvgA)}p89f0nqi&3IW4Ruc6lRAs09W>Kd02`UCs z=hdEL=ikb_gImjdnza5TLi`$+nLTRXBjw{T5iavW7Myo*!~!X z;upVoa^c*hngy`X#FncR|yb8Z(}%Ti718CY{N<+znj%+P&$z-6@F?;RUoCR3e2brj2v#} z`U0KNO1yPllk<469OSni+OD`iKb)k90b+s{4y4Fm_>$3@=8N4iD{P^q(|HJp@u~*XH*?cgg zeMju3V$HfopVI}+cUQ~6*!?w8o-(Sov{hgV=m$y9%&r_xd@2|!j!kr4t> z9?RS%-e6IqSQn>93;;_Xl_>x!LxbSbDt4~mn2hkFKtpD$*=gC7lc)>^fho}^%26LO zGND0?!2O;+Xp67Yyni>Hc^oIuBq!BfAuKDtN>ba1<{UBc|zh~O}l%s|i&z!;G3qP#7o+KNoXjx)G#^x?EdYu&6b z&G#Jn;l$FE_V&1_lBJI%*W!88kaa9mnfdk;nQxY`g4sQ6)n=>+e&qmUSX|b{p*Yit zXcnlaK6UW%JbfsIOqBt>c5Oe93;Fd9pYesYs;?1@K2BtoFl1 znPaInW@96a66|Oq-~aZ7Sc@61%37%4GaO_{TrqSBebfYQlp!bu8W0k^^?&63HjIRmvhekO1s&_{S zsX3L!c#B575{a+Cru#`;CBA?-R9CxGv`sbfNP$nWkW^AU5e5{C)#841#8=NyJbK3J z6}YZ|Q?j22TL!GH=USox1PY?p>H_YCX(hbzT^oNsl})hmgngsZB}!nAuow>-`Yg`p zYBXgpHX->yi@aN`PAPRO!vKZEI#h%&&)n>EMWNOec6;>s$DYl8Y9pXqN_5% zZ8%4r<*CkrlNn8*>$AJ`>i0^64BwQ(&TyK&q&HS5u=(12BD|cSCG}ozaU;898RF6C zH~c+zfzc8N4VNj%&_1A}a-GR3ubny7)a!X;u9p6nkuif8U~GKnM^F8%?+S)u*|Q%# z^zo%54-M@6-)n!Wfh4H`YPBS~Zv(bl_@jh9AW9$@zuy4oY0lqj1f1?W52!=UUf^RY zag~FgArpL=lA?3=`y@()8Q4SWfIm5qx1M>H*(!m6tR`ZoNnAl5B7Mn1A9|PZsd8i_ zq7v-xsz7GI_z*S!1ptx(6e1#`jpM;~ z$|7@u&5I+-z`Ut3-uu#zG#3x7*tK}pyj>j~`R&h+Yiqgxz!P1Lx9J|UFORZqB&m2e zQ}5923jQ9}I^L@2uT3!4lej`F<6z@P2nv#$WU$sVK|BLSV=t<3w8(OynD?GblVNe} zD3aLBxazlprr8}ANl0S{lT(AA9-C5@WhnbCrK!b_yaUrZlzj-bx!F4hBPx-%_M#K$v%8O)(6#OobdnlA0=c zkfAW!e%1Tcf_OsyQ+J*SB}q;*=AMjpJ}@`MEQc*f1|U`!xiL_pSF@jOnizdQBd~{GL;j-+5~0)Yzig z?>;l{?BhL-EA@KyTi1)4(%0%BQ4u2GkOm;m{bg$FaN-4O%%Tk_$p(QY?5$Dg#ILCU z!+#+6^tvW@QL7aOKB1`?mY`qjxO@}_p048AIz9cpwdMD|y>-sKk%DE;=YIZB@)75( z?|lE2gFjm`X5iAHfd*qm;RX9KL$x0QadL8VPLU>5q_%Q|V!Q%h5f3PWH>SuA9TY|4 z&O1qm{H)bqf?ygwJ^ZlD^iayuqJjoo1Q7)`TFVf4LG2Y%5Y`%@r1A)y071>Ed0hpz zCo#|pd4-q-fr`W?xD37FI6~^QwEu9d5rY!5#R05ZC3Hdj>>l(>qDuxhT6Ri?A+BA# zqR)^sA#7YAh$R6`FEo*-j0V?)hpJ|93OmG5q)N8vUX>1VuBH@8Fe=YP;$tJ(D3#ev zH-PMPZwT%jW=$@^$9eymw71(A3>jf~T~PLuOpz)?hHj@kVrQ3qE?7mo#YX^$LFYV- zN{2#wg|$}ij(Yp!zbx&UzWz_c-DS)>d*EZA{(~a`oXi4|gD6G-n8LK>n3M3dw4CM{ z+9D)==-ACZK1WLPd3{_AJE5mPH=KHrDA!oKe8UudZy;-K!nl&y1kE?U!Ps<~9Rtt3 ze_(Lp%45lukFR`pYxbO(g%dxl{rvlHer_qNd}P(C-M^i=F%c89mykl4@-yEYc#Vvy zPZz7mGUvsQ~M%jX;+?10FQdxDIr z;ECL{aI#wM9|GdhH=0i^5>>W3_^DY!9@=~(UkxGckRw!kA5vLRYOX?mPCQ?3$x5cn+Hf%9kG9 zI%;3^#`M=qEA8W`)8e|%>joz1rMtTOx0}YzzOvnR@*fyjXXi?ST&0j^w0Vh1{?`pi zSr0MN?&9r(hQ9S)+(gQ_;qF*Ay#9M%=cxvJxKy4h&YLWfH_L;B@hUNisE3^OLSzOgc~5Ei=T87v0<~--R_ni-#q1@IcjPcUuhItz9 zw#7T_YmVUOW80!?`mV6iXL5P+K{Xp-nuhHtcnKnU4vQH6;`1!FoJzQRUqXX%T zhP)>y#*NPmT>8gCv#WFBH23xprdvYGE?=7Y^hTkMGV?jC8dwczr>mP1#u8iWUv^y1 z>jSQ|d8y!z+GL#@sHiq>FIzUI^U)Qhue-{2-c0G(G4e^$s%bU%j!&=@Z+*klv}yOF z?^NbT31s%UyQ<96@fD7KR|^pzVaYxtnS~al7o~Q)lrH$-GH~k3b_om-GX;KVhUK6- z=&=0ujuSB^an7|2r4Xo!7V0Z%TLuy?PvX)XcRVz+k%U_l?~GyHdKdg1Yg6>I9Tyy3 z+CrkxZEfbULsIH|(~l#dx4;XgA$wb~&k|WM(RRmEsEsO)C`TlfEp&Hb5{C0nbUuJin-o%&BfgfQGv%& ze*iC9nWo8DlL3BdH~XAm0L^bgi*OQ?f&n!3*sKdgOdc8TE~a#ZccrdLaTVTe1h zr?hQzZ1XF94}R7aq%MB)mz(yDej?jFf5FTJwo5x6r7-f*cHlH-sP)m&y7_uxADwe% zSC^Zk&5$hMba7VErRc_;S{SwhEL{S*upSr*Bu#M=O;VK;7ZMI2gcTHXdY>bO>7@&? zGpGVDz%)yJ-AS~ei41e)d=(qu7S`m@^sez35yGT-?akcb`o0ugd4@g2lT^M?NkzFOsYwg;k+ZnV z#4p6KdoVOK>>j79lnjHq)}8Kz7Ku_L8et{cARhsNMo{Hq%`tHjb4q$qgmkGOD52UL z+g4&p#N}WS=&BTQF|WY~MD3H#l^(P%kpPv6JXj;IfmacLVmNdlR5fq{+9)um!8?He z*~dF^9d&8>1Kw&VsGlDJDg@dxVe~M9{}5I9w#CYnQHzP2IU->uh9AFr#xh8`;bD&F zrR`eJ&GMACEK_aA1y_6aO1dj9q-?*=Qd{)c9J+@uDRlWJuCFSF??tSpga!b;~um9%j;%?iT7mj)k8~>v{%FAx} z->m(?|GKjHa=!lHnNi<4eR)xT;veq+;o!KSwQAHYUq}4TckVAw&Mb8!mR$@Zxl*=Q?WLr_GQ+O4VEva0eA5}Wr*}b zt}5oG51ji)E2{9%@hgk8gc%|)NowcGW@nSQ6FvbdAaS1$DGR!;r1jwKzVM^?e^m(M zBd@gU_@zizVG+rStLdE8)Q43O*B?T5Z-$*&Ro0?{&!r;VmQ_ zO9r)Y*HP4(z)C|~Q#xT4<8!anXUrBf^ID8ed-4{^rjcxL(5~GqEKmQU%{D%B) zt_@I4w^b&;sBiSgHddX>a?J@YOCR2@ooGllus}ZEP;q8U#lwZhekPR^p`X{h=xCqM z&ryQHMTj&03~|K;dzr<`T3wukNFCS0(`@CcC)@BO%y*Sx0yF&0;TQM7b^hiHzD7MM zgAHBS2EK@CAWVZP1)@z7fN{xS(rt0M83D+2Bp{+TO;FBo3yN5GL6a!AN+4kiPYN*= zS)0W$JP=a%b%wmN&XOZ~Y{bZ%S80NC{sBYhNM=kyC5Z}o1QZNp_f}T{Q=8RidAZX) zqs^+$HsY;fVyl@v7Rlblo58^=PF!PWB38wWTtnto2{(GdBW>@BuPG zc0tARvlE*ozLsbh4HNORS-y9QLs+*dp3k*}svrcI%+2X-xp8e;3A6~jKi-}``R;^M zf@kFn#^ruIY&dyVPst$nj~zv^TPu~}LO$cI!MLK*(yi4qbGwfRt86aUGr=a@CbK`L zr6k3%TrTrN%eY&G7pA2EGbe*d5nf2kN3;AG;2!_lYggX3L1 zERjOqO~ct~J-=V@;-R<}d

SqIyFY+Z2YM&w{N35MlCz>Y?q;k=6tda0vwLC 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 literal 0 HcmV?d00001 diff --git a/src/main/webapp/gxt/flash/swfobject.js b/src/main/webapp/gxt/flash/swfobject.js new file mode 100644 index 0000000..4b704c5 --- /dev/null +++ b/src/main/webapp/gxt/flash/swfobject.js @@ -0,0 +1,5 @@ +/* SWFObject v2.1 + Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis + This software is released under the MIT License +*/ +var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("