<children xsi:type="advanced:PerspectiveStack" xmi:id="_gm_toDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.perspectivestack.0">
<children xsi:type="advanced:Perspective" xmi:id="_hr-YsDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.perspective.dashboard" label="Dashboard">
<children xsi:type="basic:PartSashContainer" xmi:id="_mAC18DAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partsashcontainer.0" horizontal="true">
- <children xsi:type="basic:PartStack" xmi:id="_orJxUDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partstack.0" containerData="4000">
- <children xsi:type="basic:Part" xmi:id="_qAM4sDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.part.search" containerData="" contributionURI="bundleclass://org.argeo.suite.e4/org.argeo.suite.e4.parts.QuickSearchView" label="Search"/>
+ <children xsi:type="basic:PartStack" xmi:id="_orJxUDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partstack.0" containerData="3000">
+ <tags>minimized</tags>
+ <children xsi:type="basic:Part" xmi:id="_qAM4sDAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.part.search" containerData="" contributionURI="bundleclass://org.argeo.suite.e4/org.argeo.suite.e4.parts.QuickSearchView" label="Search" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/actions/search.png"/>
</children>
- <children xsi:type="basic:PartStack" xmi:id="_vLza4DAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partstack.1" containerData="6000">
+ <children xsi:type="basic:PartStack" xmi:id="_vLza4DAVEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partstack.1" containerData="7000">
<tags>entityEditorArea</tags>
+ <children xsi:type="basic:Part" xmi:id="_n83mkDDnEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.part.0" contributionURI="bundleclass://org.argeo.suite.e4/org.argeo.suite.e4.parts.DefaultDashboardEditor" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/types/dashboard.png"/>
</children>
</children>
</children>
</children>
<trimBars xmi:id="_24OSADArEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.trimbar.0">
- <children xsi:type="menu:ToolBar" xmi:id="_3e5QcDArEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.toolbar.0">
+ <children xsi:type="menu:ToolBar" xmi:id="_JIUjADDhEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.toolbar.standard">
+ <children xsi:type="menu:HandledToolItem" xmi:id="_P-4LIDDhEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handledtoolitem.save" label="Save" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/actions/save.png" enabled="false" command="_1lO94DDgEeiUfOa4rxEKwQ"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_W4V9UDDhEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handledtoolitem.saveall" label="Save All" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/actions/save-all.png" enabled="false" command="_5EpEADDgEeiUfOa4rxEKwQ"/>
+ <children xsi:type="menu:HandledToolItem" xmi:id="_bV4tYDDmEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handledtoolitem.closeall" label="Close All" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/actions/close-all.png" command="_VdldQDDmEeiUfOa4rxEKwQ"/>
+ <children xsi:type="menu:ToolBarSeparator" xmi:id="_Bn7o0DDjEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.toolbarseparator.0"/>
<children xsi:type="menu:HandledToolItem" xmi:id="_4Ssr8DArEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.handledtoolitem.createTask" label="New Task" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/types/task.png" command="_2Xkt8DApEei3AbO1ldMI0w">
<parameters xmi:id="_NYpK8DAsEei3AbO1ldMI0w" elementId="targetNodeType" name="targetNodeType" value="activities:task"/>
</children>
</trimBars>
</children>
<handlers xmi:id="_ipB00DArEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.handler.0" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.connect.e4.handlers.CreateEntity" command="_2Xkt8DApEei3AbO1ldMI0w"/>
- <descriptors xmi:id="_pud7kDAtEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.taskEditor" label="Task" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.activities.e4.parts.TaskEditor"/>
- <descriptors xmi:id="_JsNs8DBiEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.personEditor" label="Person" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.people.e4.parts.PersonEditor"/>
- <descriptors xmi:id="_RxqxIDBiEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.orgEditor" label="Organisation" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.people.e4.parts.OrgEditor"/>
+ <handlers xmi:id="_9gu00DDgEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handler.1" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.connect.e4.handlers.SavePart" command="_1lO94DDgEeiUfOa4rxEKwQ"/>
+ <handlers xmi:id="_ADDAkDDhEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handler.2" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.connect.e4.handlers.SaveAllParts" command="_5EpEADDgEeiUfOa4rxEKwQ"/>
+ <handlers xmi:id="_ZBWe8DDmEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.handler.3" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.connect.e4.handlers.CloseAllParts" command="_VdldQDDmEeiUfOa4rxEKwQ"/>
+ <bindingTables xmi:id="_gxEm4DDqEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.bindingtable.0">
+ <bindings xmi:id="_hj9cYDDqEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.keybinding.0" keySequence="CTRL+S" command="_1lO94DDgEeiUfOa4rxEKwQ"/>
+ <bindings xmi:id="_pEAGYDDqEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.keybinding.1" keySequence="SHIFT+CTRL+S" command="_5EpEADDgEeiUfOa4rxEKwQ"/>
+ </bindingTables>
+ <descriptors xmi:id="_pud7kDAtEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.taskEditor" label="Task" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/types/task.png" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.activities.e4.parts.TaskEditor"/>
+ <descriptors xmi:id="_JsNs8DBiEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.personEditor" label="Person" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/types/person.png" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.people.e4.parts.PersonEditor"/>
+ <descriptors xmi:id="_RxqxIDBiEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.partdescriptor.orgEditor" label="Organisation" iconURI="platform:/plugin/org.argeo.theme.argeo2/icons/types/organisation.png" allowMultiple="true" category="entityEditorArea" closeable="true" dirtyable="true" contributionURI="bundleclass://org.argeo.connect.e4/org.argeo.people.e4.parts.OrgEditor"/>
<commands xmi:id="_2Xkt8DApEei3AbO1ldMI0w" elementId="org.argeo.suite.e4.command.createEntity" commandName="Create">
<parameters xmi:id="_GnXrcDAsEei3AbO1ldMI0w" elementId="targetNodeType" name="targetNodeType" optional="false"/>
</commands>
+ <commands xmi:id="_1lO94DDgEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.command.savePart" commandName="Save"/>
+ <commands xmi:id="_5EpEADDgEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.command.saveAll" commandName="Save All"/>
+ <commands xmi:id="_VdldQDDmEeiUfOa4rxEKwQ" elementId="org.argeo.suite.e4.command.closeAll" commandName="Close All"/>
<addons xmi:id="_bQjNYTAVEei3AbO1ldMI0w" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/>
<addons xmi:id="_bQjNYjAVEei3AbO1ldMI0w" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/>
<addons xmi:id="_bQjNYzAVEei3AbO1ldMI0w" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/>
--- /dev/null
+package org.argeo.suite.e4.parts;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+import org.argeo.cms.ui.eclipse.forms.FormToolkit;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.connect.SystemAppService;
+import org.argeo.connect.resources.ResourcesService;
+import org.argeo.connect.ui.AppWorkbenchService;
+import org.argeo.connect.ui.ConnectUiStyles;
+import org.argeo.connect.ui.SystemWorkbenchService;
+import org.argeo.connect.util.ConnectJcrUtils;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.jcr.JcrUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+
+/** Generic dashboard for Argeo Suite applications */
+public abstract class AbstractSuiteDashboard {
+
+ // DEPENDENCY INJECTION
+ private Repository repository;
+ private ResourcesService resourcesService;
+ private SystemAppService systemAppService;
+ private SystemWorkbenchService systemWorkbenchService;
+
+ private Session session;
+
+ // UI Objects
+ private FormToolkit toolkit;
+
+ public void init() {
+ session = ConnectJcrUtils.login(repository);
+// updateTooltip(input);
+ }
+
+// private void updateTooltip(IEditorInput input) {
+// if (input instanceof EntityEditorInput) {
+// EntityEditorInput sei = (EntityEditorInput) input;
+// sei.setTooltipText("My Dashboard");
+// }
+// }
+
+ /**
+ * Implementing classes must call super in order to create the correct form
+ * toolkit
+ */
+ @PostConstruct
+ public void createPartControl(Composite parent) {
+ toolkit = new FormToolkit(Display.getCurrent());
+ init();
+ }
+
+ // UTILS
+ protected Composite createGadgetCmp(Composite parent, int widthHint, int heightHint) {
+ Composite gadgetCmp = toolkit.createComposite(parent, SWT.BORDER);
+ GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
+ gd.widthHint = widthHint;
+ gd.heightHint = heightHint;
+ gadgetCmp.setLayoutData(gd);
+ CmsUtils.style(gadgetCmp, ConnectUiStyles.GADGET_BOX);
+ return gadgetCmp;
+ }
+
+ protected Composite createGadgetTitleCmp(Composite parent, String title) {
+ Composite titleCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE);
+ CmsUtils.style(titleCmp, ConnectUiStyles.GADGET_HEADER);
+ titleCmp.setBackground(null);
+ GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false);
+ titleCmp.setLayoutData(gd);
+ titleCmp.setLayout(new GridLayout());
+
+ Label titleLbl = toolkit.createLabel(titleCmp, title + " ", SWT.BOLD);
+ CmsUtils.style(titleLbl, ConnectUiStyles.GADGET_HEADER);
+ titleLbl.setBackground(null);
+ return titleCmp;
+ }
+
+ protected Composite createGadgetBodyCmp(Composite parent) {
+ Composite bodyCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE);
+ bodyCmp.setLayoutData(EclipseUiUtils.fillAll());
+ bodyCmp.setLayout(new GridLayout());
+ return bodyCmp;
+ }
+
+ protected Link createOpenEntityEditorLink(final AppWorkbenchService peopleUiService, Composite parent,
+ final String label, final Node entity) {
+ Link link = new Link(parent, SWT.NONE);
+ link.setText("<a>" + label + "</a>");
+ link.setLayoutData(EclipseUiUtils.fillWidth());
+ link.addSelectionListener(new SelectionAdapter() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void widgetSelected(final SelectionEvent event) {
+ // Map<String, String> params = new HashMap<String, String>();
+ // params.put(ConnectEditor.PARAM_JCR_ID,
+ // ConnectJcrUtils.getIdentifier(entity));
+ // CommandUtils.callCommand(peopleUiService.getOpenEntityEditorCmdId(), params);
+ peopleUiService.openEntityEditor(entity);
+ }
+ });
+ return link;
+ }
+
+ // Life cycle
+ @PreDestroy
+ public void dispose() {
+ JcrUtils.logoutQuietly(session);
+ }
+
+
+ // Expose to implementing classes
+ protected Session getSession() {
+ return session;
+ }
+
+ public ResourcesService getResourcesService() {
+ return resourcesService;
+ }
+
+ protected SystemAppService getSystemAppService() {
+ return systemAppService;
+ }
+
+ protected SystemWorkbenchService getSystemWorkbenchService() {
+ return systemWorkbenchService;
+ }
+
+ protected FormToolkit getFormToolkit() {
+ return toolkit;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+
+ public void setResourcesService(ResourcesService resourcesService) {
+ this.resourcesService = resourcesService;
+ }
+
+ public void setSystemAppService(SystemAppService systemAppService) {
+ this.systemAppService = systemAppService;
+ }
+
+ public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) {
+ this.systemWorkbenchService = systemWorkbenchService;
+ }
+}
--- /dev/null
+package org.argeo.suite.e4.parts;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.activities.ActivitiesNames;
+import org.argeo.activities.ActivitiesService;
+import org.argeo.activities.ui.TaskViewerContextMenu;
+import org.argeo.cms.auth.CurrentUser;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.connect.ConnectException;
+import org.argeo.connect.ConnectNames;
+import org.argeo.connect.ui.ConnectWorkbenchUtils;
+import org.argeo.connect.ui.Refreshable;
+import org.argeo.connect.util.ConnectJcrUtils;
+import org.argeo.eclipse.ui.EclipseUiUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.node.NodeUtils;
+import org.argeo.tracker.TrackerNames;
+import org.argeo.tracker.TrackerService;
+import org.argeo.tracker.TrackerTypes;
+import org.argeo.tracker.core.TrackerUtils;
+import org.argeo.tracker.ui.TaskListLabelProvider;
+import org.argeo.tracker.ui.TaskVirtualListComposite;
+import org.eclipse.e4.ui.di.Focus;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+
+/** Argeo Suite Default Dashboard */
+public class DefaultDashboardEditor extends AbstractSuiteDashboard implements Refreshable {
+ final static Log log = LogFactory.getLog(DefaultDashboardEditor.class);
+ // public final static String ID = AsUiPlugin.PLUGIN_ID +
+ // ".defaultDashboardEditor";
+
+ private ActivitiesService activitiesService;
+ private TrackerService trackerService;
+
+ private String datePattern = "dd MMM yyyy";
+
+ private Composite headerCmp;
+ private Composite taskListCmp;
+ private TaskVirtualListComposite tvlc;
+
+ @PostConstruct
+ public void createPartControl(Composite parent) {
+ super.createPartControl(parent);
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ Composite bodyCmp = new Composite(parent, SWT.NO_FOCUS);
+ bodyCmp.setLayoutData(EclipseUiUtils.fillAll());
+ bodyCmp.setLayout(new GridLayout());
+
+ headerCmp = new Composite(bodyCmp, SWT.NO_FOCUS);
+ headerCmp.setLayoutData(EclipseUiUtils.fillWidth());
+
+ taskListCmp = new Composite(bodyCmp, SWT.NO_FOCUS);
+ taskListCmp.setLayoutData(EclipseUiUtils.fillAll());
+ forceRefresh(null);
+ }
+
+ @Override
+ public void forceRefresh(Object object) {
+ CmsUtils.clear(headerCmp);
+ populateHeaderPart(headerCmp, NodeUtils.getUserHome(getSession()));
+
+ CmsUtils.clear(taskListCmp);
+ populateTaskListCmp(taskListCmp);
+
+ headerCmp.getParent().layout(true, true);
+ }
+
+ private void populateTaskListCmp(Composite parent) {
+ parent.setLayout(EclipseUiUtils.noSpaceGridLayout());
+ NodeIterator nit = activitiesService.getMyTasks(getSession(), true);
+ if (!nit.hasNext()) {
+ Composite noTaskCmp = new Composite(parent, SWT.NO_FOCUS);
+ noTaskCmp.setLayoutData(EclipseUiUtils.fillAll());
+ noTaskCmp.setLayout(new GridLayout());
+
+ Label noTaskLbl = new Label(noTaskCmp, SWT.CENTER);
+ noTaskLbl.setText("<i> <big> You have no pending Task. </big> </i>");
+ CmsUtils.markup(noTaskLbl);
+ noTaskLbl.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, true, true));
+
+ final Link createTaskLk = new Link(noTaskCmp, SWT.CENTER);
+ createTaskLk.setText("<a> Create a task </a>");
+ createTaskLk.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, true));
+
+ createTaskLk.addSelectionListener(new SelectionAdapter() {
+ private static final long serialVersionUID = -9028457805156989935L;
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String mainMixin = TrackerTypes.TRACKER_TASK;
+ String pathCreated = ConnectWorkbenchUtils.createAndConfigureEntity(createTaskLk.getShell(),
+ getSession(), getSystemAppService(), getSystemWorkbenchService(), mainMixin);
+ if (EclipseUiUtils.notEmpty(pathCreated))
+ forceRefresh(null);
+ }
+ });
+
+ } else {
+ TaskListLabelProvider labelProvider = new TaskListLabelProvider(trackerService);
+ tvlc = new TaskVirtualListComposite(parent, SWT.NO_FOCUS, (ILabelProvider) labelProvider, 54);
+ tvlc.setLayoutData(EclipseUiUtils.fillAll());
+ final TableViewer viewer = tvlc.getTableViewer();
+ viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray());
+ final TaskViewerContextMenu contextMenu = new TaskViewerContextMenu(viewer, getSession(),
+ activitiesService) {
+ @Override
+ public boolean performAction(String actionId) {
+ boolean hasChanged = super.performAction(actionId);
+ if (hasChanged) {
+ viewer.getTable().setFocus();
+ forceRefresh(null);
+ // NodeIterator nit =
+ // activitiesService.getMyTasks(getSession(), true);
+ // viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray());
+ }
+ return hasChanged;
+ }
+ };
+ viewer.getTable().addMouseListener(new MouseAdapter() {
+ private static final long serialVersionUID = 6737579410648595940L;
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ if (e.button == 3) {
+ // contextMenu.setCurrFolderPath(currDisplayedFolder);
+ contextMenu.show(viewer.getTable(), new Point(e.x, e.y),
+ (IStructuredSelection) viewer.getSelection());
+ }
+ }
+ });
+
+ }
+ }
+
+ private boolean isOverdue(Node node, String propName) {
+ try {
+ Calendar now = GregorianCalendar.getInstance();
+ return node.hasProperty(propName) && node.getProperty(propName).getDate().before(now);
+ } catch (RepositoryException e) {
+ throw new ConnectException("Cannot check overdue status with property " + propName + " on " + node, e);
+ }
+ }
+
+ private void populateHeaderPart(Composite bodyCmp, Node context) {
+ bodyCmp.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, true)));
+
+ Composite leftCmp = new Composite(bodyCmp, SWT.NO_FOCUS);
+ leftCmp.setLayout(new GridLayout());
+ leftCmp.setLayoutData(EclipseUiUtils.fillWidth());
+ Composite rightCmp = new Composite(bodyCmp, SWT.NO_FOCUS);
+ rightCmp.setLayout(new GridLayout());
+ rightCmp.setLayoutData(EclipseUiUtils.fillWidth());
+
+ // Title
+ Label titleLbl = new Label(leftCmp, SWT.WRAP | SWT.LEAD);
+ CmsUtils.markup(titleLbl);
+ String titleStr = "<big><b> Hello " + CurrentUser.getDisplayName() + " </b></big>";
+ titleLbl.setText(titleStr);
+ GridData gd = new GridData(SWT.TOP, SWT.BOTTOM, false, false);
+ gd.verticalIndent = 5;
+ gd.horizontalIndent = 10;
+ titleLbl.setLayoutData(gd);
+
+ NodeIterator nit = activitiesService.getMyTasks(getSession(), true);
+ if (nit.hasNext()) {
+ List<Node> overdueTasks = new ArrayList<>();
+ while (nit.hasNext()) {
+ Node currNode = nit.nextNode();
+ if (isOverdue(currNode, ActivitiesNames.ACTIVITIES_DUE_DATE))
+ overdueTasks.add(currNode);
+ }
+ if (!overdueTasks.isEmpty()) {
+ Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS);
+ long size = overdueTasks.size();
+ String overdueStr = "You have " + size + " overdue task" + (size > 1 ? "s" : "") + ": ";
+ populateMuliValueClickableList(overdueCmp, overdueTasks.toArray(new Node[0]), new TaskLp(), overdueStr);
+ }
+ }
+
+ nit = trackerService.getMyMilestones(getSession(), true);
+ List<Node> openMilestones = new ArrayList<>();
+
+ if (nit.hasNext()) {
+ List<Node> overdueMilestones = new ArrayList<>();
+ while (nit.hasNext()) {
+ Node currNode = nit.nextNode();
+ openMilestones.add(currNode);
+ if (isOverdue(currNode, TrackerNames.TRACKER_TARGET_DATE))
+ overdueMilestones.add(currNode);
+ }
+ if (!overdueMilestones.isEmpty()) {
+ Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS);
+ long size = overdueMilestones.size();
+ String overdueStr = "You have " + size + " overdue milestone" + (size > 1 ? "s" : "") + ": ";
+ populateMuliValueClickableList(overdueCmp, overdueMilestones.toArray(new Node[0]), new MilestoneLp(),
+ overdueStr);
+ }
+ }
+
+ // My projects
+ List<Node> openProjects = JcrUtils.nodeIteratorToList(trackerService.getMyProjects(getSession(), true));
+ if (!openProjects.isEmpty()) {
+ Group myProjectsGp = new Group(rightCmp, SWT.NO_FOCUS);
+ myProjectsGp.setText("My open projects");
+ myProjectsGp.setLayoutData(EclipseUiUtils.fillWidth());
+ populateMuliValueClickableList(myProjectsGp, openProjects.toArray(new Node[0]), new ProjectLp(), null);
+ }
+
+ // My Milestones
+ if (!openMilestones.isEmpty()) {
+ Group myMilestoneGp = new Group(rightCmp, SWT.NO_FOCUS);
+ myMilestoneGp.setText("My open milestones");
+ myMilestoneGp.setLayoutData(EclipseUiUtils.fillWidth());
+ populateMuliValueClickableList(myMilestoneGp, openMilestones.toArray(new Node[0]), new MilestoneLp(), null);
+ }
+ }
+
+ private class ProjectLp extends ColumnLabelProvider {
+ private static final long serialVersionUID = 7231233932794865555L;
+
+ @Override
+ public String getText(Object element) {
+ Node project = (Node) element;
+
+ String percent;
+ NodeIterator nit = TrackerUtils.getIssues(project, null, null, null, true);
+ long openNb = nit.getSize();
+
+ nit = TrackerUtils.getIssues(project, null, null, null, false);
+ long allNb = nit.getSize();
+
+ if (allNb < 1)
+ percent = "empty";
+ else {
+ double num = allNb - openNb;
+ double result = num / allNb * 100;
+ percent = String.format("%.1f", result) + "% done";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append("<a>").append(ConnectJcrUtils.get(project, Property.JCR_TITLE)).append("</a>");
+ builder.append(" (").append(percent).append(")");
+
+ return builder.toString();
+ }
+ }
+
+ private class MilestoneLp extends ColumnLabelProvider {
+ private static final long serialVersionUID = 7231233932794865555L;
+
+ @Override
+ public String getText(Object element) {
+ Node milestone = (Node) element;
+ Node project = TrackerUtils.getRelatedProject(trackerService, milestone);
+ String dueDate = ConnectJcrUtils.getDateFormattedAsString(milestone, TrackerNames.TRACKER_TARGET_DATE,
+ datePattern);
+
+ String percent;
+ String propName = TrackerNames.TRACKER_MILESTONE_UID;
+ String muid = ConnectJcrUtils.get(milestone, ConnectNames.CONNECT_UID);
+ NodeIterator nit = TrackerUtils.getIssues(project, null, propName, muid, true);
+ long openNb = nit.getSize();
+
+ nit = TrackerUtils.getIssues(project, null, propName, muid, false);
+ long allNb = nit.getSize();
+
+ if (allNb < 1)
+ percent = "empty";
+ else {
+ double num = allNb - openNb;
+ double result = num / allNb * 100;
+ percent = String.format("%.1f", result) + "% done";
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append("<a>").append(ConnectJcrUtils.get(milestone, Property.JCR_TITLE)).append("</a>");
+ builder.append(" (");
+ if (EclipseUiUtils.notEmpty(dueDate))
+ builder.append("due to ").append(dueDate).append(", ");
+
+ builder.append(percent).append(")");
+ return builder.toString();
+ }
+
+ @Override
+ public Color getForeground(Object element) {
+ Node milestone = (Node) element;
+ Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE);
+ if (dueDate != null && dueDate.before(Calendar.getInstance()))
+ return Display.getCurrent().getSystemColor(SWT.COLOR_RED);
+ return null;
+ }
+ }
+
+ private class TaskLp extends ColumnLabelProvider {
+ private static final long serialVersionUID = 7231233932794865555L;
+
+ @Override
+ public String getText(Object element) {
+ Node task = (Node) element;
+ String dueDate = ConnectJcrUtils.getDateFormattedAsString(task, ActivitiesNames.ACTIVITIES_DUE_DATE,
+ datePattern);
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("<a>").append(ConnectJcrUtils.get(task, Property.JCR_TITLE)).append("</a>");
+ if (EclipseUiUtils.notEmpty(dueDate))
+ builder.append(" (").append("due to ").append(dueDate).append(")");
+ return builder.toString();
+ }
+
+ @Override
+ public Color getForeground(Object element) {
+ Node milestone = (Node) element;
+ Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE);
+ if (dueDate != null && dueDate.before(Calendar.getInstance()))
+ return Display.getCurrent().getSystemColor(SWT.COLOR_RED);
+ return null;
+ }
+ }
+
+ @Focus
+ public void setFocus() {
+ // refreshDocListGadget();
+ }
+
+ public void setActivitiesService(ActivitiesService activitiesService) {
+ this.activitiesService = activitiesService;
+ }
+
+ public void setTrackerService(TrackerService trackerService) {
+ this.trackerService = trackerService;
+ }
+
+ // LOCAL HELPERS
+ private void populateMuliValueClickableList(Composite parent, Node[] nodes, ColumnLabelProvider lp,
+ String listLabel) {
+ CmsUtils.clear(parent);
+ RowLayout rl = new RowLayout(SWT.HORIZONTAL | SWT.WRAP);
+ rl.wrap = true;
+ rl.marginLeft = rl.marginTop = rl.marginBottom = 0;
+ rl.marginRight = 8;
+ parent.setLayout(rl);
+
+ if (EclipseUiUtils.notEmpty(listLabel)) {
+ Link link = new Link(parent, SWT.NONE);
+ link.setText(listLabel);
+ link.setFont(EclipseUiUtils.getBoldFont(parent));
+ }
+
+ int i = 1;
+ for (Node node : nodes) {
+ Link link = new Link(parent, SWT.NONE);
+ CmsUtils.markup(link);
+ link.setText(lp.getText(node) + (i != nodes.length ? ", " : ""));
+ i++;
+ // Color fc = lp.getForeground(node);
+ // if (fc != null)
+ // link.setForeground(fc);
+
+ link.addSelectionListener(new SelectionAdapter() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void widgetSelected(final SelectionEvent event) {
+ // CommandUtils.callCommand(getSystemWorkbenchService().getOpenEntityEditorCmdId(),
+ // ConnectEditor.PARAM_JCR_ID, ConnectJcrUtils.getIdentifier(node));
+ getSystemWorkbenchService().openEntityEditor(node);
+ }
+ });
+ }
+ }
+
+}