1 package org
.argeo
.docbook
.ui
;
3 import static javax
.jcr
.Property
.JCR_TITLE
;
4 import static org
.argeo
.cms
.ui
.util
.CmsUiUtils
.fillWidth
;
6 import java
.util
.ArrayList
;
7 import java
.util
.Iterator
;
9 import java
.util
.Observer
;
11 import javax
.jcr
.Item
;
12 import javax
.jcr
.Node
;
13 import javax
.jcr
.NodeIterator
;
14 import javax
.jcr
.Property
;
15 import javax
.jcr
.RepositoryException
;
16 import javax
.jcr
.Session
;
17 import javax
.jcr
.nodetype
.NodeType
;
19 import org
.apache
.commons
.logging
.Log
;
20 import org
.apache
.commons
.logging
.LogFactory
;
21 import org
.argeo
.cms
.CmsException
;
22 import org
.argeo
.cms
.text
.Paragraph
;
23 import org
.argeo
.cms
.text
.SectionTitle
;
24 import org
.argeo
.cms
.text
.TextInterpreter
;
25 import org
.argeo
.cms
.text
.TextSection
;
26 import org
.argeo
.cms
.ui
.CmsEditable
;
27 import org
.argeo
.cms
.ui
.CmsImageManager
;
28 import org
.argeo
.cms
.ui
.CmsView
;
29 import org
.argeo
.cms
.ui
.util
.CmsUiUtils
;
30 import org
.argeo
.cms
.ui
.viewers
.AbstractPageViewer
;
31 import org
.argeo
.cms
.ui
.viewers
.EditablePart
;
32 import org
.argeo
.cms
.ui
.viewers
.NodePart
;
33 import org
.argeo
.cms
.ui
.viewers
.PropertyPart
;
34 import org
.argeo
.cms
.ui
.viewers
.Section
;
35 import org
.argeo
.cms
.ui
.viewers
.SectionPart
;
36 import org
.argeo
.cms
.ui
.widgets
.EditableImage
;
37 import org
.argeo
.cms
.ui
.widgets
.EditableText
;
38 import org
.argeo
.cms
.ui
.widgets
.Img
;
39 import org
.argeo
.cms
.ui
.widgets
.StyledControl
;
40 import org
.argeo
.jcr
.JcrUtils
;
41 import org
.eclipse
.rap
.fileupload
.FileDetails
;
42 import org
.eclipse
.rap
.fileupload
.FileUploadEvent
;
43 import org
.eclipse
.rap
.fileupload
.FileUploadHandler
;
44 import org
.eclipse
.rap
.fileupload
.FileUploadListener
;
45 import org
.eclipse
.rap
.rwt
.RWT
;
46 import org
.eclipse
.swt
.SWT
;
47 import org
.eclipse
.swt
.events
.KeyEvent
;
48 import org
.eclipse
.swt
.events
.KeyListener
;
49 import org
.eclipse
.swt
.events
.MouseAdapter
;
50 import org
.eclipse
.swt
.events
.MouseEvent
;
51 import org
.eclipse
.swt
.events
.MouseListener
;
52 import org
.eclipse
.swt
.graphics
.Point
;
53 import org
.eclipse
.swt
.widgets
.Composite
;
54 import org
.eclipse
.swt
.widgets
.Control
;
55 import org
.eclipse
.swt
.widgets
.Text
;
57 /** Base class for text viewers and editors. */
58 public abstract class AbstractDbkViewer
extends AbstractPageViewer
implements KeyListener
, Observer
{
59 private static final long serialVersionUID
= -2401274679492339668L;
60 private final static Log log
= LogFactory
.getLog(AbstractDbkViewer
.class);
62 private final Section mainSection
;
64 private TextInterpreter textInterpreter
= new DbkTextInterpreter();
65 private CmsImageManager imageManager
;
67 private FileUploadListener fileUploadListener
;
68 private DbkContextMenu styledTools
;
70 private final boolean flat
;
72 protected AbstractDbkViewer(Section parent
, int style
, CmsEditable cmsEditable
) {
73 super(parent
, style
, cmsEditable
);
74 CmsView cmsView
= CmsView
.getCmsView(parent
);
75 imageManager
= cmsView
.getImageManager();
76 flat
= SWT
.FLAT
== (style
& SWT
.FLAT
);
78 if (getCmsEditable().canEdit()) {
79 fileUploadListener
= new FUL();
80 styledTools
= new DbkContextMenu(this, parent
.getDisplay());
82 this.mainSection
= parent
;
83 initModelIfNeeded(mainSection
.getNode());
84 // layout(this.mainSection);
88 public Control
getControl() {
92 protected void refresh(Control control
) throws RepositoryException
{
93 if (!(control
instanceof Section
))
95 Section section
= (Section
) control
;
96 if (section
instanceof TextSection
) {
97 CmsUiUtils
.clear(section
);
98 Node node
= section
.getNode();
99 TextSection textSection
= (TextSection
) section
;
100 if (node
.hasProperty(Property
.JCR_TITLE
)) {
101 if (section
.getHeader() == null)
102 section
.createHeader();
103 if (node
.hasProperty(Property
.JCR_TITLE
)) {
104 SectionTitle title
= newSectionTitle(textSection
, node
);
105 title
.setLayoutData(CmsUiUtils
.fillWidth());
106 updateContent(title
);
110 for (NodeIterator ni
= node
.getNodes(DocBookNames
.DBK_PARA
); ni
.hasNext();) {
111 Node child
= ni
.nextNode();
112 final SectionPart sectionPart
;
113 if (child
.isNodeType(DocBookTypes
.IMAGEDATA
) || child
.isNodeType(NodeType
.NT_FILE
)) {
114 // FIXME adapt to DocBook
115 sectionPart
= newImg(textSection
, child
);
116 } else if (child
.isNodeType(DocBookTypes
.PARA
)) {
117 sectionPart
= newParagraph(textSection
, child
);
119 sectionPart
= newSectionPart(textSection
, child
);
120 if (sectionPart
== null)
121 throw new CmsException("Unsupported node " + child
);
122 // TODO list node types in exception
124 if (sectionPart
instanceof Control
)
125 ((Control
) sectionPart
).setLayoutData(CmsUiUtils
.fillWidth());
129 for (NodeIterator ni
= section
.getNode().getNodes(DocBookNames
.DBK_SECTION
); ni
.hasNext();) {
130 Node child
= ni
.nextNode();
131 if (child
.isNodeType(DocBookTypes
.SECTION
)) {
132 TextSection newSection
= new TextSection(section
, SWT
.NONE
, child
);
133 newSection
.setLayoutData(CmsUiUtils
.fillWidth());
138 for (Section s
: section
.getSubSections().values())
144 /** To be overridden in order to provide additional SectionPart types */
145 protected SectionPart
newSectionPart(TextSection textSection
, Node node
) {
150 protected Paragraph
newParagraph(TextSection parent
, Node node
) throws RepositoryException
{
151 Paragraph paragraph
= new Paragraph(parent
, parent
.getStyle(), node
);
152 updateContent(paragraph
);
153 paragraph
.setLayoutData(fillWidth());
154 paragraph
.setMouseListener(getMouseListener());
158 protected Img
newImg(TextSection parent
, Node node
) throws RepositoryException
{
159 Img img
= new Img(parent
, parent
.getStyle(), node
) {
160 private static final long serialVersionUID
= 1297900641952417540L;
163 protected void setContainerLayoutData(Composite composite
) {
164 composite
.setLayoutData(CmsUiUtils
.grabWidth(SWT
.CENTER
, SWT
.DEFAULT
));
168 protected void setControlLayoutData(Control control
) {
169 control
.setLayoutData(CmsUiUtils
.grabWidth(SWT
.CENTER
, SWT
.DEFAULT
));
172 img
.setLayoutData(CmsUiUtils
.grabWidth(SWT
.CENTER
, SWT
.DEFAULT
));
174 img
.setMouseListener(getMouseListener());
178 protected SectionTitle
newSectionTitle(TextSection parent
, Node node
) throws RepositoryException
{
179 SectionTitle title
= new SectionTitle(parent
.getHeader(), parent
.getStyle(), node
.getProperty(JCR_TITLE
));
180 updateContent(title
);
181 title
.setMouseListener(getMouseListener());
185 protected SectionTitle
prepareSectionTitle(Section newSection
, String titleText
) throws RepositoryException
{
186 Node sectionNode
= newSection
.getNode();
187 if (!sectionNode
.hasProperty(JCR_TITLE
))
188 sectionNode
.setProperty(Property
.JCR_TITLE
, "");
189 getTextInterpreter().write(sectionNode
.getProperty(Property
.JCR_TITLE
), titleText
);
190 if (newSection
.getHeader() == null)
191 newSection
.createHeader();
192 SectionTitle sectionTitle
= newSectionTitle((TextSection
) newSection
, sectionNode
);
196 protected void updateContent(EditablePart part
) throws RepositoryException
{
197 if (part
instanceof SectionPart
) {
198 SectionPart sectionPart
= (SectionPart
) part
;
199 Node partNode
= sectionPart
.getNode();
201 if (part
instanceof StyledControl
&& (sectionPart
.getSection() instanceof TextSection
)) {
202 TextSection section
= (TextSection
) sectionPart
.getSection();
203 StyledControl styledControl
= (StyledControl
) part
;
204 if (partNode
.isNodeType(DocBookTypes
.PARA
)) {
205 String style
= partNode
.hasProperty(DocBookNames
.DBK_ROLE
)
206 ? partNode
.getProperty(DocBookNames
.DBK_ROLE
).getString()
207 : section
.getDefaultTextStyle();
208 styledControl
.setStyle(style
);
211 // use control AFTER setting style, since it may have been reset
213 if (part
instanceof EditableText
) {
214 EditableText paragraph
= (EditableText
) part
;
215 if (paragraph
== getEdited())
216 paragraph
.setText(textInterpreter
.read(partNode
));
218 paragraph
.setText(textInterpreter
.raw(partNode
));
219 } else if (part
instanceof EditableImage
) {
220 EditableImage editableImage
= (EditableImage
) part
;
221 imageManager
.load(partNode
, part
.getControl(), editableImage
.getPreferredImageSize());
223 } else if (part
instanceof SectionTitle
) {
224 SectionTitle title
= (SectionTitle
) part
;
225 title
.setStyle(title
.getSection().getTitleStyle());
226 // use control AFTER setting style
227 if (title
== getEdited())
228 title
.setText(textInterpreter
.read(title
.getProperty()));
230 title
.setText(textInterpreter
.raw(title
.getProperty()));
234 // OVERRIDDEN FROM PARENT VIEWER
236 protected void save(EditablePart part
) throws RepositoryException
{
237 if (part
instanceof EditableText
) {
238 EditableText et
= (EditableText
) part
;
239 String text
= ((Text
) et
.getControl()).getText();
241 String
[] lines
= text
.split("[\r\n]+");
242 assert lines
.length
!= 0;
243 saveLine(part
, lines
[0]);
244 if (lines
.length
> 1) {
245 ArrayList
<Control
> toLayout
= new ArrayList
<Control
>();
246 if (part
instanceof Paragraph
) {
247 Paragraph currentParagraph
= (Paragraph
) et
;
248 Section section
= currentParagraph
.getSection();
249 Node sectionNode
= section
.getNode();
250 Node currentParagraphN
= currentParagraph
.getNode();
251 for (int i
= 1; i
< lines
.length
; i
++) {
252 Node newNode
= sectionNode
.addNode(DocBookNames
.DBK_PARA
, DocBookTypes
.PARA
);
253 // newNode.addMixin(CmsTypes.CMS_STYLED);
254 saveLine(newNode
, lines
[i
]);
255 // second node was create as last, if it is not the next
257 // means there are some in between and we can take the
259 // index+1 for the re-order
260 if (newNode
.getIndex() > currentParagraphN
.getIndex() + 1) {
261 sectionNode
.orderBefore(p(newNode
.getIndex()), p(currentParagraphN
.getIndex() + 1));
263 Paragraph newParagraph
= newParagraph((TextSection
) section
, newNode
);
264 newParagraph
.moveBelow(currentParagraph
);
265 toLayout
.add(newParagraph
);
267 currentParagraph
= newParagraph
;
268 currentParagraphN
= newNode
;
270 persistChanges(sectionNode
);
272 // TODO or rather return the created paragarphs?
273 layout(toLayout
.toArray(new Control
[toLayout
.size()]));
278 protected void saveLine(EditablePart part
, String line
) {
279 if (part
instanceof NodePart
) {
280 saveLine(((NodePart
) part
).getNode(), line
);
281 } else if (part
instanceof PropertyPart
) {
282 saveLine(((PropertyPart
) part
).getProperty(), line
);
284 throw new CmsException("Unsupported part " + part
);
288 protected void saveLine(Item item
, String line
) {
290 textInterpreter
.write(item
, line
);
294 protected void prepare(EditablePart part
, Object caretPosition
) {
295 Control control
= part
.getControl();
296 if (control
instanceof Text
) {
297 Text text
= (Text
) control
;
298 if (caretPosition
!= null)
299 if (caretPosition
instanceof Integer
)
300 text
.setSelection((Integer
) caretPosition
);
301 else if (caretPosition
instanceof Point
) {
302 // TODO find a way to position the caret at the right place
304 text
.setData(RWT
.ACTIVE_KEYS
, new String
[] { "BACKSPACE", "ESC", "TAB", "SHIFT+TAB", "ALT+ARROW_LEFT",
305 "ALT+ARROW_RIGHT", "ALT+ARROW_UP", "ALT+ARROW_DOWN", "RETURN", "CTRL+RETURN", "ENTER", "DELETE" });
306 text
.setData(RWT
.CANCEL_KEYS
, new String
[] { "RETURN", "ALT+ARROW_LEFT", "ALT+ARROW_RIGHT" });
307 text
.addKeyListener(this);
308 } else if (part
instanceof Img
) {
309 ((Img
) part
).setFileUploadListener(fileUploadListener
);
313 // REQUIRED BY CONTEXT MENU
314 void setParagraphStyle(Paragraph paragraph
, String style
) {
316 Node paragraphNode
= paragraph
.getNode();
317 paragraphNode
.setProperty(DocBookNames
.DBK_ROLE
, style
);
318 persistChanges(paragraphNode
);
319 updateContent(paragraph
);
321 } catch (RepositoryException e1
) {
322 throw new CmsException("Cannot set style " + style
+ " on " + paragraph
, e1
);
326 void deletePart(SectionPart paragraph
) {
328 Node paragraphNode
= paragraph
.getNode();
329 Section section
= paragraph
.getSection();
330 Session session
= paragraphNode
.getSession();
331 paragraphNode
.remove();
333 if (paragraph
instanceof Control
)
334 ((Control
) paragraph
).dispose();
336 } catch (RepositoryException e1
) {
337 throw new CmsException("Cannot delete " + paragraph
, e1
);
341 String
getRawParagraphText(Paragraph paragraph
) {
342 return textInterpreter
.raw(paragraph
.getNode());
346 protected void splitEdit() {
349 if (getEdited() instanceof Paragraph
) {
350 Paragraph paragraph
= (Paragraph
) getEdited();
351 Text text
= (Text
) paragraph
.getControl();
352 int caretPosition
= text
.getCaretPosition();
353 String txt
= text
.getText();
354 String first
= txt
.substring(0, caretPosition
);
355 String second
= txt
.substring(caretPosition
);
356 Node firstNode
= paragraph
.getNode();
357 Node sectionNode
= firstNode
.getParent();
359 // FIXME set content the DocBook way
360 // firstNode.setProperty(CMS_CONTENT, first);
361 Node secondNode
= sectionNode
.addNode(DocBookNames
.DBK_PARA
, DocBookTypes
.PARA
);
362 // secondNode.addMixin(CmsTypes.CMS_STYLED);
364 // second node was create as last, if it is not the next one, it
365 // means there are some in between and we can take the one at
366 // index+1 for the re-order
367 if (secondNode
.getIndex() > firstNode
.getIndex() + 1) {
368 sectionNode
.orderBefore(p(secondNode
.getIndex()), p(firstNode
.getIndex() + 1));
371 // if we die in between, at least we still have the whole text
374 textInterpreter
.write(secondNode
, second
);
375 textInterpreter
.write(firstNode
, first
);
376 } catch (Exception e
) {
377 // so that no additional nodes are created:
378 JcrUtils
.discardUnderlyingSessionQuietly(firstNode
);
382 persistChanges(firstNode
);
384 Paragraph secondParagraph
= paragraphSplitted(paragraph
, secondNode
);
385 edit(secondParagraph
, 0);
386 } else if (getEdited() instanceof SectionTitle
) {
387 SectionTitle sectionTitle
= (SectionTitle
) getEdited();
388 Text text
= (Text
) sectionTitle
.getControl();
389 String txt
= text
.getText();
390 int caretPosition
= text
.getCaretPosition();
391 Section section
= sectionTitle
.getSection();
392 Node sectionNode
= section
.getNode();
393 Node paragraphNode
= sectionNode
.addNode(DocBookNames
.DBK_PARA
, DocBookTypes
.PARA
);
394 // paragraphNode.addMixin(CmsTypes.CMS_STYLED);
396 textInterpreter
.write(paragraphNode
, txt
.substring(caretPosition
));
397 textInterpreter
.write(sectionNode
.getProperty(Property
.JCR_TITLE
), txt
.substring(0, caretPosition
));
398 sectionNode
.orderBefore(p(paragraphNode
.getIndex()), p(1));
399 persistChanges(sectionNode
);
401 Paragraph paragraph
= sectionTitleSplitted(sectionTitle
, paragraphNode
);
405 } catch (RepositoryException e
) {
406 throw new CmsException("Cannot split " + getEdited(), e
);
410 protected void mergeWithPrevious() {
413 Paragraph paragraph
= (Paragraph
) getEdited();
414 Text text
= (Text
) paragraph
.getControl();
415 String txt
= text
.getText();
416 Node paragraphNode
= paragraph
.getNode();
417 if (paragraphNode
.getIndex() == 1)
419 Node sectionNode
= paragraphNode
.getParent();
420 Node previousNode
= sectionNode
.getNode(p(paragraphNode
.getIndex() - 1));
421 String previousTxt
= textInterpreter
.read(previousNode
);
422 textInterpreter
.write(previousNode
, previousTxt
+ txt
);
423 paragraphNode
.remove();
424 persistChanges(sectionNode
);
426 Paragraph previousParagraph
= paragraphMergedWithPrevious(paragraph
, previousNode
);
427 edit(previousParagraph
, previousTxt
.length());
428 } catch (RepositoryException e
) {
429 throw new CmsException("Cannot stop editing", e
);
433 protected void mergeWithNext() {
436 Paragraph paragraph
= (Paragraph
) getEdited();
437 Text text
= (Text
) paragraph
.getControl();
438 String txt
= text
.getText();
439 Node paragraphNode
= paragraph
.getNode();
440 Node sectionNode
= paragraphNode
.getParent();
441 NodeIterator paragraphNodes
= sectionNode
.getNodes(DocBookNames
.DBK_PARA
);
442 long size
= paragraphNodes
.getSize();
443 if (paragraphNode
.getIndex() == size
)
445 Node nextNode
= sectionNode
.getNode(p(paragraphNode
.getIndex() + 1));
446 String nextTxt
= textInterpreter
.read(nextNode
);
447 textInterpreter
.write(paragraphNode
, txt
+ nextTxt
);
449 Section section
= paragraph
.getSection();
450 Paragraph removed
= (Paragraph
) section
.getSectionPart(nextNode
.getIdentifier());
453 persistChanges(sectionNode
);
455 paragraphMergedWithNext(paragraph
, removed
);
456 edit(paragraph
, txt
.length());
457 } catch (RepositoryException e
) {
458 throw new CmsException("Cannot stop editing", e
);
462 protected synchronized void upload(EditablePart part
) {
464 if (part
instanceof SectionPart
) {
465 SectionPart sectionPart
= (SectionPart
) part
;
466 Node partNode
= sectionPart
.getNode();
467 int partIndex
= partNode
.getIndex();
468 Section section
= sectionPart
.getSection();
469 Node sectionNode
= section
.getNode();
471 if (part
instanceof Paragraph
) {
472 // FIXME adapt to DocBook
473 Node newNode
= sectionNode
.addNode(DocBookNames
.DBK_MEDIAOBJECT
, NodeType
.NT_FILE
);
474 newNode
.addNode(Node
.JCR_CONTENT
, NodeType
.NT_RESOURCE
);
475 JcrUtils
.copyBytesAsFile(sectionNode
, p(newNode
.getIndex()), new byte[0]);
476 if (partIndex
< newNode
.getIndex() - 1) {
478 sectionNode
.orderBefore(p(newNode
.getIndex()), p(partIndex
- 1));
480 // sectionNode.orderBefore(p(partNode.getIndex()),
481 // p(newNode.getIndex()));
482 persistChanges(sectionNode
);
483 Img img
= newImg((TextSection
) section
, newNode
);
485 layout(img
.getControl());
486 } else if (part
instanceof Img
) {
487 if (getEdited() == part
)
490 layout(part
.getControl());
493 } catch (RepositoryException e
) {
494 throw new CmsException("Cannot upload", e
);
498 protected void deepen() {
503 if (getEdited() instanceof Paragraph
) {
504 Paragraph paragraph
= (Paragraph
) getEdited();
505 Text text
= (Text
) paragraph
.getControl();
506 String txt
= text
.getText();
507 Node paragraphNode
= paragraph
.getNode();
508 Section section
= paragraph
.getSection();
509 Node sectionNode
= section
.getNode();
511 if (section
== mainSection
&& section
instanceof TextSection
&& paragraphNode
.getIndex() == 1
512 && !sectionNode
.hasProperty(JCR_TITLE
)) {
513 SectionTitle sectionTitle
= prepareSectionTitle(section
, txt
);
514 edit(sectionTitle
, 0);
517 Node newSectionNode
= sectionNode
.addNode(DocBookNames
.DBK_SECTION
, DocBookTypes
.SECTION
);
518 newSectionNode
.addMixin(NodeType
.MIX_TITLE
);
519 sectionNode
.orderBefore(h(newSectionNode
.getIndex()), h(1));
521 int paragraphIndex
= paragraphNode
.getIndex();
522 String sectionPath
= sectionNode
.getPath();
523 String newSectionPath
= newSectionNode
.getPath();
524 while (sectionNode
.hasNode(p(paragraphIndex
+ 1))) {
525 Node parag
= sectionNode
.getNode(p(paragraphIndex
+ 1));
526 sectionNode
.getSession().move(sectionPath
+ '/' + p(paragraphIndex
+ 1),
527 newSectionPath
+ '/' + DocBookNames
.DBK_PARA
);
528 SectionPart sp
= section
.getSectionPart(parag
.getIdentifier());
529 if (sp
instanceof Control
)
530 ((Control
) sp
).dispose();
533 newSectionNode
.setProperty(Property
.JCR_TITLE
, "");
534 getTextInterpreter().write(newSectionNode
.getProperty(Property
.JCR_TITLE
), txt
);
536 TextSection newSection
= new TextSection(section
, section
.getStyle(), newSectionNode
);
537 newSection
.setLayoutData(CmsUiUtils
.fillWidth());
538 newSection
.moveBelow(paragraph
);
541 paragraphNode
.remove();
545 newSection
.getParent().layout();
547 persistChanges(sectionNode
);
548 } else if (getEdited() instanceof SectionTitle
) {
549 SectionTitle sectionTitle
= (SectionTitle
) getEdited();
550 Section section
= sectionTitle
.getSection();
551 Section parentSection
= section
.getParentSection();
552 if (parentSection
== null)
553 return;// cannot deepen main section
554 Node sectionN
= section
.getNode();
555 Node parentSectionN
= parentSection
.getNode();
556 if (sectionN
.getIndex() == 1)
557 return;// cannot deepen first section
558 Node previousSectionN
= parentSectionN
.getNode(h(sectionN
.getIndex() - 1));
559 NodeIterator subSections
= previousSectionN
.getNodes(DocBookNames
.DBK_SECTION
);
560 int subsectionsCount
= (int) subSections
.getSize();
561 previousSectionN
.getSession().move(sectionN
.getPath(),
562 previousSectionN
.getPath() + "/" + h(subsectionsCount
+ 1));
564 TextSection newSection
= new TextSection(section
, section
.getStyle(), sectionN
);
566 persistChanges(previousSectionN
);
568 } catch (RepositoryException e
) {
569 throw new CmsException("Cannot deepen " + getEdited(), e
);
573 protected void undeepen() {
578 if (getEdited() instanceof Paragraph
) {
580 } else if (getEdited() instanceof SectionTitle
) {
581 SectionTitle sectionTitle
= (SectionTitle
) getEdited();
582 Section section
= sectionTitle
.getSection();
583 Node sectionNode
= section
.getNode();
584 Section parentSection
= section
.getParentSection();
585 if (parentSection
== null)
586 return;// cannot undeepen main section
588 // choose in which section to merge
589 Section mergedSection
;
590 if (sectionNode
.getIndex() == 1)
591 mergedSection
= section
.getParentSection();
593 Map
<String
, Section
> parentSubsections
= parentSection
.getSubSections();
594 ArrayList
<Section
> lst
= new ArrayList
<Section
>(parentSubsections
.values());
595 mergedSection
= lst
.get(sectionNode
.getIndex() - 1);
597 Node mergedNode
= mergedSection
.getNode();
598 boolean mergedHasSubSections
= mergedNode
.hasNode(DocBookNames
.DBK_SECTION
);
600 // title as paragraph
601 Node newParagrapheNode
= mergedNode
.addNode(DocBookNames
.DBK_PARA
, DocBookTypes
.PARA
);
602 // newParagrapheNode.addMixin(CmsTypes.CMS_STYLED);
603 if (mergedHasSubSections
)
604 mergedNode
.orderBefore(p(newParagrapheNode
.getIndex()), h(1));
605 String txt
= getTextInterpreter().read(sectionNode
.getProperty(Property
.JCR_TITLE
));
606 getTextInterpreter().write(newParagrapheNode
, txt
);
608 NodeIterator paragraphs
= sectionNode
.getNodes(DocBookNames
.DBK_PARA
);
609 while (paragraphs
.hasNext()) {
610 Node p
= paragraphs
.nextNode();
611 SectionPart sp
= section
.getSectionPart(p
.getIdentifier());
612 if (sp
instanceof Control
)
613 ((Control
) sp
).dispose();
614 mergedNode
.getSession().move(p
.getPath(), mergedNode
.getPath() + '/' + DocBookNames
.DBK_PARA
);
615 if (mergedHasSubSections
)
616 mergedNode
.orderBefore(p(p
.getIndex()), h(1));
619 Iterator
<Section
> subsections
= section
.getSubSections().values().iterator();
620 // NodeIterator sections = sectionNode.getNodes(CMS_H);
621 while (subsections
.hasNext()) {
622 Section subsection
= subsections
.next();
623 Node s
= subsection
.getNode();
624 mergedNode
.getSession().move(s
.getPath(), mergedNode
.getPath() + '/' + DocBookNames
.DBK_SECTION
);
625 subsection
.dispose();
629 section
.getNode().remove();
632 refresh(mergedSection
);
633 mergedSection
.getParent().layout();
634 layout(mergedSection
);
635 persistChanges(mergedNode
);
637 } catch (RepositoryException e
) {
638 throw new CmsException("Cannot undeepen " + getEdited(), e
);
643 protected Paragraph
paragraphSplitted(Paragraph paragraph
, Node newNode
) throws RepositoryException
{
644 Section section
= paragraph
.getSection();
645 updateContent(paragraph
);
646 Paragraph newParagraph
= newParagraph((TextSection
) section
, newNode
);
647 newParagraph
.setLayoutData(CmsUiUtils
.fillWidth());
648 newParagraph
.moveBelow(paragraph
);
649 layout(paragraph
.getControl(), newParagraph
.getControl());
653 protected Paragraph
sectionTitleSplitted(SectionTitle sectionTitle
, Node newNode
) throws RepositoryException
{
654 updateContent(sectionTitle
);
655 Paragraph newParagraph
= newParagraph(sectionTitle
.getSection(), newNode
);
656 // we assume beforeFirst is not null since there was a sectionTitle
657 newParagraph
.moveBelow(sectionTitle
.getSection().getHeader());
658 layout(sectionTitle
.getControl(), newParagraph
.getControl());
662 protected Paragraph
paragraphMergedWithPrevious(Paragraph removed
, Node remaining
) throws RepositoryException
{
663 Section section
= removed
.getSection();
666 Paragraph paragraph
= (Paragraph
) section
.getSectionPart(remaining
.getIdentifier());
667 updateContent(paragraph
);
668 layout(paragraph
.getControl());
672 protected void paragraphMergedWithNext(Paragraph remaining
, Paragraph removed
) throws RepositoryException
{
674 updateContent(remaining
);
675 layout(remaining
.getControl());
679 protected String
p(Integer index
) {
680 StringBuilder sb
= new StringBuilder(6);
681 sb
.append(DocBookNames
.DBK_PARA
).append('[').append(index
).append(']');
682 return sb
.toString();
685 protected String
h(Integer index
) {
686 StringBuilder sb
= new StringBuilder(5);
687 sb
.append(DocBookNames
.DBK_SECTION
).append('[').append(index
).append(']');
688 return sb
.toString();
692 public Section
getMainSection() {
696 public boolean isFlat() {
700 public TextInterpreter
getTextInterpreter() {
701 return textInterpreter
;
706 public void keyPressed(KeyEvent ke
) {
707 if (log
.isTraceEnabled())
710 if (getEdited() == null)
712 boolean altPressed
= (ke
.stateMask
& SWT
.ALT
) != 0;
713 boolean shiftPressed
= (ke
.stateMask
& SWT
.SHIFT
) != 0;
714 boolean ctrlPressed
= (ke
.stateMask
& SWT
.CTRL
) != 0;
718 if (ke
.keyCode
== SWT
.ESC
) {
720 } else if (ke
.character
== '\r') {
722 } else if (ke
.character
== 'S') {
725 } else if (ke
.character
== '\t') {
728 } else if (shiftPressed
) {
732 if (getEdited() instanceof Paragraph
) {
733 Paragraph paragraph
= (Paragraph
) getEdited();
734 Section section
= paragraph
.getSection();
735 if (altPressed
&& ke
.keyCode
== SWT
.ARROW_RIGHT
) {
736 edit(section
.nextSectionPart(paragraph
), 0);
737 } else if (altPressed
&& ke
.keyCode
== SWT
.ARROW_LEFT
) {
738 edit(section
.previousSectionPart(paragraph
), 0);
739 } else if (ke
.character
== SWT
.BS
) {
740 Text text
= (Text
) paragraph
.getControl();
741 int caretPosition
= text
.getCaretPosition();
742 if (caretPosition
== 0) {
745 } else if (ke
.character
== SWT
.DEL
) {
746 Text text
= (Text
) paragraph
.getControl();
747 int caretPosition
= text
.getCaretPosition();
748 int charcount
= text
.getCharCount();
749 if (caretPosition
== charcount
) {
755 } catch (Exception e
) {
757 notifyEditionException(e
);
762 public void keyReleased(KeyEvent e
) {
767 protected MouseListener
createMouseListener() {
771 private class ML
extends MouseAdapter
{
772 private static final long serialVersionUID
= 8526890859876770905L;
775 public void mouseDoubleClick(MouseEvent e
) {
777 Control source
= (Control
) e
.getSource();
778 if (getCmsEditable().canEdit()) {
779 if (getCmsEditable().isEditing() && !(getEdited() instanceof Img
)) {
780 if (source
== mainSection
)
782 EditablePart part
= findDataParent(source
);
785 getCmsEditable().startEditing();
792 public void mouseDown(MouseEvent e
) {
793 if (getCmsEditable().isEditing()) {
795 Control source
= (Control
) e
.getSource();
796 EditablePart composite
= findDataParent(source
);
797 Point point
= new Point(e
.x
, e
.y
);
798 if (!(composite
instanceof Img
))
799 edit(composite
, source
.toDisplay(point
));
800 } else if (e
.button
== 3) {
801 EditablePart composite
= findDataParent((Control
) e
.getSource());
802 if (styledTools
!= null)
803 styledTools
.show(composite
, new Point(e
.x
, e
.y
));
809 public void mouseUp(MouseEvent e
) {
813 // FILE UPLOAD LISTENER
814 private class FUL
implements FileUploadListener
{
815 public void uploadProgress(FileUploadEvent event
) {
816 // TODO Monitor upload progress
819 public void uploadFailed(FileUploadEvent event
) {
820 throw new CmsException("Upload failed " + event
, event
.getException());
823 public void uploadFinished(FileUploadEvent event
) {
824 for (FileDetails file
: event
.getFileDetails()) {
825 if (log
.isDebugEnabled())
826 log
.debug("Received: " + file
.getFileName());
828 mainSection
.getDisplay().syncExec(new Runnable() {
834 FileUploadHandler uploadHandler
= (FileUploadHandler
) event
.getSource();
835 uploadHandler
.dispose();