/** * This file is part of Archiv-Editor. * * The software Archiv-Editor serves as a client user interface for working with * the Person Data Repository. See: pdr.bbaw.de * * The software Archiv-Editor was developed at the Berlin-Brandenburg Academy * of Sciences and Humanities, Jägerstr. 22/23, D-10117 Berlin. * www.bbaw.de * * Copyright (C) 2010-2013 Berlin-Brandenburg Academy * of Sciences and Humanities * * The software Archiv-Editor was developed by @author: Christoph Plutte. * * Archiv-Editor is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Archiv-Editor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Archiv-Editor. * If not, see <http://www.gnu.org/licenses/lgpl-3.0.html>. */ package org.bbaw.pdr.ae.export.swt; import java.util.HashMap; import java.util.Vector; import org.bbaw.pdr.ae.common.CommonActivator; import org.bbaw.pdr.ae.common.NLMessages; import org.bbaw.pdr.ae.common.icons.IconsInternal; import org.bbaw.pdr.ae.common.interfaces.AEFilter; import org.bbaw.pdr.ae.export.pluggable.AeExportCoreProvider; import org.bbaw.pdr.ae.export.pluggable.AeExportUtilities; import org.bbaw.pdr.ae.export.swt.preview.PdrSelectionFilterPreview; import org.bbaw.pdr.ae.model.Aspect; import org.bbaw.pdr.ae.model.PdrObject; import org.bbaw.pdr.ae.model.Person; import org.bbaw.pdr.ae.model.Reference; import org.bbaw.pdr.ae.model.view.OrderingHead; import org.bbaw.pdr.ae.view.control.PDRObjectsProvider; import org.bbaw.pdr.ae.view.control.PDROrdererFactory; import org.bbaw.pdr.ae.view.control.filters.AspectExcludeObjectRelationsFilter; import org.bbaw.pdr.ae.view.control.filters.AspectSearchTextFilter; import org.bbaw.pdr.ae.view.control.filters.OnlyAspectDivergentMarkup; import org.bbaw.pdr.ae.view.control.filters.OnlyAspectsAboutReferenceFilter; import org.bbaw.pdr.ae.view.control.filters.OnlyAspectsBasedOnReferenceFilter; import org.bbaw.pdr.ae.view.control.filters.OnlyNewPDRObjectsFilter; import org.bbaw.pdr.ae.view.control.filters.OnlyUpdatedPDRObjectsFilter; import org.bbaw.pdr.ae.view.main.dialogs.FilterSelectionDialog; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.wizard.WizardPage; 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.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; /** * Widget arrangement for displaying and modifying a selection of PDR objects in a Wizard. * * Used by export wizards to let users preview and change their selection of PDR objects * they want to export. Selected {@link Person}s, their {@link Aspect}s and the {@link Reference}s of * those are shown in hierarchical order by a {@link PdrSelectionFilterPreview}, additional * controls for grouping and filtering are made possible with a row of buttons below. * * @author jakobh * */ public class PdrObjectsPreview extends Composite implements IPdrWidgetStructure { private final static String SETTINGS_SECTION = "pdrObjectsPreview"; private final static String SETTINGS_ORDERER = "aspectOrdererId"; private PdrSelectionFilterPreview preview; private WizardPage wizardPage; private int currentOrdererSelection; private Text searchQueryText; private PDRObjectsProvider _pdrObjectsProvider = AeExportCoreProvider.getInstance().getPdrObjectsProvider(); private String pluginId; private static HashMap<String, String> filterActionsImgIds = new HashMap<String, String>(); static { filterActionsImgIds.put("View_action_only_newAspects",IconsInternal.DECORATION_NEW); filterActionsImgIds.put("View_action_only_updated_aspects",IconsInternal.DECORATION_UPDATED); filterActionsImgIds.put("View_action_exclude_other_relations",IconsInternal.RELATION); filterActionsImgIds.put("View_action_only_divergent_markup",IconsInternal.MARKUP_QUESTION); filterActionsImgIds.put("View_action_only_based_on_reference",IconsInternal.REFERENCE); filterActionsImgIds.put("View_action_only_mentioning_reference",IconsInternal.REFERENCE_ASPECTS); filterActionsImgIds.put("View_action_reference_filter",IconsInternal.REFERENCES); filterActionsImgIds.put("View_action_person_filter",IconsInternal.PERSONS); filterActionsImgIds.put("View_action_semantic_filter",IconsInternal.CLASSIFICATIONS); filterActionsImgIds.put("View_action_time_filter",IconsInternal.TIME); filterActionsImgIds.put("View_action_user_filter",IconsInternal.USER); }; private static HashMap<String, AEFilter> filterActionFilters = new HashMap<String, AEFilter>(); static { filterActionFilters.put("View_action_only_newAspects",new OnlyNewPDRObjectsFilter()); filterActionFilters.put("View_action_only_updated_aspects",new OnlyUpdatedPDRObjectsFilter()); filterActionFilters.put("View_action_exclude_other_relations",new AspectExcludeObjectRelationsFilter(null)); filterActionFilters.put("View_action_only_divergent_markup",new OnlyAspectDivergentMarkup()); filterActionFilters.put("View_action_only_based_on_reference",new OnlyAspectsBasedOnReferenceFilter(null)); filterActionFilters.put("View_action_only_mentioning_reference",new OnlyAspectsAboutReferenceFilter(null)); }; private static HashMap<String, String> filterActionDialogIds = new HashMap<String, String>(); static { filterActionDialogIds.put("View_action_reference_filter","reference"); filterActionDialogIds.put("View_action_person_filter","person"); filterActionDialogIds.put("View_action_semantic_filter","semantic"); filterActionDialogIds.put("View_action_time_filter","year"); filterActionDialogIds.put("View_action_user_filter","user"); }; PdrObjectsPreview(Composite parent, int style) { super(parent, style); } /** * Creates a new {@link PdrObjectsPreview} instance operating on a given {@link WizardPage}. * @param pluginId identifier of the plugin using the wizard. Used for restoring dialog settings * with {@link IDialogSettings}. Can be retrieved with <code>FrameworkUtil.getBundle(getClass()).getSymbolicName();</code> * or via the plugin's {@link AeExportUtilities} provider. * @param page the {@link WizardPage} this widget is to work with. Required for disabling wizard controls on invalid input * @param parent parent {@link Composite} for this widget. */ public PdrObjectsPreview(String pluginId, WizardPage page, Composite parent) { super(parent, SWT.BORDER | SWT.SHADOW_ETCHED_IN); this.wizardPage=page; //setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); this.pluginId = pluginId; currentOrdererSelection = -1; // restore latest ordering mode IDialogSettings settings = AeExportCoreProvider.getInstance().getSettings(pluginId); if (settings.getSection(SETTINGS_SECTION) != null) { String ordererId = settings.getSection(SETTINGS_SECTION).get(SETTINGS_ORDERER); if (ordererId != null) { int i = 0; while (currentOrdererSelection < 0 && i < PDROrdererFactory.ORDERER_IDs.length) { if (PDROrdererFactory.ORDERER_IDs[i].equals(ordererId)) currentOrdererSelection = i; i++; } } } if (currentOrdererSelection<0) currentOrdererSelection=1; // semantic //container = new Composite(parent, SWT.BORDER); // set top level layout for this widget and make it fit its parent composite int columns = 7; setLayout(new GridLayout(columns, true)); setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, ((GridLayout)parent.getLayout()).numColumns, 1)); Composite previewContainer = new Composite(this, SWT.BORDER); GridData grid = new GridData(SWT.FILL, SWT.FILL, true, true, columns, 1); previewContainer.setLayoutData(grid); previewContainer.setLayout(new GridLayout(1,false)); preview = new PdrSelectionFilterPreview(wizardPage, previewContainer); // FIXME: hier nicht neue erzeugen, // sondern eine zentral vorhandene verwenden! // build controls composite for preview regrouping Composite ctlGrouping = new Composite(this, SWT.BORDER); grid = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); ctlGrouping.setLayoutData(grid); ctlGrouping.setLayout(new GridLayout(3,false)); Label groupingLbl = new Label(ctlGrouping, SWT.NONE); groupingLbl.setText(NLMessages.getString("View_group_by")); groupingLbl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); final Combo groupingCombo = new Combo(ctlGrouping, SWT.NONE | SWT.READ_ONLY); groupingCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); groupingCombo.setItems(new String[] {NLMessages.getString("View_group_all"), NLMessages.getString("View_group_semantic"), NLMessages.getString("View_group_year"), NLMessages.getString("View_group_place"), NLMessages.getString("View_group_reference"), NLMessages.getString("View_group_relation"), NLMessages.getString("View_group_markup"), NLMessages.getString("View_group_user")}); // classification combo listener groupingCombo.addSelectionListener(new SelectionAdapter(){ private int selection = -1; @Override public void widgetSelected(SelectionEvent arg0) { int item = groupingCombo.getSelectionIndex(); if (item != selection) { if (item>0) { AeExportCoreProvider.getInstance().getPdrObjectsProvider().setOrderer( PDROrdererFactory.createAspectOrderer(PDROrdererFactory.ORDERER_IDs[item])); System.out.println(" Orderer id: "+PDROrdererFactory.ORDERER_IDs[item]); } else AeExportCoreProvider.getInstance().getPdrObjectsProvider().setOrderer(null); currentOrdererSelection=item; selection = currentOrdererSelection; preview.updateColumnLabel(NLMessages.getString("View_group_by")+groupingCombo.getText()); preview.update(); } } @Override public void widgetDefaultSelected(SelectionEvent arg0) { widgetSelected(arg0); //TODO: sinnvoll? } }); groupingCombo.select(currentOrdererSelection); // loest kein event aus System.out.println(" PDR Objects Preview Orderer: "+currentOrdererSelection+"; "+ PDROrdererFactory.ORDERER_IDs[currentOrdererSelection]); AeExportCoreProvider.getInstance().getPdrObjectsProvider().setOrderer( PDROrdererFactory.createAspectOrderer(PDROrdererFactory.ORDERER_IDs[currentOrdererSelection])); preview.updateColumnLabel(NLMessages.getString("View_group_by")+groupingCombo.getText()); preview.update(); // geht vermutlich auch schöner. FIXME: wirft unten im objectsprovider auch nen // nullpointer! ImageRegistry imgReg = CommonActivator.getDefault().getImageRegistry(); // build controls composite for preview filtering Composite ctlFilters = new Composite(this, SWT.BORDER); ctlFilters.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 5, 1)); ctlFilters.setLayout(new GridLayout(9, false)); Label filterLabel = new Label(ctlFilters, SWT.NONE); filterLabel.setImage(imgReg.get(IconsInternal.FILTER)); filterLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); // FIXME: bei window resize wird die toolbar mit den filtern total klein und // die combo für gruppenauswahl total groß ToolBar filterBar = new ToolBar(ctlFilters, SWT.NONE); filterBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 3, 1)); filterBar.setLayout(new GridLayout(filterActionsImgIds.size(), false)); ToolBarManager filterBarMng = new ToolBarManager(filterBar); for (final String actionId : filterActionsImgIds.keySet()) { String imgId = filterActionsImgIds.get(actionId); //System.out.println(actionId+" "+imgId); Action action = filterActionFilters.containsKey(actionId) ? new Action(NLMessages.getString(actionId)){ AEFilter filter = filterActionFilters.get(actionId); @Override public void run() { if (isChecked()){ _pdrObjectsProvider.addFilter(filter); } else _pdrObjectsProvider.removeFilter(filter); preview.update(); }; } : new Action(NLMessages.getString(actionId)){ String type = filterActionDialogIds.get(actionId); boolean isActive() { return type.equals("person") ? _pdrObjectsProvider.hasPersonFilter() : (type.equals("reference") ? _pdrObjectsProvider.hasReferenceFilter() : (type.equals("semantic") ? _pdrObjectsProvider.hasSemanticFilter() : (type.equals("user") ? _pdrObjectsProvider.hasUserFilter() : _pdrObjectsProvider.hasYearFilter()))); } @Override public void run() { FilterSelectionDialog dialog = createDialog(type); if (!isActive()) { if (dialog.open() == 0) preview.update(); } else { AEFilter af = _pdrObjectsProvider.getFilter(type); _pdrObjectsProvider.removeFilter(af); } boolean state = isActive(); setChecked(state); } }; action.setEnabled(true); //TODO: objectsprovider is being saved isn't it? action.setChecked(false); action.setImageDescriptor(imgReg.getDescriptor(imgId)); filterBarMng.add(action); } filterBarMng.update(true); Label searchQueryLabel = new Label(ctlFilters, SWT.NONE); searchQueryLabel.setText(NLMessages.getString("View_search_notification")); searchQueryLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); searchQueryText = new Text(ctlFilters, SWT.SINGLE | SWT.BORDER); searchQueryText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); Button searchQueryButton = new Button(ctlFilters, SWT.PUSH); searchQueryButton.setToolTipText(NLMessages.getString("View_search_notification")); searchQueryButton.setImage(imgReg.get(IconsInternal.SEARCH)); searchQueryButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); searchQueryButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { String search = searchQueryText.getText(); AspectSearchTextFilter filter = _pdrObjectsProvider.getSearchFilter(); if (search.trim().length() > 0) { if (filter != null) { filter.setSearchText(search); } else { filter = new AspectSearchTextFilter(search); _pdrObjectsProvider.addFilter(filter); preview.update(); } } else { if (filter != null) { _pdrObjectsProvider.removeFilter(filter); preview.update(); } } }}); } /** * Returns true if the underlying {@link PdrSelectionFilterPreview} of this * widget contains a valid selection of {@link PdrObject}s ready for export. */ public boolean isValid() { return preview.isValid(); } /** * Returns the status message which is currently set by the * underlying {@link PdrSelectionFilterPreview}. */ public String getMessage() { return preview.getMessage(); } /** * Returns all {@link PdrObject}s that are currently selected * in this preview. * @return */ public PdrObject[] getSelectedObjects() { return preview.getSelectedObjects(); } /** * From the current preview tree forest, extract those trees that contain nodes * marked for export. * @return */ public Vector<OrderingHead> getSelectionHeads() { //TODO doc return AeExportCoreProvider.getInstance().getPdrObjectsTree().getSelectionHeads(); } /** * Used to set up a dialog for filtering {@link Aspect}s for certain * criteria. Dialog is instantiated and returned as by {@link FilterSelectionDialog}, * but not actually openened. * @param type One of <code>reference, person, semantic, year, user</code>. * @return {@link FilterSelectionDialog} */ private FilterSelectionDialog createDialog(String type) { IWorkbench workbench = PlatformUI.getWorkbench(); Display display = workbench.getDisplay(); Shell shell = new Shell(display); FilterSelectionDialog dialog = new FilterSelectionDialog(shell, _pdrObjectsProvider, type); return dialog; } @Override public void performFinish() { IDialogSettings settings = AeExportCoreProvider.getInstance(). getSettingsSection(pluginId, SETTINGS_SECTION); settings.put(SETTINGS_ORDERER, PDROrdererFactory.ORDERER_IDs[currentOrdererSelection]); } }