diff --git a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h index 244a8ea20..e620fb6c3 100644 --- a/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h +++ b/bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h @@ -710,6 +710,12 @@ typedef enum * the description. */ LOK_CALLBACK_JSDIALOG = 46, + + /** + * Send the list of functions whose name starts with the characters entered + * by the user. + */ + LOK_CALLBACK_CALC_FUNCTION_LIST = 47 } LibreOfficeKitCallbackType; @@ -832,6 +838,8 @@ static inline const char* lokCallbackTypeToString(int nType) return "LOK_CALLBACK_REFERENCE_MARKS"; case LOK_CALLBACK_JSDIALOG: return "LOK_CALLBACK_JSDIALOG"; + case LOK_CALLBACK_CALC_FUNCTION_LIST: + return "LOK_CALLBACK_CALC_FUNCTION_LIST"; } assert(!"Unknown LibreOfficeKitCallbackType type."); diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index 677505ad9..e254b94de 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -2470,6 +2470,9 @@ void ChildSession::loKitCallback(const int type, const std::string& payload) case LOK_CALLBACK_JSDIALOG: sendTextFrame("jsdialog: " + payload); break; + case LOK_CALLBACK_CALC_FUNCTION_LIST: + sendTextFrame("calcfunctionlist: " + payload); + break; #if !ENABLE_DEBUG // we want a compilation-time failure in the debug builds; but ERR in the diff --git a/loleaflet/css/mobilewizard.css b/loleaflet/css/mobilewizard.css index 22279d1ff..783d63d1e 100644 --- a/loleaflet/css/mobilewizard.css +++ b/loleaflet/css/mobilewizard.css @@ -314,7 +314,7 @@ .sub-menu-arrow { display: table-cell; padding-left: 10px; - padding-right: 20px; + padding-right: 10px; background: transparent; font-size: 1.5em; font-weight: bold; @@ -322,6 +322,28 @@ vertical-align: middle; } + .func-info-icon { + display: table-cell; + padding-left: 8px; + padding-right: 8px; + background: transparent; + font-size: 1.2em; + font-weight: bold; + color: #aaa !important; + vertical-align: middle; + border-radius: 100px; + border: solid 2px #aaa; + } + + .func-info-sig { + margin-left: 1em; + margin-bottom: 2em; + } + + .func-info-desc { + margin-left: 1em; + } + .entry-value { display: table-cell; vertical-align: middle; @@ -329,6 +351,7 @@ .ui-header-right { display: table; + margin-right: 10px; } .ui-header.level-1.mobile-wizard.ui-widget .ui-header-left span.menu-entry-with-icon { diff --git a/loleaflet/src/control/Control.JSDialogBuilder.js b/loleaflet/src/control/Control.JSDialogBuilder.js index 61befb59a..ba39f3d2d 100644 --- a/loleaflet/src/control/Control.JSDialogBuilder.js +++ b/loleaflet/src/control/Control.JSDialogBuilder.js @@ -42,6 +42,7 @@ L.Control.JSDialogBuilder = L.Control.extend({ this._controlHandlers['grid'] = this._gridHandler; this._controlHandlers['frame'] = this._frameHandler; this._controlHandlers['panel'] = this._panelHandler; + this._controlHandlers['calcfuncpanel'] = this._calcFuncListPanelHandler; this._controlHandlers['paneltabs'] = this._panelTabsHandler; this._controlHandlers['container'] = this._containerHandler; this._controlHandlers['window'] = this._containerHandler; @@ -270,6 +271,40 @@ L.Control.JSDialogBuilder = L.Control.extend({ } }, + _calcFunctionEntry: function(parentContainer, data, contentNode, builder) { + var sectionTitle = L.DomUtil.create('div', 'func-entry ui-header level-' + builder._currentDepth + ' mobile-wizard ui-widget', parentContainer); + $(sectionTitle).css('justify-content', 'space-between'); + if (data && data.id) + sectionTitle.id = data.id; + + var leftDiv = L.DomUtil.create('div', 'ui-header-left', sectionTitle); + var titleClass = 'func-name'; + var titleSpan = L.DomUtil.create('span', titleClass, leftDiv); + titleSpan.innerHTML = data.text; + + var rightDiv = L.DomUtil.create('div', 'ui-header-right', sectionTitle); + var arrowSpan = L.DomUtil.create('span', 'func-info-icon', rightDiv); + arrowSpan.innerHTML = 'i'; + + var contentDiv = L.DomUtil.create('div', 'ui-content level-' + builder._currentDepth + ' mobile-wizard', parentContainer); + contentDiv.title = data.text; + + builder._currentDepth++; + builder.build(contentDiv, [contentNode]); + builder._currentDepth--; + + $(contentDiv).hide(); + if (builder.wizard) { + $(rightDiv).click(function() { + builder.wizard.goLevelDown(contentDiv); + if (contentNode.onshow) + contentNode.onshow(); + }); + } else { + console.debug('Builder used outside of mobile wizard: please implement the click handler'); + } + }, + _explorableMenu: function(parentContainer, title, children, builder, customContent) { var sectionTitle = L.DomUtil.create('div', 'ui-header level-' + builder._currentDepth + ' mobile-wizard ui-widget', parentContainer); $(sectionTitle).css('justify-content', 'space-between'); @@ -317,6 +352,14 @@ L.Control.JSDialogBuilder = L.Control.extend({ return false; }, + _calcFuncListPanelHandler: function(parentContainer, data, builder) { + var contentNode = data.children[0]; + + builder._calcFunctionEntry(parentContainer, data, contentNode, builder); + + return false; + }, + _panelTabsHandler: function(parentContainer, data, builder) { var tabsContainer = L.DomUtil.create('div', 'ui-tabs mobile-wizard ui-widget'); var contentsContainer = L.DomUtil.create('div', 'ui-tabs-content mobile-wizard ui-widget', parentContainer); diff --git a/loleaflet/src/control/Control.MobileWizard.js b/loleaflet/src/control/Control.MobileWizard.js index d8ff8a61a..69205e60f 100644 --- a/loleaflet/src/control/Control.MobileWizard.js +++ b/loleaflet/src/control/Control.MobileWizard.js @@ -191,6 +191,10 @@ L.Control.MobileWizard = L.Control.extend({ $('#mobile-wizard').css('top', $('#spreadsheet-row-column-frame').css('top')); else $('#mobile-wizard').css('top', $('#document-container').css('top')); + } else if (data.id === 'funclist') { + $('#mobile-wizard').height('100%'); + $('#mobile-wizard').css('top', $('#spreadsheet-row-column-frame').css('top')); + $('#mobile-wizard').addClass('funcwizard'); } else { $('#mobile-wizard').height(this.options.maxHeight); $('#mobile-wizard').css('top', ''); diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 85c82b826..707a4d601 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -680,6 +680,9 @@ L.TileLayer = L.GridLayer.extend({ else if (textMsg.startsWith('jsdialog:')) { this._onJSDialogMsg(textMsg); } + else if (textMsg.startsWith('calcfunctionlist:')) { + this._onCalcFunctionListMsg(textMsg.substring('calcfunctionlist:'.length + 1)); + } }, toggleTileDebugModeImpl: function() { @@ -747,6 +750,43 @@ L.TileLayer = L.GridLayer.extend({ this._map.fire('cellformula', {formula: formula}); }, + _onCalcFunctionListMsg: function (textMsg) { + console.log('_onCalcFunctionList: textMsg: ' + textMsg); + var funcList = JSON.parse(textMsg); + this._closeMobileWizard(); + + var data = { + id: 'funclist', + type: '', + text: 'Functions', + enabled: true, + children: [] + }; + + var entries = data.children; + for (var idx in funcList) { + var func = funcList[idx]; + var name = func.signature.split('(')[0]; + var entry = { + id: '', + type: 'calcfuncpanel', + text: name, + enabled: true, + children: [] + } + entries.push(entry); + entries[entries.length-1].children[0] = { + id: '', + type: 'fixedtext', + text: '
' + func.signature + '
' + '
' + func.description + '
', + enabled: true, + style: 'func-info' + }; + } + + this._openMobileWizard(data); + }, + _onCursorVisibleMsg: function(textMsg) { var command = textMsg.match('cursorvisible: true'); this._isCursorVisible = command ? true : false;