/******************************************************************************* * Copyright (c) 2011 GitHub Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Kevin Sawicki (GitHub Inc.) - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.github.ui.gist; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.window.ToolTip; import org.eclipse.mylyn.commons.ui.CommonImages; import org.eclipse.mylyn.commons.ui.TableViewerSupport; import org.eclipse.mylyn.commons.workbench.forms.CommonFormUtil; import org.eclipse.mylyn.internal.tasks.core.TaskAttachment; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.internal.tasks.ui.commands.OpenTaskAttachmentHandler; import org.eclipse.mylyn.internal.tasks.ui.editors.AttachmentTableLabelProvider; import org.eclipse.mylyn.internal.tasks.ui.editors.EditorUtil; import org.eclipse.mylyn.internal.tasks.ui.editors.TaskEditorAttachmentPart; import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiMenus; import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard.Mode; import org.eclipse.mylyn.tasks.core.ITaskAttachment; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; /** * Gist editor attachment part. Modeled after {@link TaskEditorAttachmentPart} * but with less columns. */ public class GistAttachmentPart extends AbstractTaskEditorPart { private static final String ID_POPUP_MENU = "org.eclipse.mylyn.tasks.ui.editor.menu.attachments"; //$NON-NLS-1$ private final String[] attachmentsColumns = { org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_Name, org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_Size, org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_Creator }; private final int[] attachmentsColumnWidths = { 150, 70, 100 }; private List<TaskAttribute> attachments; private boolean hasIncoming; private MenuManager menuManager; private Composite attachmentsComposite; private Table attachmentsTable; /** * Create gist editor attachment part */ public GistAttachmentPart() { setPartName(Messages.GistAttachmentPart_PartName); } /** * @see org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart#createControl(org.eclipse.swt.widgets.Composite, * org.eclipse.ui.forms.widgets.FormToolkit) */ public void createControl(Composite parent, final FormToolkit toolkit) { initialize(); final Section section = createSection(parent, toolkit, hasIncoming); section.setText(getPartName() + " (" + attachments.size() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ if (hasIncoming) expandSection(toolkit, section); else section.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent event) { if (attachmentsComposite == null) { expandSection(toolkit, section); getTaskEditorPage().reflow(); } } }); setSection(toolkit, section); } private void expandSection(FormToolkit toolkit, Section section) { attachmentsComposite = toolkit.createComposite(section); attachmentsComposite.setLayout(EditorUtil.createSectionClientLayout()); attachmentsComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); getTaskEditorPage().registerDefaultDropListener(section); if (attachments.size() > 0) createAttachmentTable(toolkit, attachmentsComposite); else { Label label = toolkit .createLabel( attachmentsComposite, org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_No_attachments); getTaskEditorPage().registerDefaultDropListener(label); } createButtons(attachmentsComposite, toolkit); toolkit.paintBordersFor(attachmentsComposite); section.setClient(attachmentsComposite); } /** * @see org.eclipse.ui.forms.AbstractFormPart#dispose() */ public void dispose() { if (menuManager != null) menuManager.dispose(); super.dispose(); } private void createAttachmentTable(FormToolkit toolkit, final Composite attachmentsComposite) { attachmentsTable = toolkit.createTable(attachmentsComposite, SWT.MULTI | SWT.FULL_SELECTION); attachmentsTable.setLinesVisible(true); attachmentsTable.setHeaderVisible(true); attachmentsTable.setLayout(new GridLayout()); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) .grab(true, false).hint(500, SWT.DEFAULT) .applyTo(attachmentsTable); attachmentsTable.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); for (int i = 0; i < attachmentsColumns.length; i++) { TableColumn column = new TableColumn(attachmentsTable, SWT.LEFT, i); column.setText(attachmentsColumns[i]); column.setWidth(attachmentsColumnWidths[i]); column.setMoveable(true); if (i == 0) { attachmentsTable.setSortColumn(column); attachmentsTable.setSortDirection(SWT.DOWN); } } // size column attachmentsTable.getColumn(1).setAlignment(SWT.RIGHT); TableViewer attachmentsViewer = new TableViewer(attachmentsTable); attachmentsViewer.setUseHashlookup(true); attachmentsViewer.setColumnProperties(attachmentsColumns); ColumnViewerToolTipSupport.enableFor(attachmentsViewer, ToolTip.NO_RECREATE); attachmentsViewer.setSorter(new GistAttachmentSorter()); List<ITaskAttachment> attachmentList = new ArrayList<ITaskAttachment>( attachments.size()); for (TaskAttribute attribute : attachments) { ITaskAttachment taskAttachment = new TaskAttachment(getModel() .getTaskRepository(), getModel().getTask(), attribute); getTaskData().getAttributeMapper().updateTaskAttachment( taskAttachment, attribute); attachmentList.add(taskAttachment); } attachmentsViewer.setContentProvider(new ArrayContentProvider()); attachmentsViewer.setLabelProvider(new AttachmentTableLabelProvider( getModel(), getTaskEditorPage().getAttributeEditorToolkit()) { public String getColumnText(Object element, int columnIndex) { if (columnIndex > 0) columnIndex++; return super.getColumnText(element, columnIndex); } public Image getColumnImage(Object element, int columnIndex) { if (columnIndex > 0) columnIndex++; return super.getColumnImage(element, columnIndex); } }); attachmentsViewer.addOpenListener(new IOpenListener() { public void open(OpenEvent event) { openAttachments(event); } }); attachmentsViewer.addSelectionChangedListener(getTaskEditorPage()); attachmentsViewer.setInput(attachmentList.toArray()); menuManager = new MenuManager(); menuManager.setRemoveAllWhenShown(true); menuManager.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { TasksUiMenus.fillTaskAttachmentMenu(manager); } }); getTaskEditorPage().getEditorSite().registerContextMenu(ID_POPUP_MENU, menuManager, attachmentsViewer, true); Menu menu = menuManager.createContextMenu(attachmentsTable); attachmentsTable.setMenu(menu); new TableViewerSupport(attachmentsViewer, getStateFile()); } private File getStateFile() { IPath stateLocation = Platform.getStateLocation(TasksUiPlugin .getDefault().getBundle()); return stateLocation.append("GistAttachmentPart.xml").toFile(); //$NON-NLS-1$ } private void createButtons(Composite attachmentsComposite, FormToolkit toolkit) { final Composite attachmentControlsComposite = toolkit .createComposite(attachmentsComposite); attachmentControlsComposite.setLayout(new GridLayout(2, false)); attachmentControlsComposite.setLayoutData(new GridData( GridData.BEGINNING)); Button attachFileButton = toolkit .createButton( attachmentControlsComposite, org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_Attach_, SWT.PUSH); attachFileButton.setImage(CommonImages .getImage(CommonImages.FILE_PLAIN)); attachFileButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { EditorUtil.openNewAttachmentWizard(getTaskEditorPage(), Mode.DEFAULT, null); } }); getTaskEditorPage().registerDefaultDropListener(attachFileButton); } private void initialize() { attachments = getTaskData().getAttributeMapper().getAttributesByType( getTaskData(), TaskAttribute.TYPE_ATTACHMENT); for (TaskAttribute attachmentAttribute : attachments) if (getModel().hasIncomingChanges(attachmentAttribute)) { hasIncoming = true; break; } } /** * @see org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart#fillToolBar(org.eclipse.jface.action.ToolBarManager) */ protected void fillToolBar(ToolBarManager toolBarManager) { Action attachFileAction = new Action() { @Override public void run() { EditorUtil.openNewAttachmentWizard(getTaskEditorPage(), Mode.DEFAULT, null); } }; attachFileAction .setToolTipText(org.eclipse.mylyn.internal.tasks.ui.editors.Messages.TaskEditorAttachmentPart_Attach_); attachFileAction.setImageDescriptor(CommonImages.FILE_PLAIN_SMALL); toolBarManager.add(attachFileAction); } protected void openAttachments(OpenEvent event) { List<ITaskAttachment> attachments = new ArrayList<ITaskAttachment>(); StructuredSelection selection = (StructuredSelection) event .getSelection(); List<?> items = selection.toList(); for (Object item : items) if (item instanceof ITaskAttachment) attachments.add((ITaskAttachment) item); if (attachments.isEmpty()) return; IWorkbenchPage page = getTaskEditorPage().getSite() .getWorkbenchWindow().getActivePage(); try { OpenTaskAttachmentHandler.openAttachments(page, attachments); } catch (OperationCanceledException e) { // canceled } } @Override public boolean setFormInput(Object input) { if (input instanceof String) { if (attachments != null) for (TaskAttribute attachmentAttribute : attachments) { if (input.equals(attachmentAttribute.getId())) { CommonFormUtil.setExpanded( (ExpandableComposite) getControl(), true); return selectReveal(attachmentAttribute); } } } return super.setFormInput(input); } public boolean selectReveal(TaskAttribute attachmentAttribute) { if (attachmentAttribute == null || attachmentsTable == null) return false; TableItem[] attachments = attachmentsTable.getItems(); int index = 0; for (TableItem attachment : attachments) { Object data = attachment.getData(); if (data instanceof ITaskAttachment) { ITaskAttachment attachmentData = ((ITaskAttachment) data); if (attachmentData.getTaskAttribute().getValue() .equals(attachmentAttribute.getValue())) { attachmentsTable.deselectAll(); attachmentsTable.select(index); IManagedForm mform = getManagedForm(); ScrolledForm form = mform.getForm(); EditorUtil.focusOn(form, attachmentsTable); return true; } } index++; } return false; } }