loleaflet/src/control/Control.Menubar.js | 8 - loleaflet/src/layer/AnnotationManager.js | 213 +++++++++++++++++++++++-------- loleaflet/src/unocommands.js | 11 - 3 files changed, 171 insertions(+), 61 deletions(-)
New commits: commit 4071f38635099a328ff03292d9da4ec0652bb0f6 Author: Scott Clarke <scott.cla...@codethink.co.uk> AuthorDate: Thu May 23 17:03:15 2019 +0100 Commit: Henry Castro <hcas...@collabora.com> CommitDate: Mon Aug 19 16:45:22 2019 +0200 Add ability to show/hide resolved comments Add 'View:Resolved Comments' menu item Hide all comments in a thread when resolving them Connect Show/Hide resolved annotations to the annotation manager Change-Id: Ib646bdea3dfc30fde6a11aa13562db147afd7ae0 Co-authored-by: Jim MacArthur <jim.macart...@codethink.co.uk> Reviewed-on: https://gerrit.libreoffice.org/76758 Reviewed-by: Henry Castro <hcas...@collabora.com> Tested-by: Henry Castro <hcas...@collabora.com> diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index d968685f5..3a845f926 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -63,7 +63,9 @@ L.Control.Menubar = L.Control.extend({ {name: _('Reset zoom'), id: 'zoomreset', type: 'action'}, {name: _('Show Ruler'), id: 'showruler', type: 'action'}, {type: 'separator'}, - {uno: '.uno:ControlCodes'} + {uno: '.uno:ControlCodes'}, + {type: 'separator'}, + {name: _UNO('.uno:ShowResolvedAnnotations', 'text'), id: 'showresolved', type: 'action'} ] }, {name: _UNO('.uno:InsertMenu', 'text'), type: 'menu', menu: [ @@ -445,7 +447,7 @@ L.Control.Menubar = L.Control.extend({ 'downloadas-pdf', 'downloadas-odt', 'downloadas-doc', 'downloadas-docx', 'downloadas-rtf', // file menu 'downloadas-odp', 'downloadas-ppt', 'downloadas-pptx', 'print', // file menu 'downloadas-ods', 'downloadas-xls', 'downloadas-xlsx', 'closedocument', // file menu - 'fullscreen', 'zoomin', 'zoomout', 'zoomreset', // view menu + 'fullscreen', 'zoomin', 'zoomout', 'zoomreset', 'showresolved', // view menu 'about', 'keyboard-shortcuts' // help menu ] }, @@ -765,6 +767,8 @@ L.Control.Menubar = L.Control.extend({ this._map.fire('postMessage', {msgId: 'UI_InsertGraphic'}); } else if (id === 'zoomin' && this._map.getZoom() < this._map.getMaxZoom()) { this._map.zoomIn(1); + } else if (id === 'showresolved') { + this._map.showResolvedComments(item); } else if (id === 'zoomout' && this._map.getZoom() > this._map.getMinZoom()) { this._map.zoomOut(1); } else if (id === 'zoomreset') { diff --git a/loleaflet/src/layer/AnnotationManager.js b/loleaflet/src/layer/AnnotationManager.js index fcd0abbd1..da1161f06 100644 --- a/loleaflet/src/layer/AnnotationManager.js +++ b/loleaflet/src/layer/AnnotationManager.js @@ -16,6 +16,7 @@ L.AnnotationManager = L.Class.extend({ initialize: function (map, options) { this._map = map; this._items = []; + this._hiddenItems = 0; this._selected = null; L.setOptions(this, options); this._arrow = L.polyline([], {color: 'darkblue', weight: 1}); @@ -23,10 +24,10 @@ L.AnnotationManager = L.Class.extend({ this._map.on('AnnotationCancel', this._onAnnotationCancel, this); this._map.on('AnnotationClick', this._onAnnotationClick, this); this._map.on('AnnotationReply', this._onAnnotationReply, this); - this._map.on('AnnotationResolve', this._onAnnotationResolve, this); this._map.on('AnnotationSave', this._onAnnotationSave, this); this._map.on('RedlineAccept', this._onRedlineAccept, this); this._map.on('RedlineReject', this._onRedlineReject, this); + this._showResolved = false; }, // Remove only text comments from the document (excluding change tracking comments) @@ -126,6 +127,10 @@ L.AnnotationManager = L.Class.extend({ comment.avatar = this._map._viewInfoByUserName[comment.author].userextrainfo.avatar; } this._items.push(L.annotation(this._map.options.docBounds.getSouthEast(), comment).addTo(this._map)); + this.updateResolvedState(this._items[this._items.length - 1]); + if (this._items[this._items.length - 1]._data.resolved === 'true') { + this._hiddenItems++; + } } if (this._items.length > 0) { if (!ordered) { @@ -210,7 +215,7 @@ L.AnnotationManager = L.Class.extend({ }, getBounds: function () { - if (this._items.length <= 0) + if (this._items.length <= 0 || this._items.length === this._hiddenItems) return null; var allCommentsBounds; @@ -283,7 +288,7 @@ L.AnnotationManager = L.Class.extend({ }, updateDocBounds: function () { - if (this._items.length === 0) { + if (this._items.length === 0 || this._items.length === this._hiddenItems) { this._map.fire('updatemaxbounds', {sizeChanged: true}); } }, @@ -343,13 +348,15 @@ L.AnnotationManager = L.Class.extend({ idx = 0; for (idx = 0; idx < commentThread.length; ++idx) { - latLng = this._map.layerPointToLatLng(pt); - (new L.PosAnimation()).run(commentThread[idx]._container, this._map.latLngToLayerPoint(latLng)); - commentThread[idx].setLatLng(latLng, /*skip check bounds*/ true); - commentThread[idx].show(); + if (commentThread[idx]._data.resolved !== 'true' || this._showResolved) { + latLng = this._map.layerPointToLatLng(pt); + (new L.PosAnimation()).run(commentThread[idx]._container, this._map.latLngToLayerPoint(latLng)); + commentThread[idx].setLatLng(latLng, /*skip check bounds*/ true); + commentThread[idx].show(); - var commentBounds = commentThread[idx].getBounds(); - pt = pt.add([0, commentBounds.getSize().y]); + var commentBounds = commentThread[idx].getBounds(); + pt = pt.add([0, commentBounds.getSize().y]); + } } }, @@ -383,13 +390,15 @@ L.AnnotationManager = L.Class.extend({ idx = 0; for (idx = 0; idx < commentThread.length; ++idx) { - latLng = this._map.layerPointToLatLng(pt); - (new L.PosAnimation()).run(commentThread[idx]._container, this._map.latLngToLayerPoint(latLng)); - commentThread[idx].setLatLng(latLng, /*skip check bounds*/ true); - commentThread[idx].show(); + if (commentThread[idx]._data.resolved !== 'true' || this._showResolved) { + latLng = this._map.layerPointToLatLng(pt); + (new L.PosAnimation()).run(commentThread[idx]._container, this._map.latLngToLayerPoint(latLng)); + commentThread[idx].setLatLng(latLng, /*skip check bounds*/ true); + commentThread[idx].show(); - var commentBounds = commentThread[idx].getBounds(); - pt = pt.add([0, commentBounds.getSize().y]); + var commentBounds = commentThread[idx].getBounds(); + pt = pt.add([0, commentBounds.getSize().y]); + } } }, @@ -457,21 +466,23 @@ L.AnnotationManager = L.Class.extend({ // Adjust child comments too, if any for (idx = selectIndexFirst + 1; idx <= selectIndexLast; idx++) { - if (zoom) { - this._items[idx]._data.anchorPix = this._map._docLayer._twipsToPixels(this._items[idx]._data.anchorPos.min); + if (this._items[idx]._data.resolved !== 'true' || this._showResolved) { + if (zoom) { + this._items[idx]._data.anchorPix = this._map._docLayer._twipsToPixels(this._items[idx]._data.anchorPos.min); + } + latlng = this._map.layerPointToLatLng(layoutBounds.getBottomLeft()); + (new L.PosAnimation()).run(this._items[idx]._container, layoutBounds.getBottomLeft()); + this._items[idx].setLatLng(latlng, /*skip check bounds*/ true); + var commentBounds = this._items[idx].getBounds(); + layoutBounds.extend(layoutBounds.max.add([0, commentBounds.getSize().y])); } - latlng = this._map.layerPointToLatLng(layoutBounds.getBottomLeft()); - (new L.PosAnimation()).run(this._items[idx]._container, layoutBounds.getBottomLeft()); - this._items[idx].setLatLng(latlng, /*skip check bounds*/ true); - - var commentBounds = this._items[idx].getBounds(); - layoutBounds.extend(layoutBounds.max.add([0, commentBounds.getSize().y])); } layoutBounds.min = layoutBounds.min.add([this.options.marginX, 0]); layoutBounds.max = layoutBounds.max.add([this.options.marginX, 0]); layoutBounds.extend(layoutBounds.min.subtract([0, this.options.marginY])); layoutBounds.extend(layoutBounds.max.add([0, this.options.marginY])); + for (idx = selectIndexFirst - 1; idx >= 0;) { var commentThread = []; var tmpIdx = idx; @@ -479,15 +490,23 @@ L.AnnotationManager = L.Class.extend({ if (zoom) { this._items[idx]._data.anchorPix = this._map._docLayer._twipsToPixels(this._items[idx]._data.anchorPos.min); } - commentThread.push(this._items[tmpIdx]); + if (this._items[tmpIdx]._data.resolved !== 'true' || this._showResolved) { + commentThread.push(this._items[tmpIdx]); + } + tmpIdx = tmpIdx - 1; } while (tmpIdx >= 0 && this._items[tmpIdx]._data.id === this._items[tmpIdx + 1]._data.parent); - commentThread.reverse(); - // All will have some anchor position - this.layoutUp(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); - idx = idx - commentThread.length; + if (commentThread.length > 0) { + commentThread.reverse(); + // All will have some anchor position + this.layoutUp(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); + idx = idx - commentThread.length; + } else { + idx = tmpIdx; + } } + for (idx = selectIndexLast + 1; idx < this._items.length;) { commentThread = []; tmpIdx = idx; @@ -495,20 +514,29 @@ L.AnnotationManager = L.Class.extend({ if (zoom) { this._items[idx]._data.anchorPix = this._map._docLayer._twipsToPixels(this._items[idx]._data.anchorPos.min); } - commentThread.push(this._items[tmpIdx]); + if (this._items[tmpIdx]._data.resolved !== 'true' || this._showResolved) { + commentThread.push(this._items[tmpIdx]); + } + tmpIdx = tmpIdx + 1; } while (tmpIdx < this._items.length && this._items[tmpIdx]._data.parent === this._items[tmpIdx - 1]._data.id); + // All will have some anchor position - this.layoutDown(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); - idx = idx + commentThread.length; + if (commentThread.length > 0) { + this.layoutDown(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); + idx = idx + commentThread.length; + } else { + idx = tmpIdx; + } } if (!this._selected.isEdit()) { this._selected.show(); } - } else if (this._items.length > 0) { + } else if (this._items.length > 0) { // If nothing is selected, but there are comments: point = this._map.latLngToLayerPoint(this._map.unproject(L.point(topRight.x, this._items[0]._data.anchorPix.y))); layoutBounds = L.bounds(point, point); + // Pass over all comments present for (idx = 0; idx < this._items.length;) { commentThread = []; tmpIdx = idx; @@ -516,12 +544,20 @@ L.AnnotationManager = L.Class.extend({ if (zoom) { this._items[tmpIdx]._data.anchorPix = this._map._docLayer._twipsToPixels(this._items[tmpIdx]._data.anchorPos.min); } - commentThread.push(this._items[tmpIdx]); + // Add this item to the list of comments. + if (this._items[tmpIdx]._data.resolved !== 'true' || this._showResolved) { + commentThread.push(this._items[tmpIdx]); + } tmpIdx = tmpIdx + 1; + // Continue this loop, until we reach the last item, or an item which is not a direct descendant of the previous item. } while (tmpIdx < this._items.length && this._items[tmpIdx]._data.parent === this._items[tmpIdx - 1]._data.id); - this.layoutDown(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); - idx = idx + commentThread.length; + if (commentThread.length > 0) { + this.layoutDown(commentThread, this._map.unproject(L.point(topRight.x, commentThread[0]._data.anchorPix.y)), layoutBounds); + idx = idx + commentThread.length; + } else { + idx = tmpIdx; + } } } this._checkBounds(); @@ -546,6 +582,8 @@ L.AnnotationManager = L.Class.extend({ if (comment.parent && comment.parent > '0') { var parentIdx = this.getIndexOf(comment.parent); this._items.splice(parentIdx + 1, 0, annotation); + this.updateResolvedState(annotation); + this.showHideComment(annotation); } else { this._items.push(annotation); } @@ -575,7 +613,6 @@ L.AnnotationManager = L.Class.extend({ }, resolve: function (annotation) { - // This is called by WriteTileLayer var comment = { Id: { type: 'string', @@ -583,8 +620,36 @@ L.AnnotationManager = L.Class.extend({ } }; this._map.sendUnoCommand('.uno:ResolveComment', comment); - annotation.update(); - this.update(); + }, + + updateResolvedState: function (annotation) { + var threadIndexFirst = this.getRootIndexOf(annotation._data.id); + if (this._items[threadIndexFirst]._data.resolved !== annotation._data.resolved) { + annotation._data.resolved = this._items[threadIndexFirst]._data.resolved; + annotation.update(); + this.update(); + } + }, + + showHideComment: function (annotation) { + // This manually shows/hides comments + if (!this._showResolved) { + if (annotation.isVisible() && annotation._data.resolved === 'true') { + if (this._selected == annotation) { + this.unselect(); + } + annotation.hide(); + this._hiddenItems++; + annotation.update(); + } else if (!annotation.isVisible() && annotation._data.resolved === 'false') { + annotation.show(); + this._hiddenItems--; + annotation.update(); + } + this.layout(); + this.update(); + this.updateDocBounds(); + } }, remove: function (id) { @@ -711,6 +776,26 @@ L.AnnotationManager = L.Class.extend({ modified.update(); this.update(); } + } else if (action === 'Resolve') { + id = changetrack ? 'change-' + obj.redline.index : obj.comment.id; + var resolved = this.getItem(id); + if (resolved) { + var resolvedObj; + if (changetrack) { + if (!this.adjustRedLine(obj.redline)) { + // something wrong in this redline + return; + } + resolvedObj = obj.redline; + } else { + this.adjustComment(obj.comment); + resolvedObj = obj.comment; + } + resolved.setData(resolvedObj); + resolved.update(); + this.showHideComment(resolved); + this.update(); + } } }, @@ -747,22 +832,6 @@ L.AnnotationManager = L.Class.extend({ this._map.focus(); }, - _onAnnotationResolve: function (e) { - var comment = { - Id: { - type: 'string', - value: e.annotation._data.id - }, - Text: { - type: 'string', - value: e.annotation._data.reply - } - }; - this._map.sendUnoCommand('.uno:ResolveComment', comment); - this.unselect(); - this._map.focus(); - }, - _onAnnotationSave: function (e) { var comment; if (e.annotation._data.id === 'new') { @@ -881,6 +950,30 @@ L.AnnotationManager = L.Class.extend({ this._items[idx]._updateScaling(scaleFactor, this._initialLayoutData); } } + }, + + setViewResolved: function(state) { + this._showResolved = state; + + for (var idx = 0; idx < this._items.length;idx++) { + if (this._items[idx]._data.resolved === 'true') { + if (state==false) { + if (this._selected == this._items[idx]) { + this.unselect(); + } + this._items[idx].hide(); + this._hiddenItems++; + } else { + this._items[idx].show(); + this._hiddenItems--; + } + } + this._items[idx].update(); + } + this.layout(); + this.update(); + if (state === false) + this.updateDocBounds(); } }); @@ -900,6 +993,18 @@ L.Map.include({ id: 'new', // 'new' only when added by us avatar: avatar }); + }, + + showResolvedComments: function(item) { + var unoCommand = '.uno:ShowResolvedAnnotations'; + var on = $(item).hasClass('lo-menu-item-checked'); + this.sendUnoCommand(unoCommand); + this._docLayer._annotations.setViewResolved(!on); + if (on) { + $(item).removeClass('lo-menu-item-checked'); + } else { + $(item).addClass('lo-menu-item-checked'); + } } }); diff --git a/loleaflet/src/unocommands.js b/loleaflet/src/unocommands.js index bfef61bec..005f666b9 100644 --- a/loleaflet/src/unocommands.js +++ b/loleaflet/src/unocommands.js @@ -115,13 +115,13 @@ var unoCommandsArray = { InsertField:{text:{menu:_('~More Fields...'),},}, InsertFootnote:{text:{menu:_('~Footnote'),},}, InsertGraphic:{global:{context:_('Insert Image...'),menu:_('~Image...'),},}, - InsertHardHyphen:{global:{menu:_('Non-br~eaking Hyphen'),},}, + InsertHardHyphen:{global:{menu:_('Insert non-br~eaking hyphen'),},}, InsertHeaderFooterMenu:{text:{menu:_('He~ader and Footer'),},}, InsertIndexesEntry:{text:{menu:_('~Index Entry...'),},}, InsertLRM:{global:{menu:_('~Left-to-right Mark'),},}, InsertMenu:{global:{menu:_('~Insert'),},}, InsertNeutralParagraph:{text:{menu:_('Insert Unnumbered Entry'),},}, - InsertNonBreakingSpace:{global:{menu:_('~Non-breaking Space'),},}, + InsertNonBreakingSpace:{global:{menu:_('Insert ~non-breaking space'),},}, InsertObjectChart:{global:{context:_('Insert Chart'),menu:_('~Chart...'),},}, InsertPageCountField:{text:{menu:_('Page ~Count'),},}, InsertPageFooter:{text:{menu:_('Foote~r'),},}, @@ -135,7 +135,7 @@ var unoCommandsArray = { InsertRowsMenu:{spreadsheet:{menu:_('Insert ~Rows'),},}, InsertSection:{text:{menu:_('Se~ction...'),},}, InsertSlide:{presentation:{menu:_('~New Slide'),},}, - InsertSoftHyphen:{global:{menu:_('S~oft Hyphen'),},}, + InsertSoftHyphen:{global:{menu:_('Insert s~oft Hyphen'),},}, InsertSymbol:{global:{context:_('Insert Special Character'),menu:_('S~pecial Character...'),},}, InsertTimeField:{global:{menu:_('Time Field'),},text:{menu:_('~Time'),},}, InsertTitleField:{text:{menu:_('T~itle'),},}, @@ -185,11 +185,10 @@ var unoCommandsArray = { Redo:{global:{menu:_('~Redo'),},}, RejectAllTrackedChanges:{text:{menu:_('Reject All'),},}, Remove:{spreadsheet:{menu:_('~Delete Sheet...'),},}, - RemoveHyperlink:{text:{menu:_('Remove Hyperlink'),},}, + RemoveHyperlink:{global:{menu:_('~Remove Hyperlink'),},}, RemoveTableOf:{text:{menu:_('Delete index'),},}, RenameTable:{spreadsheet:{menu:_('~Rename Sheet...'),},}, ReplyComment:{global:{menu:_('Reply Comment'),},}, - ResolveComment:{global:{menu:_('Resolve Comment'),},}, ResetAttributes:{global:{menu:_('~Clear Direct Formatting'),},spreadsheet:{context:_('Clear Direct Formatting'),menu:_('Clear ~Direct Formatting'),},text:{context:_('Clear Direct Formatting'),menu:_('Clear ~Direct Formatting'),},}, RightPara:{global:{context:_('Align Right'),menu:_('Right'),},}, RotateLeft:{text:{menu:_('Rotate 90° ~Left'),},}, @@ -216,9 +215,11 @@ var unoCommandsArray = { Show:{spreadsheet:{menu:_('~Show Sheet...'),},}, ShowColumn:{spreadsheet:{context:_('S~how Columns'),menu:_('~Show'),},}, ShowDetail:{global:{menu:_('~Show Details'),},}, + ShowResolvedAnnotations:{text:{menu:_('Resolved Comments'),},}, ShowRow:{spreadsheet:{context:_('Sho~w Rows'),menu:_('~Show'),},}, ShowTrackedChanges:{text:{menu:_('~Show'),},}, Shrink:{global:{menu:_('Decrease Size'),},}, + Sidebar:{global:{menu:_('Sidebar'),},}, SlideMenu:{presentation:{menu:_('S~lide'),},}, SmallCaps:{global:{menu:_('Small capitals'),},}, SortAscending:{spreadsheet:{menu:_('Sort Ascending'),},}, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits