Merge branch 'hotfix/5.44.1'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / descriptiveDataSet / matrix / CharacterMatrixToolbar.java
1 /**
2 * Copyright (C) 2018 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix;
10
11 import java.io.IOException;
12 import java.io.StringReader;
13 import java.io.StringWriter;
14 import java.util.Collection;
15 import java.util.Properties;
16 import java.util.function.Consumer;
17
18 import org.apache.commons.lang3.StringUtils;
19 import org.eclipse.jface.viewers.ArrayContentProvider;
20 import org.eclipse.jface.viewers.ComboViewer;
21 import org.eclipse.jface.viewers.LabelProvider;
22 import org.eclipse.nebula.widgets.nattable.NatTable;
23 import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
24 import org.eclipse.nebula.widgets.nattable.export.command.ExportCommand;
25 import org.eclipse.nebula.widgets.nattable.persistence.PersistenceHelper;
26 import org.eclipse.nebula.widgets.nattable.persistence.command.DisplayPersistenceDialogCommand;
27 import org.eclipse.nebula.widgets.nattable.persistence.command.DisplayPersistenceDialogCommandHandler;
28 import org.eclipse.nebula.widgets.nattable.persistence.command.IStateChangedListener;
29 import org.eclipse.nebula.widgets.nattable.persistence.command.StateChangeEvent;
30 import org.eclipse.nebula.widgets.nattable.persistence.gui.PersistenceDialog;
31 import org.eclipse.nebula.widgets.nattable.tree.command.TreeCollapseAllCommand;
32 import org.eclipse.nebula.widgets.nattable.tree.command.TreeExpandAllCommand;
33 import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.SelectionAdapter;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.graphics.Image;
38 import org.eclipse.swt.layout.GridData;
39 import org.eclipse.swt.layout.GridLayout;
40 import org.eclipse.swt.widgets.Button;
41 import org.eclipse.swt.widgets.Composite;
42 import org.eclipse.swt.widgets.Label;
43
44 import eu.etaxonomy.cdm.api.application.ICdmRepository;
45 import eu.etaxonomy.cdm.api.service.IPreferenceService;
46 import eu.etaxonomy.cdm.model.metadata.CdmPreference;
47 import eu.etaxonomy.cdm.model.metadata.CdmPreference.PrefKey;
48 import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
49 import eu.etaxonomy.cdm.model.metadata.PreferenceSubject;
50 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
51 import eu.etaxonomy.taxeditor.model.ImageResources;
52 import eu.etaxonomy.taxeditor.model.MessagingUtils;
53 import eu.etaxonomy.taxeditor.preference.CdmPreferenceCache;
54 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
55 import eu.etaxonomy.taxeditor.store.CdmStore;
56
57 /**
58 * @author pplitzner
59 * @since Jul 9, 2018
60 *
61 */
62 public class CharacterMatrixToolbar extends Composite {
63
64 private CharacterMatrix matrix;
65 private Label wsLabel;
66 private DisplayPersistenceDialogCommandHandler displayPersistenceDialogCommandHandler;
67 private Properties natTableState;
68
69 public CharacterMatrixToolbar(CharacterMatrix matrix, int style) {
70 super(matrix, style);
71 this.matrix = matrix;
72
73 init();
74 }
75
76 private void init() {
77 setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
78 setLayout(new GridLayout(10, false));
79
80 wsLabel = new Label(this, SWT.NONE);
81
82 Button btnToggleTree = new Button(this, SWT.PUSH);
83 Button btnToggleFlat = new Button(this, SWT.PUSH);
84 Button btnCollapseAll = new Button(this, SWT.PUSH);
85 Button btnExpandAll = new Button(this, SWT.PUSH);
86 Button btnFreezeSuppInfo = new Button(this, SWT.TOGGLE);
87 ComboViewer comboStates = new ComboViewer(this, SWT.DROP_DOWN);
88 Button btnManageState = new Button(this, SWT.PUSH);
89 Button btnExcelExport = new Button(this, SWT.PUSH);
90 Button btnRefresh = new Button(this, SWT.PUSH);
91
92 /**
93 * Toogle tree button
94 */
95 initButton(
96 btnToggleTree,
97 ImageResources.getImage(ImageResources.HIERARCHICAL),
98 Messages.CharacterMatrix_SHOW_HIERARCHY,
99 null,
100 false,
101 true,
102 (e)->matrix.toggleTreeFlat(true, btnToggleFlat, btnToggleTree, btnCollapseAll, btnExpandAll, btnFreezeSuppInfo)
103 );
104
105 /**
106 * Toogle flat button
107 */
108 initButton(
109 btnToggleFlat,
110 ImageResources.getImage(ImageResources.FLAT),
111 Messages.CharacterMatrix_SHOW_FLAT_LIST,
112 null,
113 true,
114 false,
115 (e)->matrix.toggleTreeFlat(false, btnToggleFlat, btnToggleTree, btnCollapseAll, btnExpandAll, btnFreezeSuppInfo)
116 );
117
118 /**
119 *
120 * Collapse button
121 */
122 initButton(
123 btnCollapseAll,
124 ImageResources.getImage(ImageResources.COLLAPSE_ALL),
125 Messages.CharacterMatrix_COLLAPSE,
126 null,
127 true,
128 false,
129 (e)->matrix.getNatTable().doCommand(new TreeCollapseAllCommand())
130 );
131
132 /**
133 * Expand button
134 */
135 initButton(
136 btnExpandAll,
137 ImageResources.getImage(ImageResources.EXPAND_ALL),
138 Messages.CharacterMatrix_EXPAND,
139 null,
140 true,
141 false,
142 (e)->matrix.getNatTable().doCommand(new TreeExpandAllCommand())
143 );
144
145 /**
146 * Freeze supplemental info button
147 */
148 initButton(
149 btnFreezeSuppInfo,
150 ImageResources.getImage(ImageResources.LOCK_ICON),
151 Messages.CharacterMatrix_LOCK_COLUMNS,
152 null,
153 true,
154 true,
155 (e)->{
156 boolean isSelected = btnFreezeSuppInfo.getSelection();
157 matrix.freezeSupplementalColumns(isSelected);
158 btnFreezeSuppInfo.setImage(isSelected?
159 ImageResources.getImage(ImageResources.LOCK_ICON):
160 ImageResources.getImage(ImageResources.LOCK_OPEN_ICON));
161 }
162 );
163
164 /**
165 * Table state persistence
166 */
167 natTableState = new Properties();
168 //load persisted state
169 try {
170 PrefKey key = CdmPreference.NewKey(PreferenceSubject.NewTaxEditorInstance(), PreferencePredicate.CharacterMatrixTableState);
171 CdmPreference preference = CdmPreferenceCache.instance().get(key);
172 if(preference!=null){
173 natTableState.load(new StringReader(preference.getValue()));
174 }
175 } catch (IOException e1) {
176 MessagingUtils.error(getClass(), e1);
177 }
178
179 // create a combobox for showing the available view states
180 Collection<String> availableStates = PersistenceHelper.getAvailableStates(natTableState);
181 if(availableStates.isEmpty()){
182 natTableState.put(StringUtils.EMPTY, StringUtils.EMPTY); // add default config if no states are persisted
183 natTableState.setProperty(PersistenceDialog.ACTIVE_VIEW_CONFIGURATION_KEY, StringUtils.EMPTY);
184 availableStates.add(StringUtils.EMPTY);
185 }
186 comboStates.setLabelProvider(new LabelProvider(){
187 @Override
188 public String getText(Object element) {
189 if(element instanceof String && ((String) element).isEmpty()){
190 return Messages.CharacterMatrix_DEFAULT;
191 }
192 return super.getText(element);
193 }
194 });
195 comboStates.setContentProvider(new ArrayContentProvider());
196 comboStates.addSelectionChangedListener(e->
197 {
198 int index = comboStates.getCombo().getSelectionIndex();
199 if (index >= 0) {
200 String selected = comboStates.getCombo().getItem(index);
201 // load the state
202 matrix.getNatTable().loadState(selected, natTableState);
203 natTableState.setProperty(PersistenceDialog.ACTIVE_VIEW_CONFIGURATION_KEY, selected);
204 }
205 });
206 comboStates.setInput(availableStates);
207 if(comboStates.getCombo().getItemCount()>0){
208 selectStateItem(comboStates, Messages.CharacterMatrix_DEFAULT);
209 }
210
211 displayPersistenceDialogCommandHandler = new DisplayPersistenceDialogCommandHandler(natTableState, matrix.getNatTable());
212 // add listener to update the combo on view state management changes
213 displayPersistenceDialogCommandHandler.addStateChangeListener(new IStateChangedListener() {
214 @Override
215 public void handleStateChange(StateChangeEvent event) {
216 comboStates.setInput(PersistenceHelper.getAvailableStates(natTableState));
217 selectStateItem(comboStates, event.getViewConfigName());
218 }
219 });
220
221 // add button to show dialog
222 btnManageState.setImage(ImageResources.getImage(ImageResources.SETTINGS));
223 btnManageState.setToolTipText(Messages.CharacterMatrix_VIEW_CONFIG);
224 btnManageState.addSelectionListener(new SelectionAdapter() {
225 @Override
226 public void widgetSelected(SelectionEvent e) {
227 getNatTableState().remove(NatTable.INITIAL_PAINT_COMPLETE_FLAG);
228 matrix.getNatTable().doCommand(new DisplayPersistenceDialogCommand(matrix.getNatTable()));
229 Object activeConfig = natTableState.get(PersistenceDialog.ACTIVE_VIEW_CONFIGURATION_KEY);
230 if(activeConfig!=null){
231 selectStateItem(comboStates, activeConfig.toString());
232 }
233 persistTableState();
234 }
235 });
236
237 /**
238 * excel export
239 */
240 btnExcelExport.setToolTipText(Messages.CharacterMatrix_EXPORT);
241 btnExcelExport.setImage(ImageResources.getImage(ImageResources.EXPORT));
242 btnExcelExport.addSelectionListener(new SelectionAdapter() {
243 @Override
244 public void widgetSelected(SelectionEvent e) {
245 // hack for fixing #8332
246 // By scrolling for only 1 pixel the export then exports all rows
247 ViewportLayer viewportLayer = matrix.getBodyLayer().getViewportLayer();
248 if(viewportLayer.getOrigin().getY()==0){
249 viewportLayer.setOriginY(1);
250 }
251 matrix.getNatTable().doCommand(
252 new ExportCommand(
253 matrix.getNatTable().getConfigRegistry(),
254 matrix.getNatTable().getShell()));
255 matrix.getNatTable().doCommand(new VisualRefreshCommand());
256 }
257 });
258
259 /**
260 * excel export
261 */
262 // btnRefresh.setToolTipText(Messages.CharacterMatrix_REFFRESH);
263 btnRefresh.setImage(ImageResources.getImage(ImageResources.REFRESH));
264 btnRefresh.addSelectionListener(new SelectionAdapter() {
265 @Override
266 public void widgetSelected(SelectionEvent e) {
267 if (matrix != null && matrix.getPart() != null){
268
269 matrix.getPart().init(matrix.getDescriptiveDataSet().getUuid(), true);
270 matrix.initDescriptiveDataSet();
271 matrix.redraw();
272 }
273
274
275
276 }
277 });
278
279 }
280
281 private void persistTableState() {
282 if(matrix.getNatTableState()!=null){
283 StringWriter writer = new StringWriter();
284 try {
285 matrix.getNatTableState().store(writer, null);
286 ICdmRepository controller = CdmStore.getCurrentApplicationConfiguration();
287 if (controller != null){
288 IPreferenceService service = controller.getPreferenceService();
289 CdmPreference pref = CdmPreference.NewTaxEditorInstance(PreferencePredicate.CharacterMatrixTableState, writer.toString());
290 service.set(pref);
291 PreferencesUtil.updateDBPreferences();
292 }
293 } catch (IOException e) {
294 MessagingUtils.error(getClass(), e);
295 }
296 }
297 }
298
299 private void selectStateItem(ComboViewer comboStates, String stateName){
300 if(stateName.equals(StringUtils.EMPTY)){
301 stateName = Messages.CharacterMatrix_DEFAULT;
302 }
303 String[] items = comboStates.getCombo().getItems();
304 for(int i=0;i<items.length;i++){
305 if(items[i].equals(stateName)){
306 comboStates.getCombo().select(i);
307 break;
308 }
309 }
310 }
311
312 private void initButton(Button button, Image image, String tooltipText,
313 String label, boolean enabled, boolean selected, Consumer<SelectionEvent> widgetSelected){
314 if(image!=null){
315 button.setImage(image);
316 }
317 if(label!=null){
318 button.setText(label);
319 }
320 if(tooltipText!=null){
321 button.setToolTipText(tooltipText);
322 }
323 button.setSelection(selected);
324 button.setEnabled(enabled);
325 button.addSelectionListener(new SelectionAdapter() {
326 @Override
327 public void widgetSelected(SelectionEvent e) {
328 widgetSelected.accept(e);
329 }
330 });
331 }
332
333 public Label getWsLabel() {
334 return wsLabel;
335 }
336
337 public Properties getNatTableState() {
338 return natTableState;
339 }
340
341 public DisplayPersistenceDialogCommandHandler getDisplayPersistenceDialogCommandHandler() {
342 return displayPersistenceDialogCommandHandler;
343 }
344 }