From a033ea21c5bcf1f59de8edad92b1cbb520e3baf0 Mon Sep 17 00:00:00 2001 From: Xuan Sang LE Date: Thu, 13 Sep 2018 20:21:07 +0200 Subject: [PATCH] editor control --- OpenPage/assets/scheme.html | 37 ++- OpenPage/build/debug/main.css | 40 ++- OpenPage/build/debug/main.js | 407 +++++++++++++++++++++++++++++-- OpenPage/build/debug/scheme.html | 37 ++- OpenPage/coffees/dialogs.coffee | 32 +++ OpenPage/coffees/main.coffee | 237 ++++++++++++++++-- OpenPage/css/main.css | 40 ++- OpenPage/project.apj | 2 +- 8 files changed, 780 insertions(+), 52 deletions(-) create mode 100644 OpenPage/coffees/dialogs.coffee diff --git a/OpenPage/assets/scheme.html b/OpenPage/assets/scheme.html index 0d3d05e..b8deaa3 100644 --- a/OpenPage/assets/scheme.html +++ b/OpenPage/assets/scheme.html @@ -1,7 +1,36 @@ - + -
-
-
+ + +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/OpenPage/build/debug/main.css b/OpenPage/build/debug/main.css index 7223d6b..2873845 100644 --- a/OpenPage/build/debug/main.css +++ b/OpenPage/build/debug/main.css @@ -2,6 +2,42 @@ afx-app-window[data-id="OpenPage"] div[data-id="container"] { overflow: auto; - margin:0 auto; - padding:0px + margin:0px; + padding:0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: center; + background-color: #f2f1f0; +} + +afx-app-window[data-id="OpenPage"] div[data-id="odfcanvas"] +{ + cursor: text; + margin:auto; + box-shadow: 1px 1px 3px 3px #9f9F9F; +} + +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] +{ + background-color: #f5f5f5; + border: 1px solid #eaeaea; + box-shadow: 3px 3px 3px #9f9F9F; +} +afx-app-window[data-id="HyperLinkDialog"] afx-label.header span +{ + font-weight: bold; +} +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button{ + border: 1px solid #f5f5f5; + background-color: transparent; + width:100%; + height: 100%; +} + +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button:hover, afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button.btactive button +{ + border: 1px solid #759DC0; + background-color: transparent; + border-radius:5px; + color:#759DC0; } \ No newline at end of file diff --git a/OpenPage/build/debug/main.js b/OpenPage/build/debug/main.js index e61166a..c21f7bc 100644 --- a/OpenPage/build/debug/main.js +++ b/OpenPage/build/debug/main.js @@ -1,5 +1,5 @@ (function() { - var OpenPage; + var HyperLinkDialog, OpenPage; OpenPage = class OpenPage extends this.OS.GUI.BaseApplication { constructor(args) { @@ -7,19 +7,89 @@ } main() { - var el, me, userid; + // load session class + if (!OpenPage.editorSession) { + require(["webodf/editor/EditorSession"], function(ES) { + return OpenPage.EditorSession = ES; + }); + } + this.eventSubscriptions = new core.EventSubscriptions(); + this.initToolbox(); + this.initCanvas(); + return this.canvas.load(`${this._api.handler.get}/home://welcome.odt`); + } + + initToolbox() { + var el, fn, me, name, ref, results; + me = this; + this.basictool = { + undo: this.find("btundo"), + redo: this.find("btredo"), + bold: this.find("btbold"), + italic: this.find("btitalic"), + underline: this.find("btunderline"), + strike: this.find("btstrike"), + note: this.find("btnote"), + link: this.find("btlink"), + unlink: this.find("btunlink"), + image: this.find("btimage"), + ac: this.find("btac"), + al: this.find("btal"), + ar: this.find("btar"), + aj: this.find("btaj"), + indent: this.find("btindent"), + outdent: this.find("btoutdent"), + fonts: this.find("font-list"), + fontsize: this.find("font-size") + }; + fn = function(name, el) { + var act; + if (name === "fonts") { + act = "onlistselect"; + } else if (name === "fontsize") { + act = "onchange"; + } else { + act = "onbtclick"; + } + return el.set(act, function(e) { + if (!me.directFormattingCtl) { + return; + } + if (!me[name]) { + return; + } + me[name](e); + return me.editorFocus(); + }); + }; + ref = this.basictool; + results = []; + for (name in ref) { + el = ref[name]; + results.push(fn(name, el)); + } + return results; + } + + initCanvas() { + var el, me; el = this.find("odfcanvas"); me = this; el.setAttribute("translate", "no"); el.classList.add("notranslate"); - this.eventNotifier = new core.EventNotifier(["unknown-error", "documentModifiedChanged", "metadataChanged"]); - userid = "localuser"; - require(["webodf/editor/EditorSession"], function(ES) { - return OpenPage.EditorSession = ES; - }); + this.userid = "localuser"; this.canvas = new odf.OdfCanvas(el); + this.documentChanged = function(e) { + return console.log(e); + }; + this.metaChanged = function(e) { + return console.log(e); + }; + this.textStylingChanged = function(e) { + return me.updateToolbar(e); + }; //@canvas.enableAnnotations(true, true) - this.canvas.addListener("statereadychange", function() { + return this.canvas.addListener("statereadychange", function() { var op, viewOptions; me.session = new ops.Session(me.canvas); viewOptions = { @@ -27,7 +97,7 @@ caretAvatarsInitiallyVisible: false, caretBlinksOnRangeSelect: true }; - me.editorSession = new OpenPage.EditorSession(me.session, userid, { + me.editorSession = new OpenPage.EditorSession(me.session, me.userid, { viewOptions: viewOptions, directTextStylingEnabled: true, directParagraphStylingEnabled: true, @@ -39,36 +109,331 @@ zoomingEnabled: true, reviewModeEnabled: false }); + // basic format + me.directFormattingCtl = me.editorSession.sessionController.getDirectFormattingController(); + me.directFormattingCtl.subscribe(gui.DirectFormattingController.textStylingChanged, me.textStylingChanged); + me.directFormattingCtl.subscribe(gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged); + // hyper link controller + me.hyperlinkController = me.editorSession.sessionController.getHyperlinkController(); + me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalCursorMoved, function() { + return me.updateHyperlinkButtons(); + }); + me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalParagraphChanged, function() { + return me.updateHyperlinkButtons(); + }); + me.eventSubscriptions.addFrameSubscription(me.editorSession, OpenPage.EditorSession.signalParagraphStyleModified, function() { + return me.updateHyperlinkButtons(); + }); me.editorSession.sessionController.setUndoManager(new gui.TrivialUndoManager()); - me.editorSession.sessionController.getUndoManager().subscribe(gui.UndoManager.signalDocumentModifiedChanged, function(mod) { - return me.eventNotifier.emit("documentModifiedChanged", mod); - }); - me.editorSession.sessionController.getMetadataController().subscribe(gui.MetadataController.signalMetadataChanged, function(changes) { - return me.eventNotifier.emit("metadataChanged", changes); - }); + me.editorSession.sessionController.getUndoManager().subscribe(gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged); + me.editorSession.sessionController.getMetadataController().subscribe(gui.MetadataController.signalMetadataChanged, me.metaChanged); op = new ops.OpAddMember(); op.init({ - memberid: userid, + memberid: me.userid, setProperties: { "fullName": "Xuan Sang LE", "color": "blue" } }); me.session.enqueue([op]); + me.initFontList(me.editorSession.getDeclaredFonts()); me.editorSession.sessionController.insertLocalCursor(); - me.editorSession.sessionController.startEditing(); - return me.editorSession.sessionController.getEventManager().focus(); + return me.editorSession.sessionController.startEditing(); }); - this.canvas.load(`${this._api.handler.get}/home://Downloads/welcome.odt`); - return this.eventNotifier.subscribe("documentModifiedChanged", function(d) { - return console.log("document is modified"); + } + + //console.log me.editorSession.getDeclaredFonts() + + initFontList(list) { + var j, len, v; + for (j = 0, len = list.length; j < len; j++) { + v = list[j]; + v.text = v.name; + } + return this.basictool.fonts.set("items", list); + } + + updateToolbar(changes) { + if (changes.hasOwnProperty('isBold')) { + // basic style + this.basictool.bold.set("selected", changes.isBold); + } + if (changes.hasOwnProperty('isItalic')) { + this.basictool.italic.set("selected", changes.isItalic); + } + if (changes.hasOwnProperty('hasUnderline')) { + this.basictool.underline.set("selected", changes.hasUnderline); + } + if (changes.hasOwnProperty('hasStrikeThrough')) { + this.basictool.strike.set("selected", changes.hasStrikeThrough); + } + if (changes.hasOwnProperty("fontSize")) { + this.basictool.fontsize.set("value", changes.fontSize); + } + if (changes.hasOwnProperty("fontName")) { + this.selectFont(changes.fontName); + } + if (changes.hasOwnProperty("isAlignedLeft")) { + //pharagraph style + this.basictool.al.set("selected", changes.isAlignedLeft); + } + if (changes.hasOwnProperty("isAlignedRight")) { + this.basictool.ar.set("selected", changes.isAlignedRight); + } + if (changes.hasOwnProperty("isAlignedCenter")) { + this.basictool.ac.set("selected", changes.isAlignedCenter); + } + if (changes.hasOwnProperty("isAlignedJustified")) { + return this.basictool.aj.set("selected", changes.isAlignedJustified); + } + } + + updateHyperlinkButtons(e) { + var selectedLinks; + selectedLinks = this.editorSession.getSelectedHyperlinks(); + return this.basictool.unlink.set("enable", selectedLinks.length > 0); + } + + selectFont(name) { + var i, item, items, j, len, v; + items = this.basictool.fonts.get("items"); + for (i = j = 0, len = items.length; j < len; i = ++j) { + v = items[i]; + if (v.name === name) { + item = i; + } + } + return this.basictool.fonts.set("selected", item); + } + + editorFocus() { + return this.editorSession.sessionController.getEventManager().focus(); + } + + bold(e) { + //console.log @, e + return this.directFormattingCtl.setBold(!this.basictool.bold.get("selected")); + } + + italic(e) { + return this.directFormattingCtl.setItalic(!this.basictool.italic.get("selected")); + } + + underline(e) { + return this.directFormattingCtl.setHasUnderline(!this.basictool.underline.get("selected")); + } + + strike(e) { + return this.directFormattingCtl.setHasStrikethrough(!this.basictool.strike.get("selected")); + } + + fonts(e) { + return this.directFormattingCtl.setFontName(e.data.name); + } + + fontsize(e) { + return this.directFormattingCtl.setFontSize(e); + } + + al(e) { + return this.directFormattingCtl.alignParagraphLeft(); + } + + ar(e) { + return this.directFormattingCtl.alignParagraphRight(); + } + + ac(e) { + return this.directFormattingCtl.alignParagraphCenter(); + } + + aj(e) { + return this.directFormattingCtl.alignParagraphJustified(); + } + + indent(e) { + return this.directFormattingCtl.indent(); + } + + outdent(e) { + return this.directFormattingCtl.outdent(); + } + + link(e) { + var data, linkTarget, linksInSelection, me, selection, textSerializer; + // get the link first + me = this; + textSerializer = new odf.TextSerializer(); + selection = this.editorSession.getSelectedRange(); + linksInSelection = this.editorSession.getSelectedHyperlinks(); + linkTarget = linksInSelection[0] ? odf.OdfUtils.getHyperlinkTarget(linksInSelection[0]) : "http://"; + data = { + link: linkTarget, + text: "", + readonly: true, + action: "new" + }; + if (selection && selection.collapsed && linksInSelection.length === 1) { + // selection is collapsed within a single link + // text in this case is read only + data.text = textSerializer.writeToString(linksInSelection[0]); + data.action = "edit"; + } else if (selection && !selection.collapsed) { + // user select part of link or a block of text + // user convert a selection to a link + data.text = textSerializer.writeToString(selection.cloneContents()); + } else { + data.readonly = false; + } + return this.openDialog(new HyperLinkDialog(), function(d) { + var selectedLinkRange, selectionController; + selectionController = me.editorSession.sessionController.getSelectionController(); + if (d.readonly) { + // edit the existing link + if (d.action === "edit") { + selectedLinkRange = selection.cloneRange(); + selectedLinkRange.selectNode(linksInSelection[0]); + selectionController.selectRange(selectedLinkRange, true); + } + me.hyperlinkController.removeHyperlinks(); + return me.hyperlinkController.addHyperlink(d.link); + } else { + me.hyperlinkController.addHyperlink(d.link, d.text); + linksInSelection = me.editorSession.getSelectedHyperlinks(); + selectedLinkRange = selection.cloneRange(); + selectedLinkRange.selectNode(linksInSelection[0]); + return selectionController.selectRange(selectedLinkRange, true); + } + }, "__(Insert/edit link)", data); + } + + unlink(e) { + return this.hyperlinkController.removeHyperlinks(); + } + + closeDocument() { + var me, op; + // finish editing + if (!(this.editorSession && this.session)) { + return; + } + me = this; + this.eventSubscriptions.unsubscribeAll(); + this.editorSession.sessionController.endEditing(); + this.editorSession.sessionController.removeLocalCursor(); + // remove user + op = new ops.OpRemoveMember(); + op.init({ + memberid: this.userid }); + this.session.enqueue([op]); + // close the session + return this.session.close(function(e) { + if (e) { + return me.error("Cannot close session " + e); + } + me.editorSession.sessionController.getMetadataController().unsubscribe(gui.MetadataController.signalMetadataChanged, me.metaChanged); + me.editorSession.sessionController.getUndoManager().unsubscribe(gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged); + me.directFormattingCtl.unsubscribe(gui.DirectFormattingController.textStylingChanged, me.textStylingChanged); + me.directFormattingCtl.unsubscribe(gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged); + // destry editorSession + return me.editorSession.destroy(function(e) { + if (e) { + return me.error("Cannot destroy editor session " + e); + } + me.editorSession = void 0; + // destroy session + return me.session.destroy(function(e) { + if (e) { + return me.error("Cannot destroy document session " + e); + } + core.Async.destroyAll([me.canvas.destroy], function(e) { + if (e) { + return me.error("Cannot destroy canvas" + e); + } + return me.notify("Document closed"); + }); + me.session = void 0; + return me.directFormattingCtl = void 0; + }); + }); + }); + } + + + cleanup(e) { + return this.closeDocument(); } }; this.OS.register("OpenPage", OpenPage); + HyperLinkDialog = class HyperLinkDialog extends this.OS.GUI.BasicDialog { + constructor() { + super("HyperLinkDialog", { + tags: [ + { + tag: "afx-label", + att: 'text="__(Text)" data-height="23" class="header"' + }, + { + tag: "input", + att: 'data-height="30"' + }, + { + tag: "afx-label", + att: 'text="__(Link)" data-height="23" class="header"' + }, + { + tag: "input", + att: 'data-height="30"' + }, + { + tag: "div", + att: ' data-height="5"' + } + ], + width: 350, + height: 150, + resizable: false, + buttons: [ + { + label: "Ok", + onclick: function(d) { + var data; + data = { + text: (d.find("content1")).value, + link: (d.find("content3")).value, + readonly: d.data.readonly, + action: d.data.action + }; + if (d.handler) { + d.handler(data); + } + return d.quit(); + } + }, + { + label: "__(Cancel)", + onclick: function(d) { + return d.quit(); + } + } + ], + filldata: function(d) { + if (!d.data) { + return; + } + (d.find("content1")).value = d.data.text; + (d.find("content3")).value = d.data.link; + return $(d.find("content1")).prop('disabled', d.data.readonly); + } + }); + } + + }; + }).call(this); /* diff --git a/OpenPage/build/debug/scheme.html b/OpenPage/build/debug/scheme.html index 0d3d05e..b8deaa3 100644 --- a/OpenPage/build/debug/scheme.html +++ b/OpenPage/build/debug/scheme.html @@ -1,7 +1,36 @@ - + -
-
-
+ + +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/OpenPage/coffees/dialogs.coffee b/OpenPage/coffees/dialogs.coffee new file mode 100644 index 0000000..f842605 --- /dev/null +++ b/OpenPage/coffees/dialogs.coffee @@ -0,0 +1,32 @@ +class HyperLinkDialog extends this.OS.GUI.BasicDialog + constructor: () -> + super "HyperLinkDialog", { + tags: [ + { tag: "afx-label", att: 'text="__(Text)" data-height="23" class="header"' }, + { tag: "input", att: 'data-height="30"' }, + { tag: "afx-label", att: 'text="__(Link)" data-height="23" class="header"' }, + { tag: "input", att: 'data-height="30"' }, + { tag: "div", att: ' data-height="5"' } + ], + width: 350, + height: 150, + resizable: false, + buttons: [ + { + label: "Ok", onclick: (d) -> + data = + text: (d.find "content1").value, + link: (d.find "content3").value, + readonly: d.data.readonly, + action: d.data.action + d.handler data if d.handler + d.quit() + }, + { label: "__(Cancel)", onclick: (d) -> d.quit() } + ], + filldata: (d) -> + return unless d.data + (d.find "content1").value = d.data.text + (d.find "content3").value = d.data.link + $(d.find "content1").prop('disabled', d.data.readonly) + } \ No newline at end of file diff --git a/OpenPage/coffees/main.coffee b/OpenPage/coffees/main.coffee index 9c2cbd3..6d0887d 100644 --- a/OpenPage/coffees/main.coffee +++ b/OpenPage/coffees/main.coffee @@ -3,19 +3,64 @@ class OpenPage extends this.OS.GUI.BaseApplication super "OpenPage", args main: () -> + # load session class + if not OpenPage.editorSession + require ["webodf/editor/EditorSession"], (ES) -> + OpenPage.EditorSession = ES + @eventSubscriptions = new core.EventSubscriptions() + @initToolbox() + @initCanvas() + @canvas.load "#{@_api.handler.get}/home://welcome.odt" + + initToolbox: () -> + me = @ + @basictool = + undo: @find("btundo"), + redo: @find("btredo"), + bold: @find("btbold"), + italic:@find("btitalic"), + underline:@find("btunderline"), + strike: @find("btstrike"), + note: @find("btnote"), + link: @find("btlink"), + unlink: @find("btunlink"), + image:@find("btimage"), + ac: @find("btac"), + al: @find("btal"), + ar: @find("btar"), + aj: @find("btaj"), + indent: @find("btindent"), + outdent: @find("btoutdent"), + fonts: @find("font-list"), + fontsize: @find("font-size") + fn = (name, el) -> + if name is "fonts" + act = "onlistselect" + else if name is "fontsize" + act = "onchange" + else + act = "onbtclick" + el.set act, (e) -> + return unless me.directFormattingCtl + return unless me[name] + me[name](e) + me.editorFocus() + for name, el of @basictool + fn name, el + + initCanvas: () -> el = @find "odfcanvas" me = @ el.setAttribute "translate", "no" el.classList.add "notranslate" - @eventNotifier = new core.EventNotifier [ - "unknown-error", - "documentModifiedChanged", - "metadataChanged" - ] - userid = "localuser" - require ["webodf/editor/EditorSession"], (ES) -> - OpenPage.EditorSession = ES + @userid = "localuser" @canvas = new odf.OdfCanvas(el) + @documentChanged = (e) -> + console.log e + @metaChanged = (e) -> + console.log e + @textStylingChanged = (e) -> + me.updateToolbar e #@canvas.enableAnnotations(true, true) @canvas.addListener "statereadychange", ()-> me.session = new ops.Session(me.canvas) @@ -24,7 +69,7 @@ class OpenPage extends this.OS.GUI.BaseApplication caretAvatarsInitiallyVisible: false, caretBlinksOnRangeSelect: true - me.editorSession = new OpenPage.EditorSession(me.session,userid, { + me.editorSession = new OpenPage.EditorSession(me.session,me.userid, { viewOptions: viewOptions, directTextStylingEnabled: true, directParagraphStylingEnabled: true, @@ -36,25 +81,181 @@ class OpenPage extends this.OS.GUI.BaseApplication zoomingEnabled: true, reviewModeEnabled: false }) + # basic format + me.directFormattingCtl = me.editorSession.sessionController.getDirectFormattingController() + me.directFormattingCtl.subscribe gui.DirectFormattingController.textStylingChanged, me.textStylingChanged + me.directFormattingCtl.subscribe gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged + # hyper link controller + me.hyperlinkController = me.editorSession.sessionController.getHyperlinkController() + me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalCursorMoved, ()-> me.updateHyperlinkButtons() + me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalParagraphChanged, ()-> me.updateHyperlinkButtons() + me.eventSubscriptions.addFrameSubscription me.editorSession, OpenPage.EditorSession.signalParagraphStyleModified, ()-> me.updateHyperlinkButtons() + me.editorSession.sessionController.setUndoManager new gui.TrivialUndoManager() - me.editorSession.sessionController.getUndoManager().subscribe gui.UndoManager.signalDocumentModifiedChanged, (mod) -> - me.eventNotifier.emit "documentModifiedChanged", mod - me.editorSession.sessionController.getMetadataController().subscribe gui.MetadataController.signalMetadataChanged, (changes) -> - me.eventNotifier.emit "metadataChanged", changes + me.editorSession.sessionController.getUndoManager().subscribe gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged + me.editorSession.sessionController.getMetadataController().subscribe gui.MetadataController.signalMetadataChanged, me.metaChanged op = new ops.OpAddMember() op.init { - memberid: userid, + memberid: me.userid, setProperties:{ "fullName": "Xuan Sang LE", "color": "blue" } } me.session.enqueue([op]) + me.initFontList me.editorSession.getDeclaredFonts() me.editorSession.sessionController.insertLocalCursor() me.editorSession.sessionController.startEditing() - me.editorSession.sessionController.getEventManager().focus() - @canvas.load "#{@_api.handler.get}/home://Downloads/welcome.odt" - @eventNotifier.subscribe "documentModifiedChanged", (d) -> - console.log "document is modified" + #console.log me.editorSession.getDeclaredFonts() + # + + initFontList: (list) -> + v.text = v.name for v in list + @basictool.fonts.set "items", list + + updateToolbar: (changes) -> + # basic style + (@basictool.bold.set "selected", changes.isBold) if changes.hasOwnProperty 'isBold' + (@basictool.italic.set "selected", changes.isItalic) if changes.hasOwnProperty 'isItalic' + (@basictool.underline.set "selected", changes.hasUnderline) if changes.hasOwnProperty 'hasUnderline' + (@basictool.strike.set "selected", changes.hasStrikeThrough) if changes.hasOwnProperty 'hasStrikeThrough' + (@basictool.fontsize.set "value", changes.fontSize) if changes.hasOwnProperty "fontSize" + @selectFont changes.fontName if changes.hasOwnProperty "fontName" + #pharagraph style + @basictool.al.set "selected", changes.isAlignedLeft if changes.hasOwnProperty "isAlignedLeft" + @basictool.ar.set "selected", changes.isAlignedRight if changes.hasOwnProperty "isAlignedRight" + @basictool.ac.set "selected", changes.isAlignedCenter if changes.hasOwnProperty "isAlignedCenter" + @basictool.aj.set "selected", changes.isAlignedJustified if changes.hasOwnProperty "isAlignedJustified" + + updateHyperlinkButtons: (e) -> + selectedLinks = @editorSession.getSelectedHyperlinks() + @basictool.unlink.set "enable", selectedLinks.length > 0 + + selectFont: (name) -> + items = @basictool.fonts.get "items" + item = i for v, i in items when v.name is name + @basictool.fonts.set "selected", item + + editorFocus: () -> + @editorSession.sessionController.getEventManager().focus() + bold: (e) -> + #console.log @, e + @directFormattingCtl.setBold (not @basictool.bold.get "selected") + + italic: (e) -> + @directFormattingCtl.setItalic (not @basictool.italic.get "selected") + + underline: (e) -> + @directFormattingCtl.setHasUnderline (not @basictool.underline.get "selected") + + strike: (e) -> + @directFormattingCtl.setHasStrikethrough (not @basictool.strike.get "selected") + + fonts: (e) -> + @directFormattingCtl.setFontName e.data.name + + fontsize: (e) -> + @directFormattingCtl.setFontSize e + + al: (e) -> + @directFormattingCtl.alignParagraphLeft() + + ar: (e) -> + @directFormattingCtl.alignParagraphRight() + + ac: (e) -> + @directFormattingCtl.alignParagraphCenter() + + aj: (e) -> + @directFormattingCtl.alignParagraphJustified() + + indent: (e) -> + @directFormattingCtl.indent() + + outdent: (e) -> + @directFormattingCtl.outdent() + + link: (e) -> + # get the link first + me = @ + textSerializer = new odf.TextSerializer() + selection = @editorSession.getSelectedRange() + linksInSelection = @editorSession.getSelectedHyperlinks() + linkTarget = if linksInSelection[0] then odf.OdfUtils.getHyperlinkTarget(linksInSelection[0]) else "http://" + data = + link: linkTarget, + text: "", + readonly: true, + action: "new" + if selection and selection.collapsed and linksInSelection.length == 1 + # selection is collapsed within a single link + # text in this case is read only + data.text = textSerializer.writeToString linksInSelection[0] + data.action = "edit" + else if selection and !selection.collapsed + # user select part of link or a block of text + # user convert a selection to a link + data.text = textSerializer.writeToString selection.cloneContents() + else + data.readonly = false + @openDialog new HyperLinkDialog(), (d) -> + selectionController = me.editorSession.sessionController.getSelectionController() + if d.readonly + # edit the existing link + if d.action is "edit" + selectedLinkRange = selection.cloneRange() + selectedLinkRange.selectNode(linksInSelection[0]) + selectionController.selectRange(selectedLinkRange, true) + me.hyperlinkController.removeHyperlinks() + me.hyperlinkController.addHyperlink d.link + else + me.hyperlinkController.addHyperlink d.link, d.text + linksInSelection = me.editorSession.getSelectedHyperlinks() + selectedLinkRange = selection.cloneRange() + selectedLinkRange.selectNode(linksInSelection[0]) + selectionController.selectRange(selectedLinkRange, true) + , "__(Insert/edit link)", data + + unlink: (e) -> + @hyperlinkController.removeHyperlinks() + + closeDocument: () -> + # finish editing + return unless @editorSession and @session + me = @ + @eventSubscriptions.unsubscribeAll() + @editorSession.sessionController.endEditing() + @editorSession.sessionController.removeLocalCursor() + # remove user + op = new ops.OpRemoveMember() + op.init { + memberid: @userid + } + @session.enqueue [op] + # close the session + @session.close (e) -> + return (me.error "Cannot close session " + e) if e + me.editorSession.sessionController.getMetadataController().unsubscribe gui.MetadataController.signalMetadataChanged, me.metaChanged + me.editorSession.sessionController.getUndoManager().unsubscribe gui.UndoManager.signalDocumentModifiedChanged, me.documentChanged + me.directFormattingCtl.unsubscribe gui.DirectFormattingController.textStylingChanged, me.textStylingChanged + me.directFormattingCtl.unsubscribe gui.DirectFormattingController.paragraphStylingChanged, me.textStylingChanged + # destry editorSession + me.editorSession.destroy (e) -> + return (me.error "Cannot destroy editor session " + e) if e + me.editorSession = undefined + # destroy session + me.session.destroy (e) -> + return (me.error "Cannot destroy document session " + e) if e + core.Async.destroyAll [me.canvas.destroy], (e) -> + return me.error "Cannot destroy canvas" + e if e + me.notify "Document closed" + me.session = undefined + me.directFormattingCtl = undefined + # + + + cleanup: (e) -> + @closeDocument() + this.OS.register "OpenPage", OpenPage \ No newline at end of file diff --git a/OpenPage/css/main.css b/OpenPage/css/main.css index 3364df1..5affa7c 100644 --- a/OpenPage/css/main.css +++ b/OpenPage/css/main.css @@ -1,6 +1,42 @@ afx-app-window[data-id="OpenPage"] div[data-id="container"] { overflow: auto; - margin:0 auto; - padding:0px + margin:0px; + padding:0px; + padding-top: 10px; + padding-bottom: 10px; + text-align: center; + background-color: #f2f1f0; +} + +afx-app-window[data-id="OpenPage"] div[data-id="odfcanvas"] +{ + cursor: text; + margin:auto; + box-shadow: 1px 1px 3px 3px #9f9F9F; +} + +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] +{ + background-color: #f5f5f5; + border: 1px solid #eaeaea; + box-shadow: 3px 3px 3px #9f9F9F; +} +afx-app-window[data-id="HyperLinkDialog"] afx-label.header span +{ + font-weight: bold; +} +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button{ + border: 1px solid #f5f5f5; + background-color: transparent; + width:100%; + height: 100%; +} + +afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button button:hover, afx-app-window[data-id="OpenPage"] afx-hbox[data-id="toolbox"] afx-button.btactive button +{ + border: 1px solid #759DC0; + background-color: transparent; + border-radius:5px; + color:#759DC0; } \ No newline at end of file diff --git a/OpenPage/project.apj b/OpenPage/project.apj index 079f8e8..dd58840 100644 --- a/OpenPage/project.apj +++ b/OpenPage/project.apj @@ -1 +1 @@ -{"name":"OpenPage","root":"home://Documents/workspace/antosdk-apps/OpenPage","css":["css/main.css"],"javascripts":["javascripts/webodf.js","javascripts/EditorSession.js"],"coffees":["coffees/main.coffee"],"copies":["assets/scheme.html","package.json","README.md"]} \ No newline at end of file +{"name":"OpenPage","root":"home://myws/antosdk-apps/OpenPage","css":["css/main.css"],"javascripts":["javascripts/webodf.js","javascripts/EditorSession.js"],"coffees":["coffees/main.coffee","coffees/dialogs.coffee"],"copies":["assets/scheme.html","package.json","README.md"]} \ No newline at end of file