calc: added support for hidden sheets and validation of cell content

Change-Id: I5db971b8826de7d5be2f88354925cd107082da77
Reviewed-on: https://gerrit.libreoffice.org/49112
Reviewed-by: Marco Cecchetti <mrcekets@gmail.com>
Tested-by: Marco Cecchetti <mrcekets@gmail.com>
This commit is contained in:
Marco Cecchetti 2018-02-01 16:36:24 +01:00 committed by Marco Cecchetti
parent 602923d1f8
commit d887b08d60
8 changed files with 123 additions and 4 deletions

View file

@ -306,6 +306,9 @@ struct _LibreOfficeKitDocumentClass
int nType, int nType,
const char* pText); const char* pText);
/// @see lok::Document::getPartInfo().
char* (*getPartInfo) (LibreOfficeKitDocument* pThis, int nPart);
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
}; };

View file

@ -13,6 +13,8 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <Util.hpp>
#define LOK_USE_UNSTABLE_API #define LOK_USE_UNSTABLE_API
#include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <LibreOfficeKit/LibreOfficeKitEnums.h>
@ -140,6 +142,34 @@ namespace LOKitHelper
if (type == LOK_DOCTYPE_SPREADSHEET || type == LOK_DOCTYPE_PRESENTATION) if (type == LOK_DOCTYPE_SPREADSHEET || type == LOK_DOCTYPE_PRESENTATION)
{ {
if (type == LOK_DOCTYPE_SPREADSHEET)
{
std::ostringstream hposs;
for (int i = 0; i < parts; ++i)
{
ptrValue = loKitDocument->pClass->getPartInfo(loKitDocument, i);
std::string partinfo(ptrValue);
std::free(ptrValue);
const auto aPartInfo = Util::JsonToMap(partinfo);
for (const auto prop: aPartInfo)
{
const std::string& name = prop.first;
if (name == "visible")
{
if (prop.second == "0")
hposs << i << ",";
}
}
}
std::string hiddenparts = hposs.str();
if (!hiddenparts.empty())
{
hiddenparts.pop_back();
oss << " hiddenparts=" << hiddenparts;
}
}
for (int i = 0; i < parts; ++i) for (int i = 0; i < parts; ++i)
{ {
oss << "\n"; oss << "\n";

View file

@ -364,6 +364,7 @@ L.Control.Menubar = L.Control.extend({
{uno: '.uno:DataSort'}, {uno: '.uno:DataSort'},
{uno: '.uno:SortAscending'}, {uno: '.uno:SortAscending'},
{uno: '.uno:SortDescending'}, {uno: '.uno:SortDescending'},
{uno: '.uno:Validation'},
{type: 'separator'}, {type: 'separator'},
{uno: '.uno:DataFilterAutoFilter'}, {uno: '.uno:DataFilterAutoFilter'},
{name: _UNO('.uno:FilterMenu', 'spreadsheet'), type: 'menu', menu: [ {name: _UNO('.uno:FilterMenu', 'spreadsheet'), type: 'menu', menu: [

View file

@ -68,7 +68,19 @@ L.Control.Tabs = L.Control.extend({
map.renamePage(data.sheetname, nPos); map.renamePage(data.sheetname, nPos);
} }
}); });
}} }},
'showsheets': {
name: _UNO('.uno:Show', 'spreadsheet', true),
callback: function() {
map.showPage();
}
},
'hiddensheets': {
name: _UNO('.uno:Hide', 'spreadsheet', true),
callback: function() {
map.hidePage();
}
}
}, },
zIndex: 1000 zIndex: 1000
}); });
@ -103,6 +115,8 @@ L.Control.Tabs = L.Control.extend({
ssTabScroll.id = 'spreadsheet-tab-scroll'; ssTabScroll.id = 'spreadsheet-tab-scroll';
for (var i = 0; i < parts; i++) { for (var i = 0; i < parts; i++) {
if (e.hiddenParts.indexOf(i) !== -1)
continue;
var id = 'spreadsheet-tab' + i; var id = 'spreadsheet-tab' + i;
var tab = L.DomUtil.create('div', 'spreadsheet-tab', ssTabScroll); var tab = L.DomUtil.create('div', 'spreadsheet-tab', ssTabScroll);
tab.innerHTML = e.partNames[i]; tab.innerHTML = e.partNames[i];

View file

@ -233,6 +233,10 @@ L.Map.include({
return; return;
} }
if (this.getDocType() === 'spreadsheet' && docLayer._parts <= docLayer.hiddenParts() + 1) {
return;
}
this.fire('deletepage', { this.fire('deletepage', {
selectedPart: docLayer._selectedPart, selectedPart: docLayer._selectedPart,
parts: docLayer._parts parts: docLayer._parts
@ -269,6 +273,30 @@ L.Map.include({
} }
}, },
showPage: function () {
if (this.getDocType() === 'spreadsheet' && this.hasAnyHiddenPart()) {
this._socket.sendMessage('uno .uno:Show');
}
},
hidePage: function () {
if (this.getDocType() === 'spreadsheet' && this.getNumberOfVisibleParts() > 1) {
this._socket.sendMessage('uno .uno:Hide');
}
},
isHiddenPart: function (part) {
if (this.getDocType() !== 'spreadsheet')
return false;
return this._docLayer.isHiddenPart(part);
},
hasAnyHiddenPart: function () {
if (this.getDocType() !== 'spreadsheet')
return false;
return this._docLayer.hasAnyHiddenPart();
},
getNumberOfPages: function () { getNumberOfPages: function () {
return this._docLayer._pages; return this._docLayer._pages;
}, },
@ -277,6 +305,20 @@ L.Map.include({
return this._docLayer._parts; return this._docLayer._parts;
}, },
getNumberOfVisibleParts: function () {
return this.getNumberOfParts() - this._docLayer.hiddenParts();
},
getHiddenPartNames: function () {
var partNames = this._docLayer._partNames;
var names = [];
for (var i = 0; i < partNames.length; ++i) {
if (this.isHiddenPart(i))
names.push(partNames[i]);
}
return names.join(',');
},
getCurrentPageNumber: function () { getCurrentPageNumber: function () {
return this._docLayer._currentPage; return this._docLayer._currentPage;
}, },

View file

@ -904,6 +904,13 @@ L.Socket = L.Class.extend({
else if (tokens[i].substring(0, 10) === 'rectangle=') { else if (tokens[i].substring(0, 10) === 'rectangle=') {
command.rectangle = tokens[i].substring(10); command.rectangle = tokens[i].substring(10);
} }
else if (tokens[i].substring(0, 12) === 'hiddenparts=') {
var hiddenparts = tokens[i].substring(12).split(',');
command.hiddenparts = [];
hiddenparts.forEach(function (item) {
command.hiddenparts.push(parseInt(item));
});
}
} }
if (command.tileWidth && command.tileHeight && this._map._docLayer) { if (command.tileWidth && command.tileHeight && this._map._docLayer) {
var defaultZoom = this._map.options.zoom; var defaultZoom = this._map.options.zoom;

View file

@ -5,8 +5,8 @@
L.CalcTileLayer = L.TileLayer.extend({ L.CalcTileLayer = L.TileLayer.extend({
STD_EXTRA_WIDTH: 113, /* 2mm extra for optimal width, STD_EXTRA_WIDTH: 113, /* 2mm extra for optimal width,
* 0.1986cm with TeX points, * 0.1986cm with TeX points,
* 0.1993cm with PS points. */ * 0.1993cm with PS points. */
twipsToHMM: function (twips) { twipsToHMM: function (twips) {
return (twips * 127 + 36) / 72; return (twips * 127 + 36) / 72;
@ -103,6 +103,23 @@ L.CalcTileLayer = L.TileLayer.extend({
} }
}, },
isHiddenPart: function (part) {
if (!this._hiddenParts)
return false;
return this._hiddenParts.indexOf(part) !== -1;
},
hiddenParts: function () {
if (!this._hiddenParts)
return 0;
return this._hiddenParts.length;
},
hasAnyHiddenPart: function () {
if (!this._hiddenParts)
return false;
return this.hiddenParts() !== 0;
},
_onAnnotationCancel: function (e) { _onAnnotationCancel: function (e) {
if (e.annotation._data.id === 'new') { if (e.annotation._data.id === 'new') {
this.hideAnnotation(e.annotation._tag); this.hideAnnotation(e.annotation._tag);
@ -333,7 +350,7 @@ L.CalcTileLayer = L.TileLayer.extend({
_onSetPartMsg: function (textMsg) { _onSetPartMsg: function (textMsg) {
var part = parseInt(textMsg.match(/\d+/g)[0]); var part = parseInt(textMsg.match(/\d+/g)[0]);
if (part !== this._selectedPart) { if (part !== this._selectedPart && !this.isHiddenPart(part)) {
this._map.setPart(part, true); this._map.setPart(part, true);
this._map.fire('setpart', {selectedPart: this._selectedPart}); this._map.fire('setpart', {selectedPart: this._selectedPart});
// TODO: test it! // TODO: test it!
@ -401,6 +418,7 @@ L.CalcTileLayer = L.TileLayer.extend({
else { else {
this._updateMaxBounds(true); this._updateMaxBounds(true);
} }
this._hiddenParts = command.hiddenparts || [];
this._documentInfo = textMsg; this._documentInfo = textMsg;
var partNames = textMsg.match(/[^\r\n]+/g); var partNames = textMsg.match(/[^\r\n]+/g);
// only get the last matches // only get the last matches
@ -410,6 +428,7 @@ L.CalcTileLayer = L.TileLayer.extend({
parts: this._parts, parts: this._parts,
docType: this._docType, docType: this._docType,
partNames: this._partNames, partNames: this._partNames,
hiddenParts: this._hiddenParts,
source: 'status' source: 'status'
}); });
this._resetPreFetching(true); this._resetPreFetching(true);

View file

@ -78,6 +78,7 @@ var unoCommandsArray = {
GroupOutlineMenu:{spreadsheet:{menu:_('~Group and Outline'),},}, GroupOutlineMenu:{spreadsheet:{menu:_('~Group and Outline'),},},
Grow:{global:{menu:_('Increase Size'),},}, Grow:{global:{menu:_('Increase Size'),},},
HelpMenu:{global:{menu:_('~Help'),},}, HelpMenu:{global:{menu:_('~Help'),},},
Hide:{spreadsheet:{menu:_('~Hide Sheet'),},},
HideColumn:{spreadsheet:{context:_('H~ide Columns'),menu:_('~Hide'),},}, HideColumn:{spreadsheet:{context:_('H~ide Columns'),menu:_('~Hide'),},},
HideDetail:{global:{menu:_('~Hide Details'),},}, HideDetail:{global:{menu:_('~Hide Details'),},},
HideRow:{spreadsheet:{context:_('H~ide Rows'),menu:_('H~ide'),},}, HideRow:{spreadsheet:{context:_('H~ide Rows'),menu:_('H~ide'),},},
@ -196,6 +197,7 @@ var unoCommandsArray = {
SetOptimalRowHeight:{spreadsheet:{menu:_('~Optimal Height...'),},text:{menu:_('Optimal Row Height'),},}, SetOptimalRowHeight:{spreadsheet:{menu:_('~Optimal Height...'),},text:{menu:_('Optimal Row Height'),},},
Shadowed:{global:{menu:_('Shadow'),},}, Shadowed:{global:{menu:_('Shadow'),},},
SheetMenu:{spreadsheet:{menu:_('~Sheet'),},}, SheetMenu:{spreadsheet:{menu:_('~Sheet'),},},
Show:{spreadsheet:{menu:_('~Show Sheet...'),},},
ShowColumn:{spreadsheet:{context:_('S~how Columns'),menu:_('~Show'),},}, ShowColumn:{spreadsheet:{context:_('S~how Columns'),menu:_('~Show'),},},
ShowDetail:{global:{menu:_('~Show Details'),},}, ShowDetail:{global:{menu:_('~Show Details'),},},
ShowRow:{spreadsheet:{context:_('Sho~w Rows'),menu:_('~Show'),},}, ShowRow:{spreadsheet:{context:_('Sho~w Rows'),menu:_('~Show'),},},
@ -232,6 +234,7 @@ var unoCommandsArray = {
Ungroup:{global:{menu:_('~Ungroup...'),},}, Ungroup:{global:{menu:_('~Ungroup...'),},},
UpSearch:{global:{menu:_('Find Previous'),},}, UpSearch:{global:{menu:_('Find Previous'),},},
UpdateCurIndex:{text:{context:_('Update index'),menu:_('Current ~Index'),},}, UpdateCurIndex:{text:{context:_('Update index'),menu:_('Current ~Index'),},},
Validation:{spreadsheet:{menu:_('~Validity...'),},},
ViewMenu:{global:{menu:_('~View'),},}, ViewMenu:{global:{menu:_('~View'),},},
WordCountDialog:{text:{menu:_('~Word Count...'),},}, WordCountDialog:{text:{menu:_('~Word Count...'),},},
WrapAnchorOnly:{text:{menu:_('~First Paragraph'),},}, WrapAnchorOnly:{text:{menu:_('~First Paragraph'),},},