Project

General

Profile

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

    
6
import java.util.Collection;
7

    
8
import org.apache.commons.collections.CollectionUtils;
9
import org.eclipse.jface.action.Action;
10
import org.eclipse.jface.action.ToolBarManager;
11
import org.eclipse.jface.resource.ImageDescriptor;
12
import org.eclipse.swt.SWT;
13
import org.eclipse.swt.events.SelectionAdapter;
14
import org.eclipse.swt.events.SelectionEvent;
15
import org.eclipse.swt.events.SelectionListener;
16
import org.eclipse.swt.graphics.Color;
17
import org.eclipse.swt.graphics.ImageData;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Control;
20
import org.eclipse.swt.widgets.Label;
21
import org.eclipse.ui.forms.events.ExpansionEvent;
22
import org.eclipse.ui.forms.events.IExpansionListener;
23
import org.eclipse.ui.forms.widgets.Section;
24

    
25
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
26
import eu.etaxonomy.cdm.common.CdmUtils;
27
import eu.etaxonomy.taxeditor.model.ImageResources;
28
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
29
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
30
import eu.etaxonomy.taxeditor.preference.Resources;
31
import eu.etaxonomy.taxeditor.store.StoreUtil;
32
import eu.etaxonomy.taxeditor.ui.forms.AbstractFormSection;
33
import eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory;
34
import eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement;
35

    
36
/**
37
 * <p>Abstract AbstractEntityCollectionSection class.</p>
38
 *
39
 * @author n.hoffmann
40
 * @version $Id: $
41
 */
42
public abstract class AbstractEntityCollectionSection<ENTITY, ELEMENT> extends AbstractFormSection<ENTITY> implements IExpansionListener{
43
		
44
	protected Composite container;
45
	
46
	private Label label_empty;
47

    
48
	private String title;
49
	
50
	/**
51
	 * <p>Constructor for AbstractEntityCollectionSection.</p>
52
	 *
53
	 * @param conversation 
54
	 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
55
	 * @param style a int.
56
	 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
57
	 * @param title a {@link java.lang.String} object.
58
	 * @param <ENTITY> a ENTITY object.
59
	 * @param <ELEMENT> a ELEMENT object.
60
	 */
61
	public AbstractEntityCollectionSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, String title, int style) {
62
		super(formFactory, parentElement, Section.CLIENT_INDENT | style);
63
		this.title = title;
64
		this.setText(getTitleString());
65
		showToolbar();
66
		
67
		addExpansionListener(this);
68
	}
69
	
70
	protected Control createToolbar() {
71
		ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
72
		
73
		Action addAction = new Action("add", Action.AS_PUSH_BUTTON){
74
			/* (non-Javadoc)
75
			 * @see org.eclipse.jface.action.Action#run()
76
			 */
77
			@Override
78
			public void run() {
79
				ELEMENT element = createNewElement();
80
				if(element != null){
81
					addElement(element);
82
					if(! getSection().isExpanded())
83
						getSection().setExpanded(true);
84
					internalUpdateSection(true);
85
				}
86
			}
87
		};
88
		addAction.setImageDescriptor(new ImageDescriptor() {
89
			
90
			@Override
91
			public ImageData getImageData() {
92
				return ImageResources.getImage(ImageResources.ADD_ICON).getImageData();
93
			}
94
		});
95
		addAction.setToolTipText(getTooltipString());
96
		
97
		toolBarManager.add(addAction);
98
		
99
		return toolBarManager.createControl(this);
100
	}
101
	
102
	public void showToolbar(){
103
		setTextClient(createToolbar());
104
	}
105
	
106
	public void removeToolbar(){
107
		setTextClient(null);
108
	}
109
	
110
	/**
111
	 * <p>setEntity</p>
112
	 *
113
	 * @param entity a ENTITY object.
114
	 */
115
	@Override
116
	public void setEntity(ENTITY entity) {
117
		if(entity != null && hasCollectionChanged(entity)){
118
			super.setEntity(entity);
119
			internalUpdateSection(false);
120
		}
121
		setSectionTitle();
122
		layout();
123
	};
124
		
125
	/**
126
	 * Sets the title for the section. Adds a "+" sign if the collection is not empty for this section.
127
	 * Override in subclasses if you want to have a different behaviour.
128
	 */
129
	protected void setSectionTitle() {
130
		if(getCollection(getEntity()) != null && getCollection(getEntity()).size() > 0){
131
			this.setText(getTitleString() + " +");
132
		}else{
133
			this.setText(getTitleString());
134
		}
135
	}
136
	
137
	/**
138
	 * Removes all content from the container
139
	 */
140
	private void destroyDynamicContent(){
141
		if(label_empty != null){
142
			label_empty.dispose();
143
			label_empty = null;
144
		}
145
		removeElements();
146
	}
147
	
148
	/**
149
	 * Call this method after dynamically changing the client area.
150
	 * If the options changed is set to true, will also fire a state changed
151
	 * event to inform the user of unsaved changes.
152
	 *
153
	 * @param changed a boolean.
154
	 */
155
	protected void internalUpdateSection(boolean changed){
156
		destroyDynamicContent();
157
		if(isExpanded() || expandSectionWhenContentAvailable())
158
			renderContent(isExpanded());
159
		if(changed)
160
			firePropertyChangeEvent(this);
161
	}
162

    
163
	/**
164
	 * Whether the entities specific collection changed
165
	 * 
166
	 * @param newEntity
167
	 * @return
168
	 */
169
	private boolean hasCollectionChanged(ENTITY newEntity){
170

    
171
		// return true on null
172
		if(getEntity() == null || newEntity == null)	return true;	
173
		
174
		// if the entities differ the collection has changed
175
		if(! getEntity().equals(newEntity)) return true;
176
		
177
		Collection<ELEMENT> oldCollection = getCollection(getEntity());
178
		Collection<ELEMENT> newCollection = getCollection(newEntity);
179
		
180
		// return true on null
181
		if(oldCollection == null || newCollection == null) return true;
182
		
183
		// if the collections are object equal, check if the content is equal, too
184
		if(oldCollection.equals(newCollection)){
185
		
186
			boolean equal = CollectionUtils.isEqualCollection(oldCollection, newCollection);
187
			// return true when collections are not equal
188
			return equal ? false : true;
189
		}
190
		return true;
191
	}
192

    
193
	/**
194
	 * Create the elements to be shown in this seciton client area 
195
	 */
196
	private void renderContent(boolean forceExpansion)
197
	{
198
		Collection<ELEMENT> elements = getCollection(getEntity());
199
		
200
		if(elements == null || elements.isEmpty()){
201
			createEmptyContent();
202
		}else{
203
			createDynamicContents(elements);
204
			forceExpansion = true;
205
		}
206
		
207
		this.setExpanded(forceExpansion);
208
		
209
		reflow();
210
	}
211
	
212
	/**
213
	 * <p>createEmptyContent</p>
214
	 */
215
	protected void createEmptyContent(){
216
		label_empty = formFactory.createLabel(getLayoutComposite(), getEmptyString());
217
	}
218
	
219
	/**
220
	 * Creates the widgets for the collection
221
	 *
222
	 * @param elements a {@link java.util.Collection} object.
223
	 */
224
	protected void createDynamicContents(Collection<ELEMENT> elements)
225
	{		
226
		int i = 0;
227
		for(final ELEMENT element : elements){
228
			SelectionAdapter removeListener = new SelectionAdapter(){
229
				@Override
230
				public void widgetSelected(SelectionEvent e) {
231
					removeElement(element);					
232
					internalUpdateSection(true);
233
				}
234
			};
235
			boolean modulo = i++%2 == 0;
236
			String colorResource = modulo ? Resources.COLOR_LIST_EVEN : Resources.COLOR_LIST_ODD;
237
			createElementComposite(element, removeListener, StoreUtil.getColor(colorResource));
238
		}
239
	}
240

    
241
	/**
242
	 * Create the specific widget for the element
243
	 *
244
	 * @param element a ELEMENT object.
245
	 * @param removeListener a {@link org.eclipse.swt.events.SelectionListener} object.
246
	 * @param backgroundColor a {@link org.eclipse.swt.graphics.Color} object.
247
	 */
248
	protected void createElementComposite(ELEMENT element, SelectionListener removeListener, Color backgroundColor){
249
		AbstractEntityCollectionElement formElement = formFactory.createEntityCollectionElement(this, element, removeListener, backgroundColor, SWT.NULL);
250
	}
251
	
252
	/* (non-Javadoc)
253
	 * @see eu.etaxonomy.taxeditor.forms.section.AbstractEditorFormSection#setBackground(org.eclipse.swt.graphics.Color)
254
	 */
255
	/** {@inheritDoc} */
256
	@Override
257
	public void setBackground(Color color) {
258
		if(label_empty != null && !label_empty.isDisposed()){
259
			label_empty.setBackground(color);
260
		}
261
		super.setBackground(color);
262
	}
263

    
264
	/**
265
	 * <p>getTitleString</p>
266
	 *
267
	 * @return a {@link java.lang.String} object.
268
	 */
269
	public String getTitleString() {
270
		return CdmUtils.Nz(title);
271
	}
272
	
273
	/**
274
	 * <p>setTitleString</p>
275
	 *
276
	 * @param title a {@link java.lang.String} object.
277
	 */
278
	public void setTitleString(String title){
279
		this.title = title;
280
		setSectionTitle();
281
		layout();
282
	}
283
	
284
	/** {@inheritDoc} */
285
	public void expansionStateChanging(ExpansionEvent e) {
286
//		logger.warn("Expansion State Changing");
287
	}
288
	
289
	/** {@inheritDoc} */
290
	public void expansionStateChanged(ExpansionEvent e) {
291
		if(isExpanded()){
292
			renderContent(isExpanded());
293
		}else{
294
			destroyDynamicContent();
295
		}
296
	}
297
	
298
	private boolean expandSectionWhenContentAvailable(){
299
		return PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOULD_EXPAND_SECTION_WHEN_DATA_AVAILABLE);
300
	}
301
	
302
	/**
303
	 * Get the specific collection of this entity
304
	 *
305
	 * @param entity a ENTITY object.
306
	 * @return a {@link java.util.Collection} object.
307
	 */
308
	public abstract Collection<ELEMENT> getCollection(ENTITY entity);
309
	
310
	/**
311
	 * Create a new Element for this collection
312
	 *
313
	 * @return a ELEMENT object.
314
	 */
315
	public abstract ELEMENT createNewElement();
316
	
317
	/**
318
	 * Add an element to the entities collection
319
	 *
320
	 * @param element a ELEMENT object.
321
	 */
322
	public abstract void addElement(ELEMENT element);
323
	
324
	/**
325
	 * Remove an element from the entities collection
326
	 *
327
	 * @param element a ELEMENT object.
328
	 */
329
	public abstract void removeElement(ELEMENT element);
330
	
331
	/**
332
	 * String to display when the collection is empty
333
	 *
334
	 * @return a {@link java.lang.String} object.
335
	 */
336
	public abstract String getEmptyString();
337
	
338
	/**
339
	 * <p>getTooltipString</p>
340
	 *
341
	 * @return String to display when hovering the add button
342
	 */
343
	protected abstract String getTooltipString();	
344
}
(4-4/7)