diff options
Diffstat (limited to 'org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/provisional/tasks/ui/wizards/RepositoryQuerySchemaPage.java')
-rw-r--r-- | org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/provisional/tasks/ui/wizards/RepositoryQuerySchemaPage.java | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/provisional/tasks/ui/wizards/RepositoryQuerySchemaPage.java b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/provisional/tasks/ui/wizards/RepositoryQuerySchemaPage.java new file mode 100644 index 000000000..103ba627e --- /dev/null +++ b/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/provisional/tasks/ui/wizards/RepositoryQuerySchemaPage.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2015 Tasktop Technologies and others. + * 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: + * Tasktop Technologies - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.provisional.tasks.ui.wizards; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.mylyn.commons.workbench.forms.SectionComposite; +import org.eclipse.mylyn.internal.provisional.tasks.ui.wizards.AbstractQueryPageSchema.Field; +import org.eclipse.mylyn.internal.tasks.core.TaskTask; +import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskDiffUtil; +import org.eclipse.mylyn.tasks.core.IRepositoryQuery; +import org.eclipse.mylyn.tasks.core.ITask; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.eclipse.mylyn.tasks.core.data.ITaskDataWorkingCopy; +import org.eclipse.mylyn.tasks.core.data.TaskAttribute; +import org.eclipse.mylyn.tasks.core.data.TaskData; +import org.eclipse.mylyn.tasks.core.data.TaskDataModel; +import org.eclipse.mylyn.tasks.core.data.TaskDataModelEvent; +import org.eclipse.mylyn.tasks.core.data.TaskDataModelListener; +import org.eclipse.mylyn.tasks.ui.TasksUi; +import org.eclipse.mylyn.tasks.ui.editors.AbstractAttributeEditor; +import org.eclipse.mylyn.tasks.ui.editors.AttributeEditorFactory; +import org.eclipse.mylyn.tasks.ui.editors.LayoutHint; +import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.ColumnSpan; +import org.eclipse.mylyn.tasks.ui.editors.LayoutHint.RowSpan; +import org.eclipse.mylyn.tasks.ui.wizards.AbstractRepositoryQueryPage2; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.forms.widgets.FormToolkit; + +public class RepositoryQuerySchemaPage extends AbstractRepositoryQueryPage2 { + private static final String QUERYPAGE_FILTER_ID = "org.eclipse.mylyn.tasks.ui.wizards.QueryPageFilter"; + + private static final int LABEL_WIDTH = 110; + + private static final int COLUMN_WIDTH = 140; + + private static final int COLUMN_GAP = 20; + + private static final int MULTI_COLUMN_WIDTH = COLUMN_WIDTH + 5 + COLUMN_GAP + LABEL_WIDTH + 5 + COLUMN_WIDTH; + + private static final int MULTI_ROW_HEIGHT = 55; + + protected final AbstractQueryPageSchema schema; + + private final TaskData data; + + private final Pattern URL_PATTERN; + + private QueryPageSearch search; + + private final QueryPageDetails pageDetails; + + private AttributeEditorFactory factory; + + private SectionComposite scrolledComposite; + + protected TaskData targetTaskData; + + protected final Map<String, AbstractAttributeEditor> editorMap = new HashMap<String, AbstractAttributeEditor>(); + + public RepositoryQuerySchemaPage(String pageName, TaskRepository repository, IRepositoryQuery query, + AbstractQueryPageSchema schema, TaskData data, QueryPageDetails pageDetails) { + super(pageName, repository, query); + this.schema = schema; + this.data = data; + this.pageDetails = pageDetails; + setTitle(pageDetails.getPageTitle()); + setDescription(pageDetails.getPageDescription()); + URL_PATTERN = Pattern.compile(pageDetails.getUrlPattern()); + if (query != null) { + search = new QueryPageSearch(query.getUrl()); + } else { + search = new QueryPageSearch(); + } + } + + @Override + protected void createPageContent(@NonNull SectionComposite parent) { + this.scrolledComposite = parent; + + Composite scrolledBodyComposite = scrolledComposite.getContent(); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 10; + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + scrolledBodyComposite.setLayout(layout); + + Composite attributesComposite = new Composite(scrolledBodyComposite, SWT.NONE); + GridDataFactory.fillDefaults() + .align(SWT.FILL, SWT.FILL) + .grab(true, true) + .span(2, 1) + .applyTo(attributesComposite); + layout = new GridLayout(6, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + attributesComposite.setLayout(layout); + GridData g = new GridData(GridData.FILL, GridData.FILL, true, true); + g.widthHint = 400; + attributesComposite.setLayoutData(g); + attributesComposite.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND)); + FormToolkit toolkit = new FormToolkit(parent.getDisplay()); + + TaskRepository repository = getTaskRepository(); + ITask nTask = new TaskTask(repository.getConnectorKind(), repository.getRepositoryUrl(), data.getTaskId()); + ITaskDataWorkingCopy workingCopy = TasksUi.getTaskDataManager().createWorkingCopy(nTask, data); + + final TaskDataModel model = new TaskDataModel(repository, nTask, workingCopy); + factory = new AttributeEditorFactory(model, repository); + model.addModelListener(new TaskDataModelListener() { + + @Override + public void attributeChanged(TaskDataModelEvent event) { + getContainer().updateButtons(); + } + }); + targetTaskData = workingCopy.getLocalData(); + final TaskAttribute target = targetTaskData.getRoot(); + createFieldControls(attributesComposite, toolkit, layout.numColumns, target); + Point p = scrolledBodyComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + scrolledComposite.setMinSize(p); + + } + + private void createFieldControls(Composite attributesComposite, FormToolkit toolkit, int columnCount, + TaskAttribute target) { + int currentColumn = 1; + int currentPriority = 0; + int currentLayoutPriority = 0; + for (Field field : schema.getFields()) { + TaskAttribute dataAttribute = target.getAttribute(field.getKey()); + AbstractAttributeEditor attributeEditor = factory.createEditor(field.getType(), dataAttribute); + editorMap.put(dataAttribute.getId(), attributeEditor); + + String layoutPriorityString = dataAttribute.getMetaData().getValue("LayoutPriority"); + int layoutPriority = layoutPriorityString == null ? -1 : Integer.parseInt(layoutPriorityString); + int priority = (attributeEditor.getLayoutHint() != null) + ? attributeEditor.getLayoutHint().getPriority() + : LayoutHint.DEFAULT_PRIORITY; + // TODO: copied from AbstractTaskEditorAttributeSection.createAttributeControls (only layoutPriority is new) + if (priority != currentPriority || currentLayoutPriority != layoutPriority) { + currentPriority = priority; + currentLayoutPriority = layoutPriority; + if (currentColumn > 1) { + while (currentColumn <= columnCount) { + Label l = toolkit.createLabel(attributesComposite, ""); //$NON-NLS-1$ + + GridData gd = GridDataFactory.fillDefaults() + .align(SWT.LEFT, SWT.CENTER) + .hint(0, SWT.DEFAULT) + .create(); + l.setLayoutData(gd); + + currentColumn++; + } + currentColumn = 1; + } + } + + if (attributeEditor.hasLabel()) { + attributeEditor.createLabelControl(attributesComposite, toolkit); + Label label = attributeEditor.getLabelControl(); + label.setBackground(attributesComposite.getBackground()); + label.setForeground(attributesComposite.getForeground()); + String text = label.getText(); + String shortenText = TaskDiffUtil.shortenText(label, text, LABEL_WIDTH); + label.setText(shortenText); + if (!text.equals(shortenText)) { + label.setToolTipText(text); + } + GridData gd = GridDataFactory.fillDefaults() + .align(SWT.RIGHT, SWT.CENTER) + .grab(true, true) + .hint(LABEL_WIDTH, SWT.DEFAULT) + .create(); + if (currentColumn > 1) { + gd.horizontalIndent = COLUMN_GAP; + gd.widthHint = LABEL_WIDTH + COLUMN_GAP; + } + label.setLayoutData(gd); + currentColumn++; + } + attributeEditor.createControl(attributesComposite, toolkit); + attributeEditor.getControl().setBackground( + attributesComposite.getParent().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); + attributeEditor.getControl().setForeground(attributesComposite.getForeground()); + LayoutHint layoutHint = attributeEditor.getLayoutHint(); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + RowSpan rowSpan = (layoutHint != null && layoutHint.rowSpan != null) ? layoutHint.rowSpan : RowSpan.SINGLE; + ColumnSpan columnSpan = (layoutHint != null && layoutHint.columnSpan != null) + ? layoutHint.columnSpan + : ColumnSpan.SINGLE; + gd.horizontalIndent = 1;// prevent clipping of decorators on Windows + if (rowSpan == RowSpan.SINGLE && columnSpan == ColumnSpan.SINGLE) { + gd.widthHint = COLUMN_WIDTH; + gd.horizontalSpan = 1; + } else { + if (rowSpan == RowSpan.MULTIPLE) { + gd.heightHint = MULTI_ROW_HEIGHT; + } + if (columnSpan == ColumnSpan.SINGLE) { + gd.widthHint = COLUMN_WIDTH; + gd.horizontalSpan = 1; + } else { + gd.widthHint = MULTI_COLUMN_WIDTH; + gd.horizontalSpan = columnCount - currentColumn + 1; + } + } + attributeEditor.getControl().setLayoutData(gd); + + currentColumn += gd.horizontalSpan; + currentColumn %= columnCount; + } + } + + @Override + public boolean isPageComplete() { + setMessage(pageDetails.getPageDescription()); + boolean result = super.isPageComplete(); + if (!result) { + return result; + } + setErrorMessage(null); + setMessage(""); + boolean oneFieldHasValue = false; + for (Field field : schema.getFields()) { + oneFieldHasValue |= (targetTaskData.getRoot().getAttribute(field.getKey()).hasValue() + && !targetTaskData.getRoot().getAttribute(field.getKey()).getValue().equals("")); + if (field.isQueryRequired()) { + String text = targetTaskData.getRoot().getAttribute(field.getKey()).getValue(); + if (text == null || text.length() == 0) { + setMessage("Enter a value for " + field.getLabel()); + return false; + } + } + if (field.getType().equals("url")) { + String text = targetTaskData.getRoot().getAttribute(field.getKey()).getValue(); + if (text != null && text.length() > 0) { + Matcher m = URL_PATTERN.matcher(text); + if (m.find()) { + setErrorMessage(null); + return true; + } else { + setErrorMessage("Please specify a valid URL in " + field.getLabel()); + return false; + } + } + } + } + if (!oneFieldHasValue) { + setErrorMessage("Please fill at least on field!"); + } + return true; + } + + protected String getQueryUrl(String repsitoryUrl) { + StringBuilder sb = new StringBuilder(); + sb.append(repsitoryUrl); + sb.append("/"); + sb.append(pageDetails.getQueryUrlPart()); + sb.append(search.toQuery()); + return sb.toString(); + + } + + @Override + public void applyTo(IRepositoryQuery query) { + query.setSummary(this.getQueryTitle()); + query.setUrl(getQueryUrl(getTaskRepository().getRepositoryUrl())); + if (pageDetails.getQueryAttributeName() != null) { + query.setAttribute(pageDetails.getQueryAttributeName(), Boolean.TRUE.toString()); + } + } + + //FIXME: REST überarbeiten + @Override + protected void doRefreshControls() { + // ignore + + } + + //FIXME: REST überarbeiten + @Override + protected boolean hasRepositoryConfiguration() { + // ignore + return true; + } + + //FIXME: REST überarbeiten + @Override + protected boolean restoreState(@NonNull IRepositoryQuery query) { + // ignore + return false; + } +} |