/* * Carrot2 project. * * Copyright (C) 2002-2016, Dawid Weiss, Stanisław Osiński. * All rights reserved. * * Refer to the full license file "carrot2.LICENSE" * in the root folder of the repository checkout or at: * http://www.carrot2.org/carrot2.LICENSE */ package org.carrot2.workbench.core.ui; import java.util.Collections; import org.carrot2.util.attribute.BindableDescriptor.GroupingMethod; import org.carrot2.workbench.core.WorkbenchActionFactory; import org.carrot2.workbench.core.WorkbenchCorePlugin; import org.carrot2.workbench.core.helpers.GUIFactory; import org.carrot2.workbench.core.helpers.SimpleXmlMemento; import org.carrot2.workbench.core.preferences.PreferenceConstants; import org.carrot2.workbench.core.ui.actions.GroupingMethodAction; import org.carrot2.workbench.core.ui.widgets.CScrolledComposite; import org.carrot2.workbench.editors.*; import org.eclipse.jface.action.*; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.*; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.forms.widgets.SharedScrolledComposite; import org.eclipse.ui.part.Page; /** * A single page internally bound to a concrete editor. */ final class AttributeViewPage extends Page { /** * Global preference key for expansion state. */ private static final String PREFERENCE_KEY_EXPANSION_STATE = AttributeViewPage.class.getName() + ".expansionState"; /** * The search editor this page is attached to. */ private final SearchEditor editor; /** * Attribute editors. */ private AttributeGroups attributeEditors; /** * Synchronization of attribute values from {@link SearchEditor}'s * {@link SearchInput} back to this view. */ private IAttributeListener editorToViewSync; /** * Synchronization of attribute values from this page to the {@link SearchEditor}. */ private AttributeListenerAdapter viewToEditorSync; /** * Main control in this page. */ private Composite mainControl; /* * */ public AttributeViewPage(SearchEditor editor) { this.editor = editor; } /** * Make contributions to menus, toolbars and status line. */ @Override public void makeContributions(IMenuManager menu, IToolBarManager toolBar, IStatusLineManager statusManager) { super.makeContributions(menu, toolBar, statusManager); createToolbarActions(toolBar); createMenuActions(menu); } /* * */ private void createMenuActions(IMenuManager menuManager) { final SearchInput input = editor.getSearchResult().getInput(); /* * Add defaults management. */ menuManager.add(new SetNewDefaultsAction(input)); menuManager.add(new ResetToDefaultsAction(input)); menuManager.add(new ResetToFactoryDefaultsAction(input)); } /* * */ private void createToolbarActions(IToolBarManager toolBarManager) { /* * Add a local auto-update action button. */ final IWorkbenchWindow window = getSite().getWorkbenchWindow(); toolBarManager.add(WorkbenchActionFactory.AUTO_UPDATE_ACTION.create(window)); /* * Add attribute grouping action. */ toolBarManager.add(new GroupingMethodAction( PreferenceConstants.GROUPING_ATTRIBUTE_VIEW)); /* * Save/ load attributes. */ final IAction saveLoadAction = new SaveAlgorithmAttributesAction( editor.getSearchResult().getInput()); toolBarManager.add(saveLoadAction); } /** * Update grouping state in toolbars/ menus, push initial values to editors. */ private void updateGroupingState(GroupingMethod grouping) { attributeEditors.setGrouping(grouping); attributeEditors.setAttributes( editor.getSearchResult().getInput() .getAttributeValueSet().getAttributeValues()); } /* * */ @Override public void createControl(Composite parent) { final IPreferenceStore prefStore = WorkbenchCorePlugin.getDefault().getPreferenceStore(); final String key = PreferenceConstants.GROUPING_ATTRIBUTE_VIEW; prefStore.addPropertyChangeListener(new PropertyChangeListenerAdapter(key) { protected void propertyChangeFiltered(PropertyChangeEvent event) { updateGroupingState(GroupingMethod.valueOf(prefStore.getString(key))); } }); final SharedScrolledComposite scroller = new CScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL); final Composite spacer = GUIFactory.createSpacer(scroller); scroller.setContent(spacer); scroller.setExpandHorizontal(true); scroller.setExpandVertical(false); final GroupingMethod defaultGrouping = GroupingMethod.valueOf(prefStore .getString(key)); attributeEditors = new AttributeGroups(spacer, editor.getAlgorithmDescriptor(), defaultGrouping, null, Collections.<String, Object> emptyMap()); attributeEditors.setLayoutData(GridDataFactory.fillDefaults().grab(true, true) .create()); attributeEditors.setAttribute(AttributeList.ENABLE_VALIDATION_OVERLAYS, true); restoreGlobalState(); this.mainControl = scroller; scroller.reflow(true); updateGroupingState(defaultGrouping); registerListeners(); } /** * Save to global state. */ void saveGlobalState() { assert Display.getCurrent() != null; final AttributeViewMemento memento = new AttributeViewMemento(); memento.sectionsExpansionState = attributeEditors.getExpansionStates(); SimpleXmlMemento.toPreferenceStore(PREFERENCE_KEY_EXPANSION_STATE, memento); } /** * Restore from global state. */ void restoreGlobalState() { assert Display.getCurrent() != null; final AttributeViewMemento memento = SimpleXmlMemento.fromPreferenceStore( AttributeViewMemento.class, PREFERENCE_KEY_EXPANSION_STATE); if (memento != null) { attributeEditors.setExpanded(memento.sectionsExpansionState); } } /* * */ @Override public Control getControl() { return this.mainControl; } /* * */ @Override public void setFocus() { attributeEditors.setFocus(); } /* * */ @Override public void dispose() { unregisterListeners(); attributeEditors.dispose(); super.dispose(); } /* * */ private void registerListeners() { /* * Link attribute value changes: attribute view -> search result */ viewToEditorSync = new AttributeListenerAdapter() { public void valueChanged(AttributeEvent event) { editor.getSearchResult().getInput().setAttribute(event.key, event.value); } }; this.attributeEditors.addAttributeListener(viewToEditorSync); /* * Link attribute value changes: search result -> attribute view */ editorToViewSync = new AttributeListenerAdapter() { public void valueChanged(AttributeEvent event) { /* * temporarily unsubscribe from events from the attributes list to avoid * event looping. */ attributeEditors.removeAttributeListener(viewToEditorSync); attributeEditors.setAttribute(event.key, event.value); attributeEditors.addAttributeListener(viewToEditorSync); } }; editor.getSearchResult().getInput().addAttributeListener(editorToViewSync); } /* * */ private void unregisterListeners() { editor.getSearchResult().getInput().removeAttributeListener(editorToViewSync); attributeEditors.removeAttributeListener(viewToEditorSync); } }