Fix expansion state preference for details and suppData view
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / view / e4 / AbstractCdmDataViewerE4.java
1 /**
2 * Copyright (C) 2007 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
10 package eu.etaxonomy.taxeditor.view.e4;
11
12 import javax.inject.Inject;
13
14 import org.eclipse.e4.core.contexts.ContextInjectionFactory;
15 import org.eclipse.e4.core.contexts.IEclipseContext;
16 import org.eclipse.e4.core.services.log.Logger;
17 import org.eclipse.jface.viewers.Viewer;
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.SWTException;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Display;
23 import org.eclipse.ui.forms.IFormPart;
24 import org.eclipse.ui.forms.ManagedForm;
25 import org.eclipse.ui.forms.widgets.ExpandableComposite;
26 import org.eclipse.ui.forms.widgets.ScrolledForm;
27
28 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
29 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
30 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
31 import eu.etaxonomy.taxeditor.model.MessagingUtils;
32 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
33 import eu.etaxonomy.taxeditor.remoting.CdmEagerLoadingException;
34 import eu.etaxonomy.taxeditor.store.StoreUtil;
35 import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection;
36 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
37 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
38 import eu.etaxonomy.taxeditor.ui.element.RootElement;
39 import eu.etaxonomy.taxeditor.ui.section.occurrence.EmptySection;
40 import eu.etaxonomy.taxeditor.view.detail.CdmSectionPart;
41
42 /**
43 *
44 * @author pplitzner
45 * @date 18.07.2017
46 *
47 */
48 public abstract class AbstractCdmDataViewerE4 extends Viewer implements IConversationEnabled{
49 @Inject
50 private Logger logger;
51
52 protected ManagedForm managedForm;
53
54 protected CdmFormFactory formFactory;
55
56 protected ScrolledForm scrolledForm;
57
58 private Composite body;
59
60 protected RootElement rootElement;
61
62 @Inject
63 protected IEclipseContext context;
64
65 //TODO: create a super class for this?
66 private Object input;
67
68 protected IDirtyMarkable part;
69
70 @Inject
71 public AbstractCdmDataViewerE4() {
72
73 }
74
75 public void init(Composite parent, IDirtyMarkable part) {
76 this.part = part;
77
78 managedForm = new ManagedForm(parent){
79
80 @Override
81 public void dirtyStateChanged() {
82 markViewPartDirty();
83 }
84 };
85
86 createFormFactory();
87
88 scrolledForm = managedForm.getForm();
89
90 body = scrolledForm.getBody();
91
92 body.setLayout(LayoutConstants.LAYOUT());
93
94 rootElement = new RootElement(formFactory, body);
95 }
96
97
98 protected void createEmptySection(String message, RootElement parent) {
99 destroySections();
100
101 EmptySection emptySection = formFactory.createEmptySection(message, formFactory, parent, SWT.NONE);
102
103 addPart(emptySection);
104 }
105
106 public void showEmptyPage(String message){
107 destroySections();
108 createEmptySection(message, rootElement);
109 }
110
111 protected void markViewPartDirty(){
112 part.changed(input);
113 }
114
115 protected void createFormFactory() {
116 if(formFactory != null){
117 formFactory.dispose();
118 formFactory = null;
119 }
120 formFactory = new CdmFormFactory(Display.getCurrent(), this);
121 ContextInjectionFactory.inject(formFactory, context);
122 }
123
124 /** {@inheritDoc} */
125 @Override
126 public Control getControl() {
127 if(body!=null){
128 if(body.isDisposed()){
129 return null;
130 }
131 for(Control child : body.getChildren()){
132 return child;
133 }
134 }
135
136 return body;
137 }
138
139 /** {@inheritDoc} */
140 @Override
141 public void setInput(Object input) {
142 this.input = input;
143 if(input!=null){
144 try{
145 refresh();
146 }catch(CdmEagerLoadingException e){
147 logger.error(e);
148 }
149 }
150 }
151
152 /** {@inheritDoc} */
153 @Override
154 public Object getInput() {
155 return input;
156 }
157
158 /** {@inheritDoc} */
159 @Override
160 public void refresh() {
161 showParts();
162
163 if(input!=null){
164 managedForm.setInput(input);
165 }
166
167 managedForm.refresh();
168
169 // managedForm.reflow(true);
170 }
171
172 public void layout(){
173 body.layout();
174 }
175
176 protected int getSectionStyle(Class<? extends AbstractFormSection> clazz){
177 return getSectionStyle(clazz, false);
178 }
179
180 protected int getSectionStyle(Class<? extends AbstractFormSection> clazz, boolean initiallyExpanded){
181 int style = ExpandableComposite.TWISTIE;
182 String prefKey = StoreUtil.getPrefKey(clazz, getInput());
183 if(PreferencesUtil.contains(prefKey)){
184 style = PreferencesUtil.getStringValue(prefKey)==CdmSectionPart.EXPANDED?style |= ExpandableComposite.EXPANDED:style;
185 }
186 else{
187 style = initiallyExpanded?style |= ExpandableComposite.EXPANDED:style;
188 }
189 return style;
190 }
191
192 protected abstract void showParts();
193
194 public void destroySections() {
195 for (IFormPart formPart : managedForm.getParts()){
196 removePart((CdmSectionPart<?>) formPart);
197 }
198
199 managedForm.setInput(null);
200
201 formFactory.destroyElement(rootElement);
202
203 createFormFactory();
204
205 rootElement = new RootElement(formFactory, body);
206
207 for(Control control : body.getChildren()){
208 try{
209 if (control != null && !control.isDisposed()){
210 control.dispose();
211 }
212 }catch(SWTException e){
213 if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
214 MessagingUtils.errorDialog("Widget is disposed",
215 null,
216 MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
217 null,
218 e,
219 true);
220
221 }
222 }
223 control = null;
224 }
225 }
226
227 public void setFocus(){
228 // we have to set focus to a control of this viewer
229 // otherwise, after opening a dialog from the details, the focus will not be
230 // given back to the details view but to the editor
231 for(Control child : body.getChildren()){
232 child.setFocus();
233 break;
234 }
235 }
236
237 public void reflow(){
238 managedForm.reflow(true);
239 }
240
241 protected void removePart(CdmSectionPart<?> sectionPart){
242 managedForm.removePart(sectionPart);
243 formFactory.removePropertyChangeListener(sectionPart);
244 }
245
246 protected void addPart(AbstractFormSection<?> section){
247 CdmSectionPart<?> sectionPart = new CdmSectionPart<>(section);
248 managedForm.addPart(sectionPart);
249 formFactory.addPropertyChangeListener(sectionPart);
250 }
251
252 @Override
253 public ConversationHolder getConversationHolder() {
254 return null;
255 }
256
257 }