Project

General

Profile

Download (10.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 *
3
 */
4
package eu.etaxonomy.taxeditor.ui.section;
5

    
6
import java.util.Collection;
7
import java.util.EnumSet;
8
import java.util.Observable;
9
import java.util.Observer;
10

    
11
import org.eclipse.jface.action.Action;
12
import org.eclipse.jface.action.IAction;
13
import org.eclipse.jface.action.ToolBarManager;
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.swt.SWT;
16
import org.eclipse.swt.events.DisposeEvent;
17
import org.eclipse.swt.events.DisposeListener;
18
import org.eclipse.swt.events.SelectionAdapter;
19
import org.eclipse.swt.events.SelectionEvent;
20
import org.eclipse.swt.events.SelectionListener;
21
import org.eclipse.swt.graphics.Color;
22
import org.eclipse.swt.graphics.ImageData;
23
import org.eclipse.swt.widgets.Composite;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.swt.widgets.Label;
26
import org.eclipse.ui.forms.events.ExpansionEvent;
27
import org.eclipse.ui.forms.events.IExpansionListener;
28
import org.eclipse.ui.forms.widgets.ExpandableComposite;
29

    
30
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
31
import eu.etaxonomy.cdm.common.CdmUtils;
32
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
33
import eu.etaxonomy.taxeditor.model.AbstractUtility;
34
import eu.etaxonomy.taxeditor.model.ImageResources;
35
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
36
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
37
import eu.etaxonomy.taxeditor.preference.Resources;
38
import eu.etaxonomy.taxeditor.store.CdmStore;
39
import eu.etaxonomy.taxeditor.store.LoginManager;
40
import eu.etaxonomy.taxeditor.store.StoreUtil;
41
import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection;
42
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
43
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
44

    
45
/**
46
 * This class visualizes an CDM entity of type ENTITY and additionally provides the functionality to add
47
 * other elements of type ELEMENT to them.
48
 *
49
 * @param <ENTITY> A CDM entity which should be visualized by this section.
50
 * @param <ELEMENT> An element that can be added (multiple times) to this entity.
51
 *
52
 * @author n.hoffmann
53
 * @version $Id: $
54
 */
55

    
56
public abstract class AbstractEntityCollectionSection<ENTITY, ELEMENT> extends AbstractFormSection<ENTITY> implements IExpansionListener, Observer {
57

    
58
	/**
59
     *
60
     */
61
    private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
62

    
63
    protected Composite container;
64

    
65
	private Label label_empty;
66

    
67
	private String title;
68

    
69
	/**
70
	 * <p>Constructor for AbstractEntityCollectionSection.</p>
71
	 *
72
	 * @param conversation
73
	 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement} object.
74
	 * @param style a int.
75
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory} object.
76
	 * @param title a {@link java.lang.String} object.
77
	 * @param <ENTITY> a ENTITY object.
78
	 * @param <ELEMENT> a ELEMENT object.
79
	 */
80
	public AbstractEntityCollectionSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, String title, int style) {
81
		super(formFactory, parentElement, ExpandableComposite.CLIENT_INDENT | style);
82
		this.title = title;
83
		this.setText(getTitleString());
84
		updateToolbar();
85

    
86
		addExpansionListener(this);
87

    
88
		CdmStore.getLoginManager().addObserver(this);
89
		addDisposeListener(new DisposeListener() {
90
            @Override
91
            public void widgetDisposed(DisposeEvent e) {
92
                CdmStore.getLoginManager().deleteObserver(AbstractEntityCollectionSection.this);
93
            }
94
        });
95
	}
96

    
97
	protected Control createToolbar() {
98
		ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
99

    
100
		Action addAction = new Action("add", IAction.AS_PUSH_BUTTON){
101
			/* (non-Javadoc)
102
			 * @see org.eclipse.jface.action.Action#run()
103
			 */
104
			@Override
105
			public void run() {
106
				ELEMENT element = createNewElement();
107
				if(element != null){
108
					addElement(element);
109
					if(! getSection().isExpanded()) {
110
                        getSection().setExpanded(true);
111
                    }
112
					internalUpdateSection(true);
113
				}
114
			}
115
		};
116
		addAction.setImageDescriptor(new ImageDescriptor() {
117

    
118
			@Override
119
			public ImageData getImageData() {
120
				return ImageResources.getImage(ImageResources.ADD_ICON).getImageData();
121
			}
122
		});
123
		addAction.setToolTipText(getTooltipString());
124

    
125
		toolBarManager.add(addAction);
126

    
127
		return toolBarManager.createControl(this);
128
	}
129

    
130
	/**
131
	 * using this method is discouraged, use updateToolBar() instead
132
	 */
133
	public void showToolbar(){
134
		setTextClient(createToolbar());
135
	}
136

    
137
    /**
138
     * using this method is discouraged, use updateToolBar() instead
139
     */
140
	public void removeToolbar(){
141
		setTextClient(null);
142
	}
143

    
144
	/**
145
	 * <p>setEntity</p>
146
	 *
147
	 * @param entity a ENTITY object.
148
	 */
149
	@Override
150
	public void setEntity(ENTITY entity) {
151
		if(entity != null){
152
			super.setEntity(entity);
153
			internalUpdateSection(false);
154
		}
155
		setSectionTitle();
156
		updateToolbar();
157
		layout();
158
	}
159

    
160
	/**
161
	 * Sets the title for the section. Adds a "+" sign if the collection is not empty for this section.
162
	 * Override in subclasses if you want to have a different behaviour.
163
	 */
164
	protected void setSectionTitle() {
165
		if(getCollection(getEntity()) != null && getCollection(getEntity()).size() > 0){
166
			this.setText(getTitleString() + " +");
167
		}else{
168
			this.setText(getTitleString());
169
		}
170
	}
171

    
172
	/**
173
	 * Removes all content from the container
174
	 */
175
	private void destroyDynamicContent(){
176
		if(label_empty != null){
177
			label_empty.dispose();
178
			label_empty = null;
179
		}
180
		removeElements();
181
	}
182

    
183
	/**
184
	 * Call this method after dynamically changing the client area.
185
	 * If the options changed is set to true, will also fire a state changed
186
	 * event to inform the user of unsaved changes.
187
	 *
188
	 * @param changed a boolean.
189
	 */
190
	protected void internalUpdateSection(boolean changed){
191
		destroyDynamicContent();
192
		if(isExpanded() || expandSectionWhenContentAvailable()) {
193
            renderContent(isExpanded());
194
        }
195
		if(changed) {
196
            firePropertyChangeEvent(this);
197
        }
198
	}
199

    
200
	/**
201
	 * Create the elements to be shown in this section client area
202
	 */
203
	private void renderContent(boolean forceExpansion)
204
	{
205
		Collection<ELEMENT> elements = getCollection(getEntity());
206

    
207
		if(elements == null || elements.isEmpty()){
208
			createEmptyContent();
209
		}else{
210
			createDynamicContents(elements);
211
			forceExpansion = true;
212
		}
213

    
214
		this.setExpanded(forceExpansion);
215

    
216
		reflow();
217
	}
218

    
219
	/**
220
	 * <p>createEmptyContent</p>
221
	 */
222
	protected void createEmptyContent(){
223
		label_empty = formFactory.createLabel(getLayoutComposite(), getEmptyString());
224
	}
225

    
226
	/**
227
	 * Creates the widgets for the collection
228
	 *
229
	 * @param elements a {@link java.util.Collection} object.
230
	 */
231
	protected void createDynamicContents(Collection<ELEMENT> elements)
232
	{
233
		int i = 0;
234
		for(final ELEMENT element : elements){
235
			SelectionAdapter removeListener = new SelectionAdapter(){
236
				@Override
237
				public void widgetSelected(SelectionEvent e) {
238
					removeElement(element);
239
					internalUpdateSection(true);
240
				}
241
			};
242
			boolean modulo = i++%2 == 0;
243
			String colorResource = modulo ? Resources.COLOR_LIST_EVEN : Resources.COLOR_LIST_ODD;
244
			createElementComposite(element, removeListener, AbstractUtility.getColor(colorResource));
245
		}
246
	}
247

    
248
	/**
249
	 * Create the specific widget for the element
250
	 *
251
	 * @param element a ELEMENT object.
252
	 * @param removeListener a {@link org.eclipse.swt.events.SelectionListener} object.
253
	 * @param backgroundColor a {@link org.eclipse.swt.graphics.Color} object.
254
	 */
255
	protected void createElementComposite(ELEMENT element, SelectionListener removeListener, Color backgroundColor){
256
		formFactory.createEntityCollectionElement(this, element, removeListener, backgroundColor, SWT.NULL);
257
	}
258

    
259
	/* (non-Javadoc)
260
	 * @see eu.etaxonomy.taxeditor.forms.section.AbstractEditorFormSection#setBackground(org.eclipse.swt.graphics.Color)
261
	 */
262
	/** {@inheritDoc} */
263
	@Override
264
	public void setBackground(Color color) {
265
		if(label_empty != null && !label_empty.isDisposed()){
266
			label_empty.setBackground(color);
267
		}
268
		super.setBackground(color);
269
	}
270

    
271
	/**
272
	 * <p>getTitleString</p>
273
	 *
274
	 * @return a {@link java.lang.String} object.
275
	 */
276
	public String getTitleString() {
277
		return CdmUtils.Nz(title);
278
	}
279

    
280
	/**
281
	 * <p>setTitleString</p>
282
	 *
283
	 * @param title a {@link java.lang.String} object.
284
	 */
285
	public void setTitleString(String title){
286
		this.title = title;
287
		setSectionTitle();
288
		layout();
289
	}
290

    
291
	/** {@inheritDoc} */
292
	@Override
293
    public void expansionStateChanging(ExpansionEvent e) {
294
//		logger.warn("Expansion State Changing");
295
	}
296

    
297
	/** {@inheritDoc} */
298
	@Override
299
    public void expansionStateChanged(ExpansionEvent e) {
300
		if(isExpanded()){
301
			renderContent(isExpanded());
302
		}else{
303
			destroyDynamicContent();
304
		}
305
	}
306

    
307
	private boolean expandSectionWhenContentAvailable(){
308
		return PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOULD_EXPAND_SECTION_WHEN_DATA_AVAILABLE);
309
	}
310

    
311
	/**
312
	 * Remove an element from the entities collection and update the section
313
	 *
314
	 * @param element a ELEMENT object.
315
	 */
316
	public void removeElementAndUpdate(ELEMENT element) {
317
		removeElement(element);
318
		internalUpdateSection(true);
319
	}
320

    
321
	/* (non-Javadoc)
322
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
323
	 */
324
	@Override
325
    public void update(Observable o, Object arg){
326
	    if(o instanceof LoginManager){
327
	        updateToolbar();
328
	    }
329
	}
330

    
331
    private void updateToolbar() {
332
        if(getEntity() != null && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), UPDATE)){
333
            showToolbar();
334
        } else {
335
            removeToolbar();
336
        }
337
    }
338

    
339
	/**
340
	 * Get the specific collection of this entity
341
	 *
342
	 * @param entity a ENTITY object.
343
	 * @return a {@link java.util.Collection} object.
344
	 */
345
	public abstract Collection<ELEMENT> getCollection(ENTITY entity);
346

    
347
	/**
348
	 * Create a new Element for this collection
349
	 *
350
	 * @return a ELEMENT object.
351
	 */
352
	public abstract ELEMENT createNewElement();
353

    
354
	/**
355
	 * Add an element to the entities collection
356
	 *
357
	 * @param element a ELEMENT object.
358
	 */
359
	public abstract void addElement(ELEMENT element);
360

    
361
	/**
362
	 * Remove an element from the entities collection
363
	 *
364
	 * @param element a ELEMENT object.
365
	 */
366
	public abstract void removeElement(ELEMENT element);
367

    
368
	/**
369
	 * String to display when the collection is empty
370
	 *
371
	 * @return a {@link java.lang.String} object.
372
	 */
373
	public abstract String getEmptyString();
374

    
375
	/**
376
	 * <p>getTooltipString</p>
377
	 *
378
	 * @return String to display when hovering the add button
379
	 */
380
	protected abstract String getTooltipString();
381
}
(4-4/8)