From 6bfda2284f0a992a74dcc0589ae1d9154476052a Mon Sep 17 00:00:00 2001 From: Phillipus Date: Mon, 9 Dec 2024 11:58:23 +0000 Subject: [PATCH] Use a dialog to select User Properties for the Search Filter --- .../views/tree/search/SearchFilter.java | 4 + .../views/tree/search/SearchWidget.java | 108 +++++----- .../UserPropertiesKeySelectionDialog.java | 192 ++++++++++++++++++ .../views/tree/search/messages.properties | 2 +- 4 files changed, 243 insertions(+), 63 deletions(-) create mode 100644 com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/UserPropertiesKeySelectionDialog.java diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java index a76b70c02..2834438fa 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchFilter.java @@ -234,6 +234,10 @@ void removePropertiesFilter(String key) { fPropertiesFilter.remove(key); } + Set getPropertiesFilter() { + return fPropertiesFilter; + } + void resetPropertiesFilter() { fPropertiesFilter.clear(); } diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java index 95ec5e6a1..130f65caf 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/SearchWidget.java @@ -29,6 +29,7 @@ import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -75,7 +76,6 @@ public class SearchWidget extends Composite { private List fConceptActions = new ArrayList<>(); - private MenuManager fPropertiesMenu; private MenuManager fSpecializationsMenu; private Timer fKeyDelayTimer; @@ -233,9 +233,21 @@ public void run() { dropDownAction.add(fActionFilterDocumentation); // Properties - fPropertiesMenu = new MenuManager(Messages.SearchWidget_5); - dropDownAction.add(fPropertiesMenu); - populatePropertiesMenu(); + IAction actionProperties = new Action(Messages.SearchWidget_5, IAction.AS_PUSH_BUTTON) { + @Override + public void run() { + UserPropertiesKeySelectionDialog dialog = new UserPropertiesKeySelectionDialog(getShell(), getAllUniquePropertyKeys(), + new ArrayList<>(fSearchFilter.getPropertiesFilter())); + if(dialog.open() != Window.CANCEL) { + fSearchFilter.resetPropertiesFilter(); + for(String key : dialog.getSelectedKeys()) { + fSearchFilter.addPropertiesFilter(key); + } + refreshTree(); + } + } + }; + dropDownAction.add(actionProperties); dropDownAction.add(new Separator()); @@ -315,26 +327,26 @@ public void run() { dropDownAction.add(new Separator()); // Show All Folders - IAction action = new Action(Messages.SearchWidget_12, IAction.AS_CHECK_BOX) { + IAction actionFolders = new Action(Messages.SearchWidget_12, IAction.AS_CHECK_BOX) { @Override public void run() { fSearchFilter.setShowAllFolders(isChecked()); refreshTree(); } }; - action.setChecked(fSearchFilter.isShowAllFolders()); - dropDownAction.add(action); + actionFolders.setChecked(fSearchFilter.isShowAllFolders()); + dropDownAction.add(actionFolders); dropDownAction.add(new Separator()); // Reset - action = new Action(Messages.SearchWidget_13) { + IAction actionReset = new Action(Messages.SearchWidget_13) { @Override public void run() { reset(); } }; - dropDownAction.add(action); + dropDownAction.add(actionReset); // Need to update toolbar manager now toolBarmanager.update(true); @@ -350,9 +362,6 @@ private void reset() { // Don't filter on Documentation menu item fActionFilterDocumentation.setChecked(false); - // Clear & uncheck Properties menu items - populatePropertiesMenu(); - // Clear & uncheck Specializations menu items populateSpecializationsMenu(); @@ -376,7 +385,6 @@ private void reset() { */ public void softReset() { // Clear & Reset Properties - populatePropertiesMenu(); fSearchFilter.resetPropertiesFilter(); // Clear & Reset Specializations @@ -414,56 +422,33 @@ public ImageDescriptor getImageDescriptor() { return action; } - private void populatePropertiesMenu() { - fPropertiesMenu.removeAll(); - - // Models that are loaded are the ones in the Models Tree - Set set = new LinkedHashSet<>(); // LinkedHashSet is faster when sorting - - for(IArchimateModel model : IEditorModelManager.INSTANCE.getModels()) { - getAllUniquePropertyKeysForModel(model, set); - } - - List list = new ArrayList<>(set); - - // Sort alphabetically, but don't use Collator.getInstance() as it's too slow - list.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); - - // Limit to a sensible menu size - if(list.size() > 1000) { - list = list.subList(0, 999); - } - - for(String key : list) { - IAction action = new Action(key, IAction.AS_CHECK_BOX) { - @Override - public void run() { - if(isChecked()) { - fSearchFilter.addPropertiesFilter(key); - } - else { - fSearchFilter.removePropertiesFilter(key); - } - refreshTree(); - } - }; - - fPropertiesMenu.add(action); - } - - fPropertiesMenu.update(true); - } - - private void getAllUniquePropertyKeysForModel(IArchimateModel model, Set set) { - for(Iterator iter = model.eAllContents(); iter.hasNext();) { - EObject element = iter.next(); - if(element instanceof IProperty property) { - String key = property.getKey(); - if(StringUtils.isSetAfterTrim(key)) { - set.add(key); - } + private List getAllUniquePropertyKeys() { + // Maximum amount of items to display when getting all unique keys + final int MAX_ITEMS = 10000; + + Set set = new LinkedHashSet<>(); // LinkedHashSet is faster when sorting + + for(IArchimateModel model : IEditorModelManager.INSTANCE.getModels()) { + for(Iterator iter = model.eAllContents(); iter.hasNext();) { + EObject element = iter.next(); + if(element instanceof IProperty property) { + String key = property.getKey(); + if(StringUtils.isSetAfterTrim(key)) { + set.add(key); + if(set.size() > MAX_ITEMS) { // Don't get more than this + break; + } + } + } } } + + List list = new ArrayList<>(set); + + // Sort alphabetically, but don't use Collator.getInstance() as it's too slow + list.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); + + return list; } private void populateSpecializationsMenu() { @@ -586,7 +571,6 @@ public void dispose() { fViewer = null; fSearchFilter = null; fConceptActions = null; - fPropertiesMenu = null; fSpecializationsMenu = null; } } diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/UserPropertiesKeySelectionDialog.java b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/UserPropertiesKeySelectionDialog.java new file mode 100644 index 000000000..c057bc10a --- /dev/null +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/UserPropertiesKeySelectionDialog.java @@ -0,0 +1,192 @@ +package com.archimatetool.editor.views.tree.search; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +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.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; + +import com.archimatetool.editor.ui.IArchiImages; +import com.archimatetool.editor.ui.components.ExtendedTitleAreaDialog; + + + +/** + * User Properties Key Selection Dialog + * + * @author Phillip Beauvoir + */ +public class UserPropertiesKeySelectionDialog extends ExtendedTitleAreaDialog { + + private static String HELP_ID = "com.archimatetool.help.userProperties"; //$NON-NLS-1$ + + private CheckboxTableViewer tableViewer; + private Button buttonSelectAll, buttonDeselectAll; + + private List keys; + private List selectedKeys; + + /** + * @param parentShell + * @param keys The list of property keys + * @param selected A list of property keys to select. Can be null. + */ + public UserPropertiesKeySelectionDialog(Shell parentShell, List keys, List selected) { + super(parentShell, "UserPropertiesSelectionDialog"); //$NON-NLS-1$ + setTitleImage(IArchiImages.ImageFactory.getImage(IArchiImages.ECLIPSE_IMAGE_IMPORT_PREF_WIZARD)); + setShellStyle(getShellStyle() | SWT.RESIZE); + + this.keys = keys; + selectedKeys = selected; + } + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText("Select Properties"); + } + + @Override + protected Control createButtonBar(Composite parent) { + Control c = super.createButtonBar(parent); + if(keys.size() == 0) { + getButton(IDialogConstants.OK_ID).setEnabled(false); + buttonSelectAll.setEnabled(false); + buttonDeselectAll.setEnabled(false); + } + return c; + } + + @Override + protected Control createDialogArea(Composite parent) { + // Help + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, HELP_ID); + + setTitle("Select Properties"); + setMessage("Select Property Keys for Filter"); + + Composite composite = (Composite)super.createDialogArea(parent); + + Composite client = new Composite(composite, SWT.NULL); + GridLayout layout = new GridLayout(2, false); + client.setLayout(layout); + client.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createTableControl(client); + createButtonPanel(client); + + return composite; + } + + private void createTableControl(Composite parent) { + Composite tableComp = new Composite(parent, SWT.BORDER); + TableColumnLayout tableLayout = new TableColumnLayout(); + tableComp.setLayout(tableLayout); + tableComp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + tableViewer = CheckboxTableViewer.newCheckList(tableComp, SWT.MULTI | SWT.FULL_SELECTION); + tableViewer.getControl().setLayoutData(new GridData(GridData.FILL_BOTH)); + + tableViewer.getTable().setLinesVisible(true); + + // Columns + TableViewerColumn columnKey = new TableViewerColumn(tableViewer, SWT.NONE, 0); + tableLayout.setColumnData(columnKey.getColumn(), new ColumnWeightData(100, true)); + + // Content Provider + tableViewer.setContentProvider(new IStructuredContentProvider() { + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + + @Override + public Object[] getElements(Object inputElement) { + return keys.toArray(); + } + + @Override + public void dispose() { + } + }); + + // Label Provider + tableViewer.setLabelProvider(new LabelProvider()); + + tableViewer.setInput(keys); + + if(selectedKeys != null) { + tableViewer.setCheckedElements(selectedKeys.toArray()); + } + } + + private void createButtonPanel(Composite parent) { + Composite client = new Composite(parent, SWT.NULL); + + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + client.setLayout(layout); + + GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); + client.setLayoutData(gd); + + buttonSelectAll = new Button(client, SWT.PUSH); + buttonSelectAll.setText("Select All"); + gd = new GridData(GridData.FILL_HORIZONTAL); + buttonSelectAll.setLayoutData(gd); + buttonSelectAll.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + tableViewer.setCheckedElements(keys.toArray()); + })); + + buttonDeselectAll = new Button(client, SWT.PUSH); + buttonDeselectAll.setText("Deselect All"); + gd = new GridData(GridData.FILL_HORIZONTAL); + buttonDeselectAll.setLayoutData(gd); + buttonDeselectAll.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + tableViewer.setCheckedElements(new Object[] {}); + })); + } + + @Override + protected void buttonPressed(int buttonId) { + selectedKeys = new ArrayList<>(); + for(Object o : tableViewer.getCheckedElements()) { + selectedKeys.add((String)o); + } + + setReturnCode(buttonId); + close(); + } + + public List getSelectedKeys() { + return selectedKeys; + } + + @Override + protected void okPressed() { + super.okPressed(); + + } + + @Override + protected Point getDefaultDialogSize() { + return new Point(400, 250); + } + +} \ No newline at end of file diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/messages.properties b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/messages.properties index b83751a23..be5f3865b 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/messages.properties +++ b/com.archimatetool.editor/src/com/archimatetool/editor/views/tree/search/messages.properties @@ -11,7 +11,7 @@ SearchWidget_17=Views SearchWidget_2=Documentation SearchWidget_3=Search in Documentation SearchWidget_4=Filter Options -SearchWidget_5=Properties +SearchWidget_5=Properties... SearchWidget_6=Business SearchWidget_7=Application SearchWidget_8=Technology && Physical