Project

General

Profile

Download (9.76 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
    private static final EnumSet<CRUD> UPDATE = EnumSet.of(CRUD.UPDATE);
59

    
60
    protected Composite container;
61

    
62
	private Label label_empty;
63

    
64
	private String title;
65

    
66
    private AbstractEntityCollectionElement entityCollectionElement;
67

    
68
	public AbstractEntityCollectionSection(CdmFormFactory formFactory, ConversationHolder conversation, ICdmFormElement parentElement, String title, int style) {
69
		super(formFactory, parentElement, ExpandableComposite.CLIENT_INDENT | style);
70
		this.title = title;
71
		this.setText(getTitleString());
72
		updateToolbar();
73

    
74
		addExpansionListener(this);
75

    
76
		CdmStore.getLoginManager().addObserver(this);
77
		addDisposeListener(new DisposeListener() {
78
            @Override
79
            public void widgetDisposed(DisposeEvent e) {
80
                CdmStore.getLoginManager().deleteObserver(AbstractEntityCollectionSection.this);
81
            }
82
        });
83
	}
84

    
85
	protected Control createToolbar() {
86
		ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
87

    
88
		Action addAction = new Action("add", IAction.AS_PUSH_BUTTON){
89
			@Override
90
			public void run() {
91
				ELEMENT element = createNewElement();
92
				if(element != null){
93
					addElement(element);
94
					if(! getSection().isExpanded()) {
95
                        getSection().setExpanded(true);
96
                    }
97
					internalUpdateSection(true);
98
				}
99
			}
100
		};
101
		addAction.setImageDescriptor(new ImageDescriptor() {
102

    
103
			@Override
104
			public ImageData getImageData() {
105
				return ImageResources.getImage(ImageResources.ADD_ICON).getImageData();
106
			}
107
		});
108
		addAction.setToolTipText(getTooltipString());
109

    
110
		toolBarManager.add(addAction);
111

    
112
		return toolBarManager.createControl(this);
113
	}
114

    
115
	/**
116
	 * using this method is discouraged, use updateToolBar() instead
117
	 */
118
	public void showToolbar(){
119
		setTextClient(createToolbar());
120
	}
121

    
122
    /**
123
     * using this method is discouraged, use updateToolBar() instead
124
     */
125
	public void removeToolbar(){
126
		setTextClient(null);
127
	}
128

    
129
	@Override
130
	public void setEntity(ENTITY entity) {
131
		if(entity != null){
132
			super.setEntity(entity);
133
			internalUpdateSection(false);
134
		}
135
		setSectionTitle();
136
		updateToolbar();
137
		layout();
138
	}
139

    
140
	/**
141
	 * Sets the title for the section. Adds a "+" sign if the collection is not empty for this section.
142
	 * Override in subclasses if you want to have a different behaviour.
143
	 */
144
	protected void setSectionTitle() {
145
		Collection<ELEMENT> collection = getCollection(getEntity());
146
		if(collection != null && collection.size() > 0){
147
			this.setText(getTitleString() + " +");
148
		}else{
149
			this.setText(getTitleString());
150
		}
151
	}
152

    
153
	/**
154
	 * Removes all content from the container
155
	 */
156
	private void destroyDynamicContent(){
157
		if(label_empty != null){
158
			label_empty.dispose();
159
			label_empty = null;
160
		}
161
		removeElements();
162
	}
163

    
164
	/**
165
	 * Call this method after dynamically changing the client area.
166
	 * If the options changed is set to <code>true</code>, will also fire a state changed
167
	 * event to inform the user of unsaved changes.
168
	 *
169
	 * @param changed a boolean.
170
	 */
171
	protected void internalUpdateSection(boolean changed){
172
	    setSectionTitle();
173
		destroyDynamicContent();
174
		if(isExpanded() || expandSectionWhenContentAvailable()) {
175
            renderContent(isExpanded());
176
        }
177
		if(changed) {
178
            firePropertyChangeEvent(this);
179
        }
180
	}
181

    
182
	/**
183
	 * Create the elements to be shown in this section client area
184
	 */
185
	private void renderContent(boolean forceExpansion)
186
	{
187
		Collection<ELEMENT> elements = getCollection(getEntity());
188

    
189
		if(elements == null || elements.isEmpty()){
190
			createEmptyContent();
191
		}else{
192
			createDynamicContents(elements);
193
			forceExpansion = true;
194
		}
195

    
196
		this.setExpanded(forceExpansion);
197

    
198
		reflow();
199
	}
200

    
201
	protected void createEmptyContent(){
202
		label_empty = formFactory.createLabel(getLayoutComposite(), getEmptyString());
203
	}
204

    
205
	/**
206
	 * Creates the widgets for the collection
207
	 *
208
	 * @param elements a {@link java.util.Collection} object.
209
	 */
210
	protected void createDynamicContents(Collection<ELEMENT> elements)
211
	{
212
		int i = 0;
213
		for(final ELEMENT element : elements){
214
			SelectionAdapter removeListener = new SelectionAdapter(){
215
				@Override
216
				public void widgetSelected(SelectionEvent e) {
217
					removeElement(element);
218
					internalUpdateSection(true);
219
				}
220
			};
221
			boolean modulo = i++%2 == 0;
222
			String colorResource = modulo ? Resources.COLOR_LIST_EVEN : Resources.COLOR_LIST_ODD;
223
			createElementComposite(element, removeListener, AbstractUtility.getColor(colorResource));
224
		}
225
	}
226

    
227
	/**
228
	 * Create the specific widget for the element
229
	 *
230
	 * @param element a ELEMENT object.
231
	 * @param removeListener a {@link org.eclipse.swt.events.SelectionListener} object.
232
	 * @param backgroundColor a {@link org.eclipse.swt.graphics.Color} object.
233
	 */
234
	protected void createElementComposite(ELEMENT element, SelectionListener removeListener, Color backgroundColor){
235
		entityCollectionElement = formFactory.createEntityCollectionElement(this, element, removeListener, backgroundColor, SWT.NULL);
236
	}
237

    
238
	/** {@inheritDoc} */
239
	@Override
240
	public void setBackground(Color color) {
241
		if(label_empty != null && !label_empty.isDisposed()){
242
			label_empty.setBackground(color);
243
		}
244
		super.setBackground(color);
245
	}
246

    
247
	/**
248
	 * <p>getTitleString</p>
249
	 *
250
	 * @return a {@link java.lang.String} object.
251
	 */
252
	public String getTitleString() {
253
		return CdmUtils.Nz(title);
254
	}
255

    
256
	/**
257
	 * <p>setTitleString</p>
258
	 *
259
	 * @param title a {@link java.lang.String} object.
260
	 */
261
	public void setTitleString(String title){
262
		this.title = title;
263
		setSectionTitle();
264
		layout();
265
	}
266

    
267
	/** {@inheritDoc} */
268
	@Override
269
    public void expansionStateChanging(ExpansionEvent e) {
270
//		logger.warn("Expansion State Changing");
271
	}
272

    
273
	/** {@inheritDoc} */
274
	@Override
275
    public void expansionStateChanged(ExpansionEvent e) {
276
		if(isExpanded()){
277
			renderContent(isExpanded());
278
		}else{
279
			destroyDynamicContent();
280
		}
281
	}
282

    
283
	private boolean expandSectionWhenContentAvailable(){
284
		return PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOULD_EXPAND_SECTION_WHEN_DATA_AVAILABLE);
285
	}
286

    
287
	/**
288
	 * Remove an element from the entities collection and update the section
289
	 *
290
	 * @param element a ELEMENT object.
291
	 */
292
	public void removeElementAndUpdate(ELEMENT element) {
293
		removeElement(element);
294
		internalUpdateSection(true);
295
	}
296

    
297
	@Override
298
    public void update(Observable o, Object arg){
299
	    if(o instanceof LoginManager){
300
	        updateToolbar();
301
	    }
302
	}
303

    
304
    private void updateToolbar() {
305
        if(getEntity() != null && CdmStore.currentAuthentiationHasPermission(StoreUtil.getCdmEntity(getEntity()), UPDATE)){
306
            showToolbar();
307
        } else {
308
            removeToolbar();
309
        }
310
    }
311

    
312
    public AbstractEntityCollectionElement getEntityCollectionElement() {
313
        return entityCollectionElement;
314
    }
315

    
316
	/**
317
	 * Get the specific collection of this entity
318
	 *
319
	 * @param entity a ENTITY object.
320
	 * @return a {@link java.util.Collection} object.
321
	 */
322
	public abstract Collection<ELEMENT> getCollection(ENTITY entity);
323

    
324
	/**
325
	 * Create a new Element for this collection
326
	 *
327
	 * @return a ELEMENT object.
328
	 */
329
	public abstract ELEMENT createNewElement();
330

    
331
	/**
332
	 * Add an element to the entities collection
333
	 *
334
	 * @param element a ELEMENT object.
335
	 */
336
	public abstract void addElement(ELEMENT element);
337

    
338
	/**
339
	 * Remove an element from the entities collection
340
	 *
341
	 * @param element a ELEMENT object.
342
	 */
343
	public abstract void removeElement(ELEMENT element);
344

    
345
	/**
346
	 * String to display when the collection is empty
347
	 *
348
	 * @return a {@link java.lang.String} object.
349
	 */
350
	public abstract String getEmptyString();
351

    
352
	/**
353
	 * <p>getTooltipString</p>
354
	 *
355
	 * @return String to display when hovering the add button
356
	 */
357
	protected abstract String getTooltipString();
358
}
(4-4/8)