1 package org
.argeo
.app
.swt
.docbook
;
3 import static org
.argeo
.app
.docbook
.DbkAcrUtils
.isDbk
;
4 import static org
.argeo
.app
.docbook
.DbkType
.para
;
6 import java
.util
.Optional
;
8 import org
.argeo
.api
.acr
.Content
;
9 import org
.argeo
.api
.cms
.ux
.Cms2DSize
;
10 import org
.argeo
.api
.cms
.ux
.CmsEditable
;
11 import org
.argeo
.app
.docbook
.DbkAttr
;
12 import org
.argeo
.app
.docbook
.DbkType
;
13 import org
.argeo
.cms
.swt
.CmsSwtUtils
;
14 import org
.argeo
.cms
.swt
.SwtEditablePart
;
15 import org
.argeo
.cms
.swt
.acr
.AbstractPageViewer
;
16 import org
.argeo
.cms
.swt
.acr
.SwtSection
;
17 import org
.argeo
.cms
.swt
.acr
.SwtSectionPart
;
18 import org
.argeo
.cms
.swt
.widgets
.EditableText
;
19 import org
.argeo
.cms
.swt
.widgets
.StyledControl
;
20 import org
.eclipse
.swt
.SWT
;
21 import org
.eclipse
.swt
.layout
.GridData
;
22 import org
.eclipse
.swt
.widgets
.Composite
;
23 import org
.eclipse
.swt
.widgets
.Control
;
25 public class DocBookViewer
extends AbstractPageViewer
{
27 private TextInterpreter textInterpreter
= new DbkTextInterpreter();
28 private DbkImageManager imageManager
;
30 private TextSection mainSection
;
32 private boolean showMainTitle
= true;
34 private Integer maxMediaWidth
= null;
35 private String defaultSectionStyle
;
37 public DocBookViewer(Composite parent
, int style
, Content item
, CmsEditable cmsEditable
) {
38 super(parent
, style
, cmsEditable
);
39 imageManager
= new DbkImageManager(item
);
41 for (Content child
: item
) {
42 if (child
.hasContentClass(DbkType
.article
)) {
43 if (mainSection
!= null)
44 throw new IllegalStateException("Main section already created");
45 mainSection
= new TextSection(parent
, 0, child
);
46 mainSection
.setLayoutData(CmsSwtUtils
.fillAll());
52 protected void refresh(Control control
) {
53 if (!(control
instanceof SwtSection
))
55 long begin
= System
.currentTimeMillis();
56 SwtSection section
= (SwtSection
) control
;
57 if (section
instanceof TextSection
) {
58 CmsSwtUtils
.clear(mainSection
);
59 refreshTextSection(mainSection
);
62 long duration
= System
.currentTimeMillis() - begin
;
63 // System.out.println(duration + " ms - " + DbkUtils.getTitle(section.getNode()));
67 protected void refreshTextSection(TextSection section
) {
68 Content sectionContent
= section
.getContent();
70 Optional
<String
> roleAttr
= sectionContent
.get(DbkAttr
.role
, String
.class);
71 String style
= roleAttr
.orElse(section
.getDefaultTextStyle());
73 CmsSwtUtils
.style(section
, style
);
76 Optional
<Content
> titleContent
= sectionContent
.soleChild(DbkType
.title
.qName());
78 if (titleContent
.isPresent()) {
79 boolean showTitle
= getMainSection() == section ? showMainTitle
: true;
81 if (section
.getHeader() == null)
82 section
.createHeader();
83 DbkSectionTitle title
= newSectionTitle(section
, titleContent
.get());
84 title
.setLayoutData(CmsSwtUtils
.fillWidth());
89 boolean processingSubSections
= false;
90 for (Content child
: section
.getContent()) {
91 if (child
.hasContentClass(DbkType
.section
)) {
92 processingSubSections
= true;
93 TextSection childSection
= new TextSection(section
, 0, child
);
94 childSection
.setLayoutData(CmsSwtUtils
.fillWidth());
95 refreshTextSection(childSection
);
97 if (processingSubSections
)
98 throw new IllegalStateException(child
+ " is below a subsection");
99 SwtSectionPart sectionPart
= null;
100 if (child
.hasContentClass(DbkType
.para
)) {
101 sectionPart
= newParagraph(section
, child
);
102 } else if (child
.hasContentClass(DbkType
.mediaobject
)) {
103 if (child
.hasChild(DbkType
.imageobject
)) {
104 sectionPart
= newImg(section
, child
);
105 } else if (child
.hasChild(DbkType
.videoobject
)) {
106 sectionPart
= newVideo(section
, child
);
108 throw new IllegalArgumentException("Unsupported media object " + child
);
110 } else if (isDbk(child
, DbkType
.title
)) {
112 // TODO check that it is first?
114 throw new IllegalArgumentException("Unsupported type for " + child
);
116 if (sectionPart
!= null && sectionPart
instanceof Control
)
117 ((Control
) sectionPart
).setLayoutData(CmsSwtUtils
.fillWidth());
122 protected void updateContent(SwtEditablePart part
) {
123 if (part
instanceof SwtSectionPart
) {
124 SwtSectionPart sectionPart
= (SwtSectionPart
) part
;
125 Content partContent
= sectionPart
.getContent();
127 if (part
instanceof StyledControl
&& (sectionPart
.getSection() instanceof TextSection
)) {
128 TextSection section
= (TextSection
) sectionPart
.getSection();
129 StyledControl styledControl
= (StyledControl
) part
;
130 if (isDbk(partContent
, para
)) {
131 Optional
<String
> roleAttr
= partContent
.get(DbkAttr
.role
.qName(), String
.class);
132 String style
= roleAttr
.orElse(section
.getDefaultTextStyle());
133 styledControl
.setStyle(style
);
136 // use control AFTER setting style, since it may have been reset
138 if (part
instanceof EditableText
) {
139 EditableText paragraph
= (EditableText
) part
;
140 if (paragraph
== getEdited())
141 paragraph
.setText(textInterpreter
.raw(partContent
));
143 paragraph
.setText(textInterpreter
.readSimpleHtml(partContent
));
144 // paragraph.setText(textInterpreter.readSimpleHtml(partContent));
146 } else if (part
instanceof DbkImg
) {
147 DbkImg editableImage
= (DbkImg
) part
;
148 // imageManager.load(partContent, part.getControl(), editableImage.getPreferredImageSize());
149 } else if (part
instanceof DbkVideo
) {
150 DbkVideo video
= (DbkVideo
) part
;
151 video
.load(part
.getControl());
153 } else if (part
instanceof DbkSectionTitle
) {
154 DbkSectionTitle title
= (DbkSectionTitle
) part
;
155 title
.setStyle(title
.getSection().getTitleStyle());
156 // use control AFTER setting style
157 if (title
== getEdited())
158 title
.setText(textInterpreter
.read(title
.getContent()));
160 title
.setText(textInterpreter
.readSimpleHtml(title
.getContent()));
164 protected Paragraph
newParagraph(TextSection parent
, Content node
) {
165 Paragraph paragraph
= new Paragraph(parent
, parent
.getStyle(), node
);
166 updateContent(paragraph
);
167 paragraph
.setLayoutData(CmsSwtUtils
.fillWidth());
168 paragraph
.setMouseListener(getMouseListener());
169 paragraph
.setFocusListener(getFocusListener());
173 protected DbkSectionTitle
newSectionTitle(TextSection parent
, Content titleNode
) {
174 int style
= parent
.getStyle();
175 Composite titleParent
= newSectionHeader(parent
);
176 if (parent
.isTitleReadOnly())
177 style
= style
| SWT
.READ_ONLY
;
178 DbkSectionTitle title
= new DbkSectionTitle(titleParent
, style
, titleNode
);
179 updateContent(title
);
180 title
.setMouseListener(getMouseListener());
181 title
.setFocusListener(getFocusListener());
185 protected DbkImg
newImg(TextSection parent
, Content node
) {
186 DbkImg img
= new DbkImg(parent
, parent
.getStyle(), node
, imageManager
);
188 if (maxMediaWidth
!= null) {
189 imgGd
= new GridData(SWT
.CENTER
, SWT
.FILL
, false, false);
190 imgGd
.widthHint
= maxMediaWidth
;
191 img
.setPreferredSize(new Cms2DSize(maxMediaWidth
, 0));
193 imgGd
= CmsSwtUtils
.grabWidth(SWT
.CENTER
, SWT
.DEFAULT
);
195 img
.setLayoutData(imgGd
);
197 img
.setMouseListener(getMouseListener());
198 img
.setFocusListener(getFocusListener());
202 protected DbkVideo
newVideo(TextSection parent
, Content node
) {
203 DbkVideo video
= new DbkVideo(parent
, getCmsEditable().canEdit() ? SWT
.NONE
: SWT
.READ_ONLY
, node
);
205 if (maxMediaWidth
!= null) {
206 gd
= new GridData(SWT
.CENTER
, SWT
.FILL
, false, false);
208 // gd.widthHint = maxMediaWidth;
209 // gd.heightHint = (int) (gd.heightHint * 0.5625);
211 gd
= new GridData(SWT
.CENTER
, SWT
.FILL
, false, false);
212 // gd.widthHint = video.getWidth();
213 // gd.heightHint = video.getHeight();
215 video
.setLayoutData(gd
);
216 updateContent(video
);
221 * To be overridden in order to provide additional processing at the section
224 * @return the parent to use for the {@link DbkSectionTitle}, by default
225 * {@link Section#getHeader()}
227 protected Composite
newSectionHeader(TextSection section
) {
228 return section
.getHeader();
231 public TextSection
getMainSection() {
235 public void setShowMainTitle(boolean showMainTitle
) {
236 this.showMainTitle
= showMainTitle
;
239 public String
getDefaultSectionStyle() {
240 return defaultSectionStyle
;
243 public void setDefaultSectionStyle(String defaultSectionStyle
) {
244 this.defaultSectionStyle
= defaultSectionStyle
;
247 public void setMaxMediaWidth(Integer maxMediaWidth
) {
248 this.maxMediaWidth
= maxMediaWidth
;
252 public Control
getControl() {