Skip to content
Snippets Groups Projects
Commit 60b43b94 authored by srosse's avatar srosse
Browse files

OO-3618: first implementation of multi-columns text

parent 3e685ccf
No related branches found
No related tags found
No related merge requests found
Showing
with 203 additions and 13 deletions
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package org.olat.modules.ceditor; package org.olat.modules.ceditor;
import org.olat.core.util.xml.XStreamHelper; import org.olat.core.util.xml.XStreamHelper;
import org.olat.modules.portfolio.ui.editor.TextSettings;
import org.olat.modules.portfolio.ui.media.ImageHorizontalAlignment; import org.olat.modules.portfolio.ui.media.ImageHorizontalAlignment;
import org.olat.modules.portfolio.ui.media.ImageSettings; import org.olat.modules.portfolio.ui.media.ImageSettings;
import org.olat.modules.portfolio.ui.media.ImageSize; import org.olat.modules.portfolio.ui.media.ImageSize;
...@@ -41,7 +42,8 @@ public class ContentEditorXStream { ...@@ -41,7 +42,8 @@ public class ContentEditorXStream {
static { static {
XStream.setupDefaultSecurity(xstream); XStream.setupDefaultSecurity(xstream);
Class<?>[] types = new Class[] { Class<?>[] types = new Class[] {
ImageSettings.class, ImageHorizontalAlignment.class, ImageTitlePosition.class, ImageSize.class ImageSettings.class, ImageHorizontalAlignment.class, ImageTitlePosition.class, ImageSize.class,
TextSettings.class
}; };
xstream.addPermission(new ExplicitTypePermission(types)); xstream.addPermission(new ExplicitTypePermission(types));
...@@ -49,6 +51,8 @@ public class ContentEditorXStream { ...@@ -49,6 +51,8 @@ public class ContentEditorXStream {
xstream.alias("imagehorizontalalignment", ImageHorizontalAlignment.class); xstream.alias("imagehorizontalalignment", ImageHorizontalAlignment.class);
xstream.alias("imagetitleposition", ImageTitlePosition.class); xstream.alias("imagetitleposition", ImageTitlePosition.class);
xstream.alias("imagesize", ImageSize.class); xstream.alias("imagesize", ImageSize.class);
xstream.alias("textsettings", TextSettings.class);
} }
public static String toXml(Object obj) { public static String toXml(Object obj) {
......
...@@ -19,19 +19,28 @@ ...@@ -19,19 +19,28 @@
*/ */
package org.olat.modules.portfolio.ui.editor; package org.olat.modules.portfolio.ui.editor;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.UserRequest; import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.RichTextElement; import org.olat.core.gui.components.form.flexible.elements.RichTextElement;
import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.elements.StaticTextElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.WindowControl;
import org.olat.core.util.CodeHelper; import org.olat.core.util.CodeHelper;
import org.olat.core.util.Formatter; import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper; import org.olat.core.util.StringHelper;
import org.olat.core.util.filter.FilterFactory; import org.olat.core.util.filter.FilterFactory;
import org.olat.modules.ceditor.ContentEditorXStream;
import org.olat.modules.portfolio.PortfolioService; import org.olat.modules.portfolio.PortfolioService;
import org.olat.modules.portfolio.model.HTMLPart; import org.olat.modules.portfolio.model.HTMLPart;
import org.olat.modules.portfolio.ui.editor.event.ChangePartEvent; import org.olat.modules.portfolio.ui.editor.event.ChangePartEvent;
...@@ -45,6 +54,11 @@ import org.springframework.beans.factory.annotation.Autowired; ...@@ -45,6 +54,11 @@ import org.springframework.beans.factory.annotation.Autowired;
*/ */
public class HTMLRawEditorController extends FormBasicController implements PageElementEditorController { public class HTMLRawEditorController extends FormBasicController implements PageElementEditorController {
private Link column1Link;
private Link column2Link;
private Link column3Link;
private Link column4Link;
private RichTextElement htmlItem; private RichTextElement htmlItem;
private StaticTextElement staticItem; private StaticTextElement staticItem;
...@@ -55,11 +69,23 @@ public class HTMLRawEditorController extends FormBasicController implements Page ...@@ -55,11 +69,23 @@ public class HTMLRawEditorController extends FormBasicController implements Page
private PortfolioService portfolioService; private PortfolioService portfolioService;
public HTMLRawEditorController(UserRequest ureq, WindowControl wControl, HTMLPart htmlPart) { public HTMLRawEditorController(UserRequest ureq, WindowControl wControl, HTMLPart htmlPart) {
super(ureq, wControl, LAYOUT_BAREBONE); super(ureq, wControl, "html_raw_editor");
this.htmlPart = htmlPart; this.htmlPart = htmlPart;
initForm(ureq); initForm(ureq);
setEditMode(editMode); setEditMode(editMode);
column1Link = LinkFactory.createToolLink("text.column.1", translate("text.column.1"), this);
column2Link = LinkFactory.createToolLink("text.column.2", translate("text.column.2"), this);
column3Link = LinkFactory.createToolLink("text.column.3", translate("text.column.3"), this);
column4Link = LinkFactory.createToolLink("text.column.4", translate("text.column.4"), this);
if(StringHelper.containsNonWhitespace(htmlPart.getLayoutOptions())) {
TextSettings settings = ContentEditorXStream.fromXml(htmlPart.getLayoutOptions(), TextSettings.class);
setActiveColumLink(settings.getNumOfColumns());
} else {
setActiveColumLink(1);
}
} }
@Override @Override
...@@ -72,6 +98,17 @@ public class HTMLRawEditorController extends FormBasicController implements Page ...@@ -72,6 +98,17 @@ public class HTMLRawEditorController extends FormBasicController implements Page
this.editMode = editMode; this.editMode = editMode;
htmlItem.setVisible(editMode); htmlItem.setVisible(editMode);
staticItem.setVisible(!editMode); staticItem.setVisible(!editMode);
flc.getFormItemComponent().contextPut("editMode", Boolean.valueOf(editMode));
}
@Override
public List<Link> getOptionLinks() {
List<Link> links = new ArrayList<>(2);
links.add(column4Link);
links.add(column3Link);
links.add(column2Link);
links.add(column1Link);
return links;
} }
@Override @Override
...@@ -85,11 +122,27 @@ public class HTMLRawEditorController extends FormBasicController implements Page ...@@ -85,11 +122,27 @@ public class HTMLRawEditorController extends FormBasicController implements Page
String formattedContent = Formatter.formatLatexFormulas(contentOrExample(content)); String formattedContent = Formatter.formatLatexFormulas(contentOrExample(content));
staticItem = uifactory.addStaticTextElement(cmpId + "_static", formattedContent, formLayout); staticItem = uifactory.addStaticTextElement(cmpId + "_static", formattedContent, formLayout);
((FormLayoutContainer)formLayout).contextPut("htmlCmpId", cmpId);
} }
@Override @Override
protected void propagateDirtinessToContainer(FormItem fiSrc, FormEvent fe) { protected void propagateDirtinessToContainer(FormItem fiSrc, FormEvent fe) {
//super.propagateDirtinessToContainer(fiSrc, fe); //
}
@Override
public void event(UserRequest ureq, Component source, Event event) {
if(column1Link == source) {
doSetColumn(1);
} else if(column2Link == source) {
doSetColumn(2);
} else if(column3Link == source) {
doSetColumn(3);
} else if(column4Link == source) {
doSetColumn(4);
}
super.event(ureq, source, event);
} }
@Override @Override
...@@ -116,6 +169,40 @@ public class HTMLRawEditorController extends FormBasicController implements Page ...@@ -116,6 +169,40 @@ public class HTMLRawEditorController extends FormBasicController implements Page
fireEvent(ureq, new ChangePartEvent(htmlPart)); fireEvent(ureq, new ChangePartEvent(htmlPart));
} }
private void setActiveColumLink(int numOfColumns) {
column1Link.setIconLeftCSS("o_icon o_icon_column");
column2Link.setIconLeftCSS("o_icon o_icon_columns");
column3Link.setIconLeftCSS("o_icon o_icon_columns");
column4Link.setIconLeftCSS("o_icon o_icon_columns");
if(numOfColumns == 1) {
column1Link.setIconLeftCSS("o_icon o_icon_check");
} else if(numOfColumns == 2) {
column2Link.setIconLeftCSS("o_icon o_icon_check");
} else if(numOfColumns == 3) {
column3Link.setIconLeftCSS("o_icon o_icon_check");
} else if(numOfColumns == 4) {
column4Link.setIconLeftCSS("o_icon o_icon_check");
}
flc.getFormItemComponent().contextPut("htmlRawClass", "o_pf_html_raw o_html_col" + numOfColumns);
flc.setDirty(true);
}
private void doSetColumn(int numOfColumns) {
TextSettings settings;
if(StringHelper.containsNonWhitespace(htmlPart.getLayoutOptions())) {
settings = ContentEditorXStream.fromXml(htmlPart.getLayoutOptions(), TextSettings.class);
} else {
settings = new TextSettings();
}
settings.setNumOfColumns(numOfColumns);
String settingsXml = ContentEditorXStream.toXml(settings);
htmlPart.setLayoutOptions(settingsXml);
htmlPart = portfolioService.updatePart(htmlPart);
setActiveColumLink(numOfColumns);
}
private String contentOrExample(String content) { private String contentOrExample(String content) {
String raw = FilterFactory.getHtmlTagsFilter().filter(content); String raw = FilterFactory.getHtmlTagsFilter().filter(content);
String staticContent = content; String staticContent = content;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
package org.olat.modules.portfolio.ui.editor; package org.olat.modules.portfolio.ui.editor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -233,6 +234,11 @@ public class PageEditorController extends BasicController { ...@@ -233,6 +234,11 @@ public class PageEditorController extends BasicController {
private void doEditElement(EditorFragment fragment) { private void doEditElement(EditorFragment fragment) {
for(EditorFragment eFragment:fragments) { for(EditorFragment eFragment:fragments) {
eFragment.setEditMode(eFragment.equals(fragment)); eFragment.setEditMode(eFragment.equals(fragment));
List<Link> additionalTools = eFragment.getAdditionalTools();
for(Link additionalTool:additionalTools) {
mainVC.put(additionalTool.getComponentName(), additionalTool);
}
} }
//The link must every time created as new //The link must every time created as new
...@@ -285,7 +291,7 @@ public class PageEditorController extends BasicController { ...@@ -285,7 +291,7 @@ public class PageEditorController extends BasicController {
deleteLink.setVisible(secCallback.canDeleteElement()); deleteLink.setVisible(secCallback.canDeleteElement());
deleteLink.setEnabled(secCallback.canDeleteElement()); deleteLink.setEnabled(secCallback.canDeleteElement());
fragment.setDeleteLink(deleteLink); fragment.setDeleteLink(deleteLink);
mainVC.setDirty(true); mainVC.setDirty(true);
} }
...@@ -546,6 +552,13 @@ public class PageEditorController extends BasicController { ...@@ -546,6 +552,13 @@ public class PageEditorController extends BasicController {
this.moveDownLink = moveDownLink; this.moveDownLink = moveDownLink;
} }
public List<Link> getAdditionalTools() {
if(editorPart instanceof PageElementEditorController) {
return ((PageElementEditorController)editorPart).getOptionLinks();
}
return Collections.emptyList();
}
public String getType() { public String getType() {
return handler.getType(); return handler.getType();
} }
......
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
*/ */
package org.olat.modules.portfolio.ui.editor; package org.olat.modules.portfolio.ui.editor;
import java.util.ArrayList;
import java.util.List;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Controller;
/** /**
...@@ -41,5 +45,10 @@ public interface PageElementEditorController extends Controller { ...@@ -41,5 +45,10 @@ public interface PageElementEditorController extends Controller {
* @param editMode * @param editMode
*/ */
public void setEditMode(boolean editMode); public void setEditMode(boolean editMode);
public default List<Link> getOptionLinks() {
return new ArrayList<>(1);
}
} }
package org.olat.modules.portfolio.ui.editor;
/**
*
* Initial date: 7 sept. 2018<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class TextSettings {
private int numOfColumns;
public int getNumOfColumns() {
return numOfColumns;
}
public void setNumOfColumns(int numOfColumns) {
this.numOfColumns = numOfColumns;
}
}
#if($editMode)
$r.render(${htmlCmpId})
#else
<div class="$htmlRawClass">$r.render("${htmlCmpId}_static")</div>
#end
\ No newline at end of file
...@@ -11,10 +11,14 @@ ...@@ -11,10 +11,14 @@
<div class="o_page_others_above"> <div class="o_page_others_above">
<span class="o_page_type"><i class="o_icon $fragment.typeCssClass"> </i> $r.translate($fragment.type)</span> <span class="o_page_type"><i class="o_icon $fragment.typeCssClass"> </i> $r.translate($fragment.type)</span>
$r.render($fragment.saveLink) $r.render($fragment.saveLink)
#if($r.visible($fragment.deleteLink)) #if($r.visible($fragment.deleteLink))
$r.render($fragment.deleteLink) $r.render($fragment.deleteLink)
#end #end
#foreach($additionalTool in $fragment.additionalTools)
$r.render($additionalTool)
#end
</div> </div>
</div> </div>
<div class="o_page_tools_dd"> <div class="o_page_tools_dd">
......
...@@ -69,5 +69,9 @@ save.and.close=Schliessen ...@@ -69,5 +69,9 @@ save.and.close=Schliessen
show.description=Beschreibung show.description=Beschreibung
show.source=Quelle show.source=Quelle
text=Text text=Text
text.column.1=1 Spalte
text.column.2=2 Spalten
text.column.3=3 Spalten
text.column.4=4 Spalten
title.example=<h1>Anklicken um Titel zu bearbeiten</h1> title.example=<h1>Anklicken um Titel zu bearbeiten</h1>
video=Video video=Video
...@@ -66,5 +66,9 @@ save.and.close=Close ...@@ -66,5 +66,9 @@ save.and.close=Close
show.description=Description show.description=Description
show.source=Source show.source=Source
text=Text text=Text
text.column.1=1 column
text.column.2=2 columns
text.column.3=3 columns
text.column.4=4 columns
title.example=<h1>Click to edit title</h1> title.example=<h1>Click to edit title</h1>
video=Video video=Video
...@@ -27,6 +27,8 @@ import org.olat.core.gui.components.text.TextFactory; ...@@ -27,6 +27,8 @@ import org.olat.core.gui.components.text.TextFactory;
import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.WindowControl;
import org.olat.core.util.CodeHelper; import org.olat.core.util.CodeHelper;
import org.olat.core.util.Formatter; import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.modules.ceditor.ContentEditorXStream;
import org.olat.modules.portfolio.model.HTMLPart; import org.olat.modules.portfolio.model.HTMLPart;
import org.olat.modules.portfolio.ui.editor.HTMLRawEditorController; import org.olat.modules.portfolio.ui.editor.HTMLRawEditorController;
import org.olat.modules.portfolio.ui.editor.PageElement; import org.olat.modules.portfolio.ui.editor.PageElement;
...@@ -36,6 +38,7 @@ import org.olat.modules.portfolio.ui.editor.PageElementRenderingHints; ...@@ -36,6 +38,7 @@ import org.olat.modules.portfolio.ui.editor.PageElementRenderingHints;
import org.olat.modules.portfolio.ui.editor.PageRunComponent; import org.olat.modules.portfolio.ui.editor.PageRunComponent;
import org.olat.modules.portfolio.ui.editor.PageRunElement; import org.olat.modules.portfolio.ui.editor.PageRunElement;
import org.olat.modules.portfolio.ui.editor.SimpleAddPageElementHandler; import org.olat.modules.portfolio.ui.editor.SimpleAddPageElementHandler;
import org.olat.modules.portfolio.ui.editor.TextSettings;
/** /**
* *
...@@ -52,20 +55,26 @@ public class HTMLRawPageElementHandler implements PageElementHandler, SimpleAddP ...@@ -52,20 +55,26 @@ public class HTMLRawPageElementHandler implements PageElementHandler, SimpleAddP
@Override @Override
public String getIconCssClass() { public String getIconCssClass() {
// For now we use the paragraph icon until we have a minimized paragraph eleent // For now we use the paragraph icon until we have a minimized paragraph element o_icon_code
//return "o_icon_code";
return "o_icon_paragraph"; return "o_icon_paragraph";
} }
@Override @Override
public PageRunElement getContent(UserRequest ureq, WindowControl wControl, PageElement element, PageElementRenderingHints options) { public PageRunElement getContent(UserRequest ureq, WindowControl wControl, PageElement element, PageElementRenderingHints options) {
String content = ""; String content = "";
int numOfColumns = 1;
if(element instanceof HTMLPart) { if(element instanceof HTMLPart) {
content = ((HTMLPart)element).getContent(); HTMLPart htmlPart = (HTMLPart)element;
content = htmlPart.getContent();
content = Formatter.formatLatexFormulas(content); content = Formatter.formatLatexFormulas(content);
if(StringHelper.containsNonWhitespace(htmlPart.getLayoutOptions())) {
TextSettings settings = ContentEditorXStream.fromXml(htmlPart.getLayoutOptions(), TextSettings.class);
numOfColumns = settings.getNumOfColumns();
}
} }
TextComponent cmp = TextFactory.createTextComponentFromString("htmlRawCmp" + CodeHelper.getRAMUniqueID(), content, null, false, null); TextComponent cmp = TextFactory.createTextComponentFromString("htmlRawCmp" + CodeHelper.getRAMUniqueID(), content, null, false, null);
cmp.setElementCssClass("o_pf_html_raw"); cmp.setElementCssClass("o_pf_html_raw o_html_col" + numOfColumns);
return new PageRunComponent(cmp); return new PageRunComponent(cmp);
} }
......
...@@ -81,6 +81,8 @@ $fa-css-prefix: "o_icon" !default; ...@@ -81,6 +81,8 @@ $fa-css-prefix: "o_icon" !default;
.o_icon_close_togglebox:before { content: $fa-var-caret-down;} .o_icon_close_togglebox:before { content: $fa-var-caret-down;}
.o_icon_code:before { content: $fa-var-code;} .o_icon_code:before { content: $fa-var-code;}
.o_icon_color_picker:before { content: $fa-var-tint;} .o_icon_color_picker:before { content: $fa-var-tint;}
.o_icon_column:before { content: $fa-var-align-justify;}
.o_icon_columns:before { content: $fa-var-columns;}
.o_icon_copy:before { content: $fa-var-copy;} .o_icon_copy:before { content: $fa-var-copy;}
.o_icon_courseareas:before { content: $fa-var-circle-thin;} .o_icon_courseareas:before { content: $fa-var-circle-thin;}
.o_icon_coursedb:before { content: $fa-var-database;} .o_icon_coursedb:before { content: $fa-var-database;}
......
...@@ -356,6 +356,22 @@ ...@@ -356,6 +356,22 @@
border-radius: $o-panel-placeholder-border-radius; border-radius: $o-panel-placeholder-border-radius;
} }
.o_pf_html_raw {
&.o_html_col2 {
column-count: 2;
column-gap: 1em;
}
&.o_html_col3 {
column-count: 3;
column-gap: 1em;
}
&.o_html_col4 {
column-count: 4;
column-gap: 1em;
}
}
.o_image, .o_video { .o_image, .o_video {
@extend %o_block_large; @extend %o_block_large;
padding: $o-portfolio-media-content-space; padding: $o-portfolio-media-content-space;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -21,7 +21,7 @@ package org.olat.modules.ceditor; ...@@ -21,7 +21,7 @@ package org.olat.modules.ceditor;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.olat.modules.ceditor.ContentEditorXStream; import org.olat.modules.portfolio.ui.editor.TextSettings;
import org.olat.modules.portfolio.ui.media.ImageHorizontalAlignment; import org.olat.modules.portfolio.ui.media.ImageHorizontalAlignment;
import org.olat.modules.portfolio.ui.media.ImageSettings; import org.olat.modules.portfolio.ui.media.ImageSettings;
import org.olat.modules.portfolio.ui.media.ImageSize; import org.olat.modules.portfolio.ui.media.ImageSize;
...@@ -65,5 +65,18 @@ public class ContentEditorXStreamTest { ...@@ -65,5 +65,18 @@ public class ContentEditorXStreamTest {
Assert.assertEquals(ImageTitlePosition.above, deserializedSettings.getTitlePosition()); Assert.assertEquals(ImageTitlePosition.above, deserializedSettings.getTitlePosition());
Assert.assertEquals("o_image_title_style", deserializedSettings.getTitleStyle()); Assert.assertEquals("o_image_title_style", deserializedSettings.getTitleStyle());
} }
@Test
public void textSettingsToXmlAndFrom() {
TextSettings settings = new TextSettings();
settings.setNumOfColumns(3);
// serialize
String xml = ContentEditorXStream.toXml(settings);
// read
TextSettings deserializedSettings = ContentEditorXStream.fromXml(xml, TextSettings.class);
//check
Assert.assertNotNull(deserializedSettings);
Assert.assertEquals(3, deserializedSettings.getNumOfColumns());
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment