]> git.argeo.org Git - lgpl/argeo-commons.git/blob - AbstractPageViewer.java
331275c44dd3484dbd8e0bd071bfc7e08109fa58
[lgpl/argeo-commons.git] / AbstractPageViewer.java
1 package org.argeo.cms.viewers;
2
3 import java.util.Observable;
4 import java.util.Observer;
5
6 import javax.jcr.Node;
7 import javax.jcr.RepositoryException;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.argeo.cms.CmsEditable;
12 import org.argeo.cms.CmsException;
13 import org.argeo.cms.widgets.ScrolledPage;
14 import org.eclipse.jface.viewers.ContentViewer;
15 import org.eclipse.jface.viewers.ISelection;
16 import org.eclipse.jface.viewers.StructuredSelection;
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.events.MouseAdapter;
19 import org.eclipse.swt.events.MouseListener;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Widget;
23
24 /** Base class for viewers related to a page */
25 public abstract class AbstractPageViewer extends ContentViewer implements
26 Observer {
27 private static final long serialVersionUID = 5438688173410341485L;
28
29 private final static Log log = LogFactory.getLog(AbstractPageViewer.class);
30
31 private final boolean readOnly;
32 /** The basis for the layouts, typically a ScrolledPage. */
33 private final Composite page;
34 private final CmsEditable cmsEditable;
35
36 private MouseListener mouseListener;
37
38 private EditablePart edited;
39 private ISelection selection = StructuredSelection.EMPTY;
40
41 // FIXME Added by BSinou to manage non-section Composite.
42 // Is it the correct method?
43 protected AbstractPageViewer(Composite parent, int style,
44 CmsEditable cmsEditable) {
45 // read only at UI level
46 readOnly = SWT.READ_ONLY == (style & SWT.READ_ONLY);
47
48 this.cmsEditable = cmsEditable == null ? CmsEditable.NON_EDITABLE
49 : cmsEditable;
50 if (this.cmsEditable instanceof Observable)
51 ((Observable) this.cmsEditable).addObserver(this);
52
53 if (cmsEditable.canEdit()) {
54 mouseListener = createMouseListener();
55 }
56 page = findPage(parent);
57 }
58
59 protected AbstractPageViewer(Section parent, int style,
60 CmsEditable cmsEditable) {
61 // read only at UI level
62 readOnly = SWT.READ_ONLY == (style & SWT.READ_ONLY);
63
64 this.cmsEditable = cmsEditable == null ? CmsEditable.NON_EDITABLE
65 : cmsEditable;
66 if (this.cmsEditable instanceof Observable)
67 ((Observable) this.cmsEditable).addObserver(this);
68
69 if (cmsEditable.canEdit()) {
70 mouseListener = createMouseListener();
71 }
72 page = findPage(parent);
73 }
74
75 /**
76 * Can be called to simplify the called to isModelInitialized() and
77 * initModel()
78 */
79 protected void initModelIfNeeded(Node node) {
80 try {
81 if (!isModelInitialized(node))
82 if (getCmsEditable().canEdit()) {
83 initModel(node);
84 node.getSession().save();
85 }
86 } catch (Exception e) {
87 throw new CmsException("Cannot initialize model", e);
88 }
89 }
90
91 /** Called if user can edit and model is not initialized */
92 protected Boolean isModelInitialized(Node node) throws RepositoryException {
93 return true;
94 }
95
96 /** Called if user can edit and model is not initialized */
97 protected void initModel(Node node) throws RepositoryException {
98 }
99
100 /** Create (retrieve) the MouseListener to use. */
101 protected MouseListener createMouseListener() {
102 return new MouseAdapter() {
103 private static final long serialVersionUID = 1L;
104 };
105 }
106
107 protected Composite findPage(Composite composite) {
108 if (composite instanceof ScrolledPage) {
109 return (ScrolledPage) composite;
110 } else {
111 if (composite.getParent() == null)
112 return composite;
113 return findPage(composite.getParent());
114 }
115 }
116
117 @Override
118 public void update(Observable o, Object arg) {
119 if (o == cmsEditable)
120 editingStateChanged(cmsEditable);
121 }
122
123 /** To be overridden in order to provide the actual refresh */
124 protected void refresh(Control control) throws RepositoryException {
125 }
126
127 /** To be overridden.Save the edited part. */
128 protected void save(EditablePart part) throws RepositoryException {
129 }
130
131 /** Prepare the edited part */
132 protected void prepare(EditablePart part, Object caretPosition) {
133 }
134
135 /** Notified when the editing state changed. Does nothing, to be overridden */
136 protected void editingStateChanged(CmsEditable cmsEditable) {
137 }
138
139 @Override
140 public void refresh() {
141 try {
142 if (cmsEditable.canEdit() && !readOnly)
143 mouseListener = createMouseListener();
144 else
145 mouseListener = null;
146 refresh(getControl());
147 layout(getControl());
148 } catch (RepositoryException e) {
149 throw new CmsException("Cannot refresh", e);
150 }
151 }
152
153 @Override
154 public void setSelection(ISelection selection, boolean reveal) {
155 this.selection = selection;
156 }
157
158 protected void updateContent(EditablePart part) throws RepositoryException {
159 }
160
161 // LOW LEVEL EDITION
162 protected void edit(EditablePart part, Object caretPosition) {
163 try {
164 if (edited == part)
165 return;
166
167 if (edited != null && edited != part)
168 stopEditing(true);
169
170 part.startEditing();
171 updateContent(part);
172 prepare(part, caretPosition);
173 edited = part;
174 layout(part.getControl());
175 } catch (RepositoryException e) {
176 throw new CmsException("Cannot edit " + part, e);
177 }
178 }
179
180 private void stopEditing(Boolean save) throws RepositoryException {
181 if (edited instanceof Widget && ((Widget) edited).isDisposed()) {
182 edited = null;
183 return;
184 }
185
186 assert edited != null;
187 if (edited == null) {
188 if (log.isTraceEnabled())
189 log.warn("Told to stop editing while not editing anything");
190 return;
191 }
192
193 if (save)
194 save(edited);
195
196 edited.stopEditing();
197 updateContent(edited);
198 layout(((EditablePart) edited).getControl());
199 edited = null;
200 }
201
202 // METHODS AVAILABLE TO EXTENDING CLASSES
203 protected void saveEdit() {
204 try {
205 if (edited != null)
206 stopEditing(true);
207 } catch (RepositoryException e) {
208 throw new CmsException("Cannot stop editing", e);
209 }
210 }
211
212 protected void cancelEdit() {
213 try {
214 if (edited != null)
215 stopEditing(false);
216 } catch (RepositoryException e) {
217 throw new CmsException("Cannot cancel editing", e);
218 }
219 }
220
221 /** Layout this controls from the related base page. */
222 public void layout(Control... controls) {
223 page.layout(controls);
224 }
225
226 // UTILITIES
227 /** Check whether the edited part is in a proper state */
228 protected void checkEdited() {
229 if (edited == null || (edited instanceof Widget)
230 && ((Widget) edited).isDisposed())
231 throw new CmsException(
232 "Edited should not be null or disposed at this stage");
233 }
234
235 // GETTERS / SETTERS
236 public boolean isReadOnly() {
237 return readOnly;
238 }
239
240 protected EditablePart getEdited() {
241 return edited;
242 }
243
244 public MouseListener getMouseListener() {
245 return mouseListener;
246 }
247
248 public CmsEditable getCmsEditable() {
249 return cmsEditable;
250 }
251
252 @Override
253 public ISelection getSelection() {
254 return selection;
255 }
256
257 }