Merge branch 'release/v9.1.0'

# Conflicts:
#	.github/workflows/rebuild-macros-tips.yaml
This commit is contained in:
Alexander Trofimov
2025-10-14 18:31:05 +03:00
1617 changed files with 197047 additions and 37159 deletions

View File

@ -513,7 +513,7 @@
if (typeof _config.document.fileType === 'string' && _config.document.fileType != '') {
_config.document.fileType = _config.document.fileType.toLowerCase();
var type = /^(?:(xls|xlsx|ods|csv|gsheet|xlsm|xlt|xltm|xltx|fods|ots|xlsb|sxc|et|ett|numbers)|(pps|ppsx|ppt|pptx|odp|gslides|pot|potm|potx|ppsm|pptm|fodp|otp|sxi|dps|dpt|key|odg)|(pdf|djvu|xps|oxps)|(doc|docx|odt|gdoc|txt|rtf|mht|htm|html|mhtml|epub|docm|dot|dotm|dotx|fodt|ott|fb2|xml|oform|docxf|sxw|stw|wps|wpt|pages|hwp|hwpx|md)|(vsdx|vssx|vstx|vsdm|vssm|vstm))$/
var type = /^(?:(xls|xlsx|ods|csv|gsheet|xlsm|xlt|xltm|xltx|fods|ots|xlsb|sxc|et|ett|numbers)|(pps|ppsx|ppt|pptx|odp|gslides|pot|potm|potx|ppsm|pptm|fodp|otp|sxi|dps|dpt|key|odg)|(pdf|djvu|xps|oxps)|(doc|docx|odt|gdoc|txt|rtf|mht|htm|html|mhtml|epub|docm|dot|dotm|dotx|fodt|ott|fb2|xml|oform|docxf|sxw|stw|wps|wpt|pages|hwp|hwpx|md|hml)|(vsdx|vssx|vstx|vsdm|vssm|vstm))$/
.exec(_config.document.fileType);
if (!type) {
window.alert("The \"document.fileType\" parameter for the config object is invalid. Please correct it.");
@ -669,16 +669,6 @@
});
};
var _processSaveResult = function(result, message) {
_sendCommand({
command: 'processSaveResult',
data: {
result: result,
message: message
}
});
};
// TODO: remove processRightsChange, use denyEditingRights
var _processRightsChange = function(enabled, message) {
_sendCommand({
@ -903,7 +893,6 @@
return {
showMessage : _showMessage,
processSaveResult : _processSaveResult,
processRightsChange : _processRightsChange,
denyEditingRights : _denyEditingRights,
refreshHistory : _refreshHistory,

View File

@ -313,10 +313,13 @@ div {
fileType = fileInfo.FileExtension ? fileInfo.FileExtension.substr(1) : fileType;
fileType = fileType.toLowerCase();
let customizationClose = !!(fileInfo.ClosePostMessage || fileInfo.CloseUrl);
const canEdit = (fileInfo.UserCanOnlyComment || fileInfo.UserCanWrite || fileInfo.UserCanReview);
//connector Nextcloud Office 8.4.5 (SupportsUpdate=undefined, UserCanWrite=true, UserCanNotWriteRelative=false)
let customizationSaveAs = (fileInfo.SupportsUpdate || fileInfo.UserCanWrite) && !fileInfo.UserCanNotWriteRelative;
let customizationSaveAs = (fileInfo.SupportsUpdate || canEdit) && !fileInfo.UserCanNotWriteRelative;
let customizationFormSubmit = queryParams.formsubmit === "1";
let permissionsEdit = !fileInfo.ReadOnly && fileInfo.UserCanWrite && !customizationFormSubmit;
let permissionsEdit = !fileInfo.ReadOnly && (!fileInfo.UserCanOnlyComment && fileInfo.UserCanWrite) && !customizationFormSubmit;
const permissionsReview = (fileInfo.UserCanOnlyComment || fileInfo.SupportsReviewing===false) ? false : (fileInfo.UserCanReview===false ? false : fileInfo.UserCanReview);
const permissionsComment = permissionsEdit || !!fileInfo.UserCanOnlyComment;
let permissionsFillForm = permissionsEdit || customizationFormSubmit;
sessionId = userAuth.userSessionId;
var config = {
@ -346,7 +349,8 @@ div {
},
"permissions": {
"edit": permissionsEdit,
"review": (fileInfo.SupportsReviewing===false) ? false : (fileInfo.UserCanReview===false ? false : fileInfo.UserCanReview),
"review": permissionsReview,
"comment": permissionsComment,
"copy": fileInfo.CopyPasteRestrictions!=="CurrentDocumentOnly" && fileInfo.CopyPasteRestrictions!=="BlockAll",
"print": !fileInfo.DisablePrint && !fileInfo.HidePrintOption,
"chat": queryParams.dchat!=="1",

View File

@ -59,10 +59,6 @@ if (window.Common === undefined) {
$me.trigger('applyeditrights', data);
},
'processSaveResult': function(data) {
$me.trigger('processsaveresult', data);
},
'processRightsChange': function(data) {
$me.trigger('processrightschange', data);
},

View File

@ -0,0 +1,350 @@
/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
+function() {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.Shortcuts = new(function() {
var localStorageKey = '',
actionsMap = {},
api = null;
var setApi = function(newApi) {
api = newApi;
if(window.DE) {
localStorageKey = 'de-shortcuts';
} else if(window.PDFE) {
localStorageKey = 'pdfe-shortcuts';
} else if(window.PE) {
localStorageKey = 'pe-shortcuts';
} else if(window.SSE) {
localStorageKey = 'sse-shortcuts';
} else if(window.VE) {
localStorageKey = 've-shortcuts';
}
_fillActionsMap();
api && _applyShortcutsInSDK();
};
var _keyCodeToKeyName = function(code) {
const specialKeys = {
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Ctrl',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
32: 'Space',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
44: 'PrintScreen',
45: 'Insert',
46: 'Delete',
91: 'Meta',
93: 'ContextMenu',
96: "Num 0",
97: "Num 1",
98: "Num 2",
99: "Num 3",
100: "Num 4",
101: "Num 5",
102: "Num 6",
103: "Num 7",
104: "Num 8",
105: "Num 9",
106: "Num *",
107: "Num +",
108: "Num Enter",
109: "Num -",
110: "Num .",
111: "Num /",
112: 'F1',
113: 'F2',
114: 'F3',
115: 'F4',
116: 'F5',
117: 'F6',
118: 'F7',
119: 'F8',
120: 'F9',
121: 'F10',
122: 'F11',
123: 'F12',
144: 'NumLock',
145: 'ScrollLock',
173: 'ff-',
61: 'ff=',
186: ';',
187: '=',
188: ',',
189: '-',
190: '.',
191: '/',
192: '`',
219: '[',
220: '\\',
221: ']',
222: '\'',
};
if (specialKeys[code]) {
return specialKeys[code];
}
return String.fromCharCode(code);
};
var _getDefaultShortcutActions = function() {
if(window.DE || window.PDFE) {
return Asc.c_oAscDocumentShortcutType;
} else if(window.PE) {
return Asc.c_oAscPresentationShortcutType;
} else if(window.SSE) {
return Asc.c_oAscSpreadsheetShortcutType;
} else if(window.VE) {
return Asc.c_oAscDiagramShortcutType;
}
return {};
};
var _fillActionsMap = function() {
actionsMap = {};
const shortcutActions = _getDefaultShortcutActions();
const unlockedTypes = Asc.c_oAscUnlockedShortcutActionTypes || {};
for (let actionName in shortcutActions) {
const type = shortcutActions[actionName];
actionsMap[type] = {
action: {
name: actionName,
type: type,
isLocked: !unlockedTypes[type]
},
shortcuts: []
}
}
pairs(Asc.c_oAscDefaultShortcuts).forEach(function(item) {
const actionType = item[0];
const shortcuts = item[1];
const actionItem = actionsMap[actionType];
if(actionItem) {
actionItem.shortcuts = shortcuts.map(function(ascShortcut) {
return {
keys: _getAscShortcutKeys(ascShortcut),
isCustom: false,
ascShortcut: ascShortcut,
}
});
}
});
let removableIndexes = {};
pairs(_getModifiedShortcuts()).forEach(function(item) {
const actionType = item[0];
const shortcuts = item[1];
const actionItem = actionsMap[actionType];
if(actionItem) {
shortcuts.forEach(function(ascShortcut) {
const ascShortcutIndex = ascShortcut.asc_GetShortcutIndex();
const defaultShortcutIndex = findIndex(actionItem.shortcuts, function(shortcut) {
return shortcut.ascShortcut.asc_GetShortcutIndex() == ascShortcutIndex;
});
if(defaultShortcutIndex != -1) {
actionItem.shortcuts[defaultShortcutIndex].ascShortcut = ascShortcut;
} else {
removableIndexes[ascShortcutIndex] = actionType;
actionItem.shortcuts.push({
keys: _getAscShortcutKeys(ascShortcut),
isCustom: true,
ascShortcut: ascShortcut,
});
}
});
}
})
for (const actionType in actionsMap) {
const item = actionsMap[actionType];
const shortcuts = actionsMap[actionType].shortcuts;
if(shortcuts.length == 0 && item.action.isLocked) {
// Delete actions if it has no shortcuts and the action is locked
delete actionsMap[actionType];
} else if(Object.keys(removableIndexes).length > 0) {
// Remove shortcuts from other actions if they conflict with updated shortcuts
const foundIndex = findIndex(shortcuts, function(shortcut) {
const ascShortcutIndex = shortcut.ascShortcut.asc_GetShortcutIndex();
if(removableIndexes[ascShortcutIndex] && removableIndexes[ascShortcutIndex] != actionType) {
delete removableIndexes[ascShortcutIndex];
return true;
}
return false;
});
if(foundIndex != -1) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(shortcuts[foundIndex].ascShortcut.asc_ToJson());
copyAscShortcut.asc_SetIsHidden(true);
shortcuts[foundIndex].ascShortcut = copyAscShortcut;
}
}
}
};
var _applyShortcutsInSDK = function() {
const applyMethod = function(storage) {
storage = JSON.parse(storage || common.localStorage.getItem(localStorageKey) || "{}");
for (const actionType in storage) {
storage[actionType] = storage[actionType].map(function(ascShortcutJson) {
const ascShortcut = new Asc.CAscShortcut();
ascShortcut.asc_FromJson(ascShortcutJson);
return ascShortcut;
});
}
api.asc_resetAllShortcutTypes();
const modifiedShortcuts = flatten(values(storage));
if(modifiedShortcuts.length) {
api.asc_applyAscShortcuts(modifiedShortcuts);
}
};
$(window).on('storage', function (e) {
if(e.key == localStorageKey) {
applyMethod(e.originalEvent.newValue);
_fillActionsMap();
}
});
applyMethod();
};
/**
* Retrieves user-modified shortcuts from localStorage.
* @returns {Object<number, CAscShortcut[]>}
* An object where keys are action types and values are arrays of ascShortcut instances.
*/
var _getModifiedShortcuts = function() {
const storage = JSON.parse(common.localStorage.getItem(localStorageKey) || "{}");
for (const actionType in storage) {
storage[actionType] = storage[actionType].map(function(ascShortcutJson) {
const ascShortcut = new Asc.CAscShortcut();
ascShortcut.asc_FromJson(ascShortcutJson);
return ascShortcut;
});
}
return storage;
};
var _getAscShortcutKeys = function(ascShortcut) {
const keys = [];
ascShortcut.asc_IsCommand() && keys.push('⌘');
ascShortcut.asc_IsCtrl() && keys.push('Ctrl');
ascShortcut.asc_IsAlt() && keys.push('Alt');
ascShortcut.asc_IsShift() && keys.push('Shift');
keys.push(_keyCodeToKeyName(ascShortcut.asc_GetKeyCode()));
return keys;
};
// Utils
var pairs = function(obj) {
var result = [];
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result.push([key, obj[key]]);
}
}
return result;
};
var flatten = function(array) {
var result = [];
function flat(arr) {
for (var i = 0; i < arr.length; i++) {
var value = arr[i];
if (Array.isArray(value)) {
flat(value);
} else {
result.push(value);
}
}
}
flat(array);
return result;
};
var values = function(obj) {
var result = [];
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result.push(obj[key]);
}
}
return result;
};
var findIndex = function(array, predicate) {
for (var i = 0; i < array.length; i++) {
if (predicate(array[i], i, array)) {
return i;
}
}
return -1;
};
return {
setApi: setApi
}
});
}();

View File

@ -152,6 +152,11 @@
config.callback(btn);
}
});
$dlgWarning.on('click', '[data-dismiss="modal"]', function() {
if (config.closecallback) {
config.closecallback();
}
});
$dlgWarning.on('hidden.bs.modal', function() {
$dlgWarning.remove();

View File

@ -1097,6 +1097,14 @@ define([
this.updateIcon();
Common.NotificationCenter.on('uitheme:changed', this.updateIcons.bind(this));
if (this.cmpEl && this.options.customAttributes) {
for (var key in this.options.customAttributes) {
if (Object.prototype.hasOwnProperty.call(this.options.customAttributes, key)) {
this.cmpEl.attr(Common.Utils.String.htmlEncode(key), Common.Utils.String.htmlEncode(this.options.customAttributes[key]));
}
}
}
},
updateIcons: function() {

View File

@ -125,7 +125,10 @@ define([
cls: 'color-menu ' + (options.eyeDropper ? 'shifted-right' : 'shifted-left'),
additionalAlign: options.additionalAlign,
items: (options.additionalItemsBefore ? options.additionalItemsBefore : []).concat(auto).concat([
{ template: _.template('<div id="' + id + '-color-menu" style="width: ' + width + '; height:' + height + '; display: inline-block;"></div>') }
{
template: _.template('<div id="' + id + '-color-menu" style="width: ' + width + '; height:' + height + '; display: inline-block;"></div>'),
stopPropagation: options.hidePaletteOnClick===false
}
]).concat(options.hideColorsSeparator ? [] : {caption: '--'}).concat(eyedropper).concat([
{
id: id + '-color-new',

View File

@ -1404,9 +1404,9 @@ define([
if (data.keyCode==Common.UI.Keys.RETURN) {
if (this.selectedBeforeHideRec) // only for ComboDataView menuPicker
rec = this.selectedBeforeHideRec;
if (this.canAddRecents) // only for DaraViewShape
if (this.canAddRecents) // only for DataViewShape
this.addRecentItem(rec);
this.trigger('item:click', this, this, rec, e);
rec && this.trigger('item:click', this, this, rec, e);
if (this.parentMenu)
this.parentMenu.hide();
} else {
@ -1880,6 +1880,8 @@ define([
this.addRecentItem(record);
},
addRecentItem: function (rec) {
if (!rec) return;
var me = this,
exist = false,
type = rec.get('data').shapeType,

View File

@ -685,7 +685,7 @@ define([
}
})(), Common.UI.InputFieldBtnPassword || {}));
Common.UI.InputFieldBtnCalendar = Common.UI.InputFieldBtn.extend((function (){
Common.UI.InputFieldBtnCalendar = Common.UI.InputFieldBtn.extend(_.extend((function() {
return {
options: {
id: null,
@ -767,7 +767,7 @@ define([
textDate: 'Select date'
}
})());
})(), Common.UI.InputFieldBtnCalendar || {}));
Common.UI.InputFieldFixed = Common.UI.InputField.extend((function() {
return {

View File

@ -189,11 +189,11 @@ define([
labelEl.text(name);
},
setHeaderWidth: function(index, width) {
setHeaderWidth: function(index, width, innerLabel) {
if(index < 0 || index > this.options.headers.length - 1 || !this.headerEl) return;
var labelEl = $(this.headerEl.find('.table-header-item')[index]);
if(labelEl.attr('sort-type')) {
if(labelEl.attr('sort-type') && innerLabel) {
labelEl = labelEl.find('label')[0];
}

View File

@ -631,9 +631,25 @@ define([
if (item.options.stopPropagation) {
e.stopPropagation();
var me = this;
_.delay(function(){
me.$el.parent().parent().find('[data-toggle=dropdown]').focus();
}, 10);
const _callback = function (records, observer) {
if (records[0].oldValue && records[0].oldValue.indexOf('over') && !me.$el.hasClass('over')) {
observer.disconnect();
_.delay(function(){
me.$el.parent().parent().find('[data-toggle=dropdown]').focus();
}, 10);
}
};
if ((this.menuAlignEl || this.menuRoot.parent()).is('li.dropdown-submenu')) { // for bug 24712, click from submenu
(new MutationObserver(_callback)).observe(this.$el[0], {
attributes : true,
attributeFilter : ['class'],
attributeOldValue: true
});
} else { // click from button menu, set focus to button
_.delay(function(){
me.$el.parent().find('[data-toggle=dropdown]').focus();
}, 10);
}
return;
}
this.trigger(item.isCustomItem ? 'item:custom-click' : 'item:click', this, item, e);

View File

@ -205,26 +205,7 @@ define([
}
if (me.options.hint) {
el.attr('data-toggle', 'tooltip');
el.tooltip({
title : me.options.hint,
placement : me.options.hintAnchor||function(tip, element) {
var pos = Common.Utils.getBoundingClientRect(element),
actualWidth = tip.offsetWidth,
actualHeight = tip.offsetHeight,
innerWidth = Common.Utils.innerWidth(),
innerHeight = Common.Utils.innerHeight();
var top = pos.top,
left = pos.left + pos.width + 2;
if (top + actualHeight > innerHeight) {
top = innerHeight - actualHeight - 2;
}
if (left + actualWidth > innerWidth) {
left = pos.left - actualWidth - 2;
}
Common.Utils.setOffset($(tip),{top: top,left: left}).addClass('in');
}
});
this.createHint();
}
if (this.cls)
@ -260,6 +241,39 @@ define([
return this;
},
createHint: function() {
if(!this.cmpEl) return;
this.cmpEl.attr('data-toggle', 'tooltip');
this.cmpEl.tooltip({
title : this.options.hint,
placement : this.options.hintAnchor||function(tip, element) {
var pos = Common.Utils.getBoundingClientRect(element),
actualWidth = tip.offsetWidth,
actualHeight = tip.offsetHeight,
innerWidth = Common.Utils.innerWidth(),
innerHeight = Common.Utils.innerHeight();
var top = pos.top,
left = pos.left + pos.width + 2;
if (top + actualHeight > innerHeight) {
top = innerHeight - actualHeight - 2;
}
if (left + actualWidth > innerWidth) {
left = pos.left - actualWidth - 2;
}
Common.Utils.setOffset($(tip),{top: top,left: left}).addClass('in');
}
});
},
updateHint: function(hint) {
this.options.hint = hint;
if (!this.rendered) return;
this.cmpEl.tooltip('destroy');
this.createHint();
},
setCaption: function(caption) {
this.caption = caption;

View File

@ -379,7 +379,9 @@ define([
if (this.options.hold && ( e.keyCode==Common.UI.Keys.UP || e.keyCode==Common.UI.Keys.DOWN)) {
e.preventDefault();
e.stopPropagation();
if (this.switches.timeout===undefined) {
if (e.metaKey) {
this._step(e.keyCode === Common.UI.Keys.UP);
} else if (this.switches.timeout===undefined) {
this.switches.fromKeyDown = true;
this._startSpin(e.keyCode==Common.UI.Keys.UP, e);
}

View File

@ -160,6 +160,7 @@ define([
Common.NotificationCenter.on('uitheme:changed', _.bind(function() {
this.clearActiveData();
this.processPanelVisible();
this.repaintMoreBtns();
}, this));
},
@ -378,7 +379,28 @@ define([
var _tabTemplate = _.template('<li class="ribtab" style="display: none;" <% if (typeof layoutname == "string") print(" data-layout-name=" + \' \' + layoutname) + \' \' %>><a role="tab" id="<%= action %>" data-tab="<%= action %>" data-title="<%= caption %>" data-hint="0" data-hint-direction="bottom" data-hint-offset="small" <% if (typeof dataHintTitle !== "undefined") { %> data-hint-title="<%= dataHintTitle %>" <% } %> ><%= caption %></a></li>');
config.tabs[after + 1] = tab;
if (after===undefined || tab.aux)
after = config.tabs.length-1;
if (tab.aux) { // alwayw show tab at the end of toolbar
config.tabs.push(tab);
} else if (config.tabs[after + 1]) {
var index = -1;
for (let i=after + 2; i<config.tabs.length; i++) {
if (config.tabs[i]===undefined) {
index = i;
break;
}
}
if (index<0 || index>config.tabs.length-1)
config.tabs.splice(after+1, 0, tab);
else {
config.tabs.splice(index, 1);
config.tabs.splice(after+1, 0, tab);
}
} else {
config.tabs[after + 1] = tab;
}
var _after_action = _get_tab_action(after);
var _elements = this.$tabs || this.$layout.find('.tabs');
@ -424,7 +446,8 @@ define([
},
getLastTabIdx: function() {
return config.tabs.length;
var index = _.findIndex(config.tabs, {aux: true});
return index<0 ? config.tabs.length-1 : index-1;
},
isCompact: function () {
@ -462,9 +485,9 @@ define([
* hide button's caption to decrease panel width
* ##adopt-panel-width
**/
processPanelVisible: function(panel, force) {
processPanelVisible: function(panel, reset, force) {
var me = this;
function _fc() {
function _fc(reset) {
var $active = panel || me.$panels.filter('.active');
if ( $active && $active.length ) {
var _maxright = $active.parents('.box-controls').width(),
@ -524,9 +547,9 @@ define([
}
data.rightedge = _rightedge;
}
me.resizeToolbar(force);
me.resizeToolbar(reset);
} else {
more_section.is(':visible') && me.resizeToolbar(force);
more_section.is(':visible') && me.resizeToolbar(reset);
if (!more_section.is(':visible')) {
for (var i=0; i<_btns.length; i++) {
var btn = _btns[i];
@ -558,12 +581,13 @@ define([
}
};
if (!me._timer_id) {
_fc();
if (!me._timer_id || force) {
me._timer_id && clearInterval(me._timer_id);
_fc(reset);
me._needProcessPanel = false;
me._timer_id = setInterval(function() {
me._timer_id = setInterval(function() {
if (me._needProcessPanel) {
_fc();
_fc(me._needProcessPanel.reset);
me._needProcessPanel = false;
} else {
clearInterval(me._timer_id);
@ -571,7 +595,7 @@ define([
}
}, 100);
} else
me._needProcessPanel = true;
me._needProcessPanel = {reset: me._needProcessPanel ? me._needProcessPanel.reset || reset : reset};
},
/**/
@ -618,6 +642,9 @@ define([
var moreContainer = $('<div class="dropdown-menu more-container" data-tab="' + tab + '"><div style="display: inline;"></div></div>');
optsFold.$bar.append(moreContainer);
btnsMore[tab].panel = moreContainer.find('div');
} else if (btnsMore[tab].needRepaint && panel.is(':visible')) {
btnsMore[tab].cmpEl.closest('.more-box').css('top', Common.Utils.getPosition(panel).top);
btnsMore[tab].needRepaint = false;
}
this.$moreBar = btnsMore[tab].panel;
},
@ -625,8 +652,11 @@ define([
repaintMoreBtns: function() {
for (var btn in btnsMore) {
if (btnsMore[btn] && btnsMore[btn].cmpEl) {
var box = btnsMore[btn].cmpEl.closest('.more-box');
box.css('top', Common.Utils.getPosition(box.parent()).top);
var box = btnsMore[btn].cmpEl.closest('.more-box'),
panel = box.parent(),
isVisible = panel.is(':visible');
isVisible && box.css('top', Common.Utils.getPosition(panel).top);
btnsMore[btn].needRepaint = !isVisible;
}
}
},
@ -646,6 +676,22 @@ define([
}
},
moveAllFromMoreButton: function(tab) {
if (btnsMore[tab]) {
var moreBar = btnsMore[tab].panel,
items = moreBar ? moreBar.children() : [];
if (items.length>0) {
items.removeAttr('hidden-on-resize');
items.removeAttr('data-hidden-tb-item');
items.removeAttr('group-state');
var panel = this.$panels.filter('[data-tab=' + tab + ']');
panel.length && panel.find('.more-box').before(items);
this.clearMoreButton(tab);
}
}
this.clearActiveData();
},
clearActiveData: function(tab) {
var panel = tab ? this.$panels.filter('[data-tab=' + tab + ']') : this.$panels.filter('.active');
if ( panel.length ) {
@ -727,7 +773,7 @@ define([
var $panel = this.getTab(tab),
$morepanel = this.getMorePanel(tab),
$moresection = $panel ? $panel.find('.more-box') : null;
($moresection.length<1) && ($moresection = null);
($moresection && $moresection.length<1) && ($moresection = null);
return $panel ? !($panel.find('> .group').length>0 || $morepanel && $morepanel.find('.group').length>0) : false;
},

View File

@ -132,12 +132,15 @@ define([
this.cmpEl = me.$el;
}
this.cmpEl.find('.track-center').width(me.options.width - 14);
this.cmpEl[me.direction === 'vertical' ? 'height' : 'width'](me.options.width);
this.track = this.cmpEl.find('.track');
this.thumb = this.cmpEl.find('.thumb');
const halfThumbSize = this.thumb.outerWidth() / 2;
this.width = this.options.width - halfThumbSize;
this.cmpEl.find('.track-center').width(me.options.width - 14);
this.cmpEl[me.direction === 'vertical' ? 'height' : 'width'](this.width);
var onMouseUp = function (e) {
e.preventDefault();
e.stopPropagation();
@ -179,7 +182,7 @@ define([
var onMouseDown = function (e) {
if ( me.disabled ) return;
me._dragstart = me.direction === 'vertical' ? (e.pageY*Common.Utils.zoom() - Common.Utils.getOffset(me.thumb).top) : (e.pageX*Common.Utils.zoom() - Common.Utils.getOffset(me.thumb).left) - 6;
me._dragstart = me.direction === 'vertical' ? (e.pageY*Common.Utils.zoom() - Common.Utils.getOffset(me.thumb).top) : (e.pageX*Common.Utils.zoom() - Common.Utils.getOffset(me.thumb).left) - halfThumbSize;
me.thumb.addClass('active');
$(document).on('mouseup', onMouseUp);
@ -248,13 +251,6 @@ define([
}
}
const thumbWidth = this.thumb.width() / 2;
const delta = -thumbWidth * 2;
this.thumbRange = new Float32Array(101);
for (let i = 0; i < 101; i++) {
this.thumbRange[i] = thumbWidth + delta * (i / 100);
}
this.setThumbPosition(me.options.value);
me.rendered = true;
@ -267,10 +263,8 @@ define([
pos = 0;
}
const offset = pos / 100 * this.width + this.thumbRange[pos];
this.track.css('--slider-unfill-percent', 100 - pos + '%');
this.thumb.css(this.direction === 'vertical' ? 'top' : 'left', offset + 'px');
this.thumb.css(this.direction === 'vertical' ? 'top' : 'left', pos + '%');
},
setValue: function(value) {

View File

@ -74,7 +74,17 @@ define([
].join('')),
initialize : function(options) {
this.textSynchronize += Common.Utils.String.platformKey('Ctrl+S');
const me = this;
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
app.getController('Common.Controllers.Shortcuts').updateShortcutHints({
Save: {
label: '',
applyCallback: function(item, hintText) {
me.textSynchronize += hintText;
},
ignoreUpdates: true
},
});
Common.UI.BaseView.prototype.initialize.call(this, options);
this.target = this.options.target;
@ -102,7 +112,7 @@ define([
this.cmpEl.find('.btn-div').on('click', _.bind(function() { this.trigger('buttonclick');}, this));
this.closable && this.cmpEl.addClass('closable');
this.binding.windowresize = _.bind(this.applyPlacement, this);
this.binding.windowresize = _.bind(this.onWindowResize, this);
}
this.applyPlacement();
@ -131,8 +141,18 @@ define([
this.automove && $(window).off('resize', this.binding.windowresize);
},
applyPlacement: function () {
onWindowResize: function() {
this.applyPlacement();
},
applyPlacement: function (repeatOnce) {
var target = this.target && this.target.length>0 ? this.target : $(document.body);
if (!target.is(':visible') && !repeatOnce) {
var me = this;
setTimeout(function(){ me.applyPlacement(true); }, 100);
return;
}
var showxy = Common.Utils.getOffset(target),
offset = this.offset || {x: 0, y: 0};
if (this.placement=='target' && !this.position) {
@ -237,6 +257,7 @@ define([
// maxwidth: 250 // number or string '123px/none/...', 250 by default,
// extCls: '' //
// noHighlight: false // false by default,
// noArrow: false // false by default,
// multiple: false // false by default, show tip multiple times,
// isNewFeature: false // false by default, show "New" tip in the header
// }
@ -264,14 +285,22 @@ define([
return _helpTips[step] && !(_helpTips[step].name && Common.localStorage.getItem(_helpTips[step].name));
};
var _applyPlacement = function(step) {
if (_helpTips[step] && _helpTips[step].tip && _helpTips[step].tip.isVisible())
_helpTips[step].tip.applyPlacement();
};
var _closeTip = function(step, force, preventNext) {
var props = _helpTips[step];
if (props) {
preventNext && (props.next = undefined);
props.tip && props.tip.close();
props.tip = undefined;
force && props.name && Common.localStorage.setItem(props.name, 1);
}
var steps = typeof step === 'string' ? [step] : step;
steps && steps.forEach(function(step) {
var props = _helpTips[step];
if (props) {
preventNext && (props.next = undefined);
props.tip && props.tip.close();
props.tip = undefined;
force && props.name && Common.localStorage.setItem(props.name, 1);
}
});
};
var _findTarget = function(target) {
@ -323,7 +352,7 @@ define([
}
props.tip = new Common.UI.SynchronizeTip({
extCls: 'colored' + (props.extCls ? ' ' + props.extCls : '') + (props.noHighlight ? ' no-arrow' : ''),
extCls: 'colored' + (props.extCls ? ' ' + props.extCls : '') + (props.noArrow ? ' no-arrow' : ''),
style: 'min-width:200px;max-width:' + (props.maxwidth ? props.maxwidth + (typeof props.maxwidth === 'number' ? 'px;' : ';') : '250px;'),
placement: placement,
position: props.position,
@ -335,6 +364,7 @@ define([
textLink: props.link ? props.link.text : '',
closable: props.closable !== false, // true by default
showButton: props.showButton !== false, // true by default
textButton: props.textButton, // button text, Got it by default
automove: !!props.automove
});
props.tip.on({
@ -378,7 +408,8 @@ define([
closeTip: _closeTip,
removeTip: _removeTip,
addTips: _addTips,
getNeedShow: _getNeedShow
getNeedShow: _getNeedShow,
applyPlacement: _applyPlacement
}
})();
});

View File

@ -54,7 +54,7 @@ define([
this.iconTitle = '';
this.index = -1;
this.template = _.template(['<li class="list-item <% if(active){ %>active selected<% } %> <% if(cls.length){%><%= cls %><%}%><% if(iconVisible){%> icon-visible <%}%>" data-label="<%- label %>">',
'<span tabtitle="<%- label %>" draggable="true" oo_editor_input="true" tabindex="-1" data-index="<%= index %>">',
'<span tabtitle="<%- label %>" draggable="true" oo_editor_input="true" tabindex="-1" data-index="<%= sheetindex %>">',
'<div class="toolbar__icon <% if(iconCls.length){%><%= iconCls %><%}%>" title="<% if(iconTitle.length){%><%=Common.Utils.String.htmlEncode(iconTitle)%><%}%>"></div>',
'<%- label %>',
'</span>',

View File

@ -64,6 +64,14 @@ define([
StateManager.prototype.initialize = function (options) {
this.bar = options.bar;
if (!Common.Utils.isIE && !Common.Utils.isSafari) {
if (Common.Utils.isMac) {
this.ghostImage = new Image();
this.ghostImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
} else {
this.ghostImage = document.createElement('div');
}
}
};
StateManager.prototype.attach = function (tab) {
@ -204,8 +212,7 @@ define([
{dragstart: $.proxy(function (e) {
var event = e.originalEvent;
if (!Common.Utils.isIE && !Common.Utils.isSafari) {
var img = document.createElement('div');
event.dataTransfer.setDragImage(img, 0, 0);
event.dataTransfer.setDragImage(this.ghostImage, 0, 0);
} else if (Common.Utils.isIE) {
this.bar.selectTabs.forEach(function (tab) {
tab.$el.find('span').prop('tabtitle', '');
@ -326,6 +333,7 @@ define([
this.isDragDrop = true;
}
this.trigger('tab:drop', event.dataTransfer, 'last', (event.ctrlKey || Common.Utils.isMac && event.altKey));
this.preventCutTab = true;
} else {
this.isDrop = undefined;
}

View File

@ -103,7 +103,9 @@
cls : opts.cls,
html : opts.html,
hideonclick : opts.hideonclick,
keepvisible: opts.keepvisible
keepvisible: opts.keepvisible,
dir : opts.dir,
animation : opts.animation
});
if (opts.hideonclick) {

View File

@ -158,6 +158,7 @@ define([
minheight: 0,
enableKeyEvents: true,
automove: true,
transparentMask: false,
role: 'dialog'
};
@ -536,7 +537,11 @@ define([
(Math.max(text.width(), check.length>0 ? $(check).find('.checkbox-indeterminate').outerWidth(true) : 0)));
window.setSize(width, parseInt(body.css('height')) + parseInt(header.css('height')));
} else {
text.css('white-space', 'normal');
text.css({
'white-space': 'normal',
'overflow-wrap': 'break-word',
'word-wrap': 'break-word'
});
window.setWidth(options.width);
text_cnt.height(Math.max(text.height(), icon_height) + ((check.length>0) ? (check.height() + parseInt(check.css('margin-top'))) : 0));
body.height(parseInt(text_cnt.css('height')) + parseInt(footer.css('height')));
@ -767,7 +772,7 @@ define([
mask.attr('counter', parseInt(mask.attr('counter'))+1);
mask.show();
} else {
var maskOpacity = $(':root').css('--modal-window-mask-opacity');
var maskOpacity = this.initConfig.transparentMask ? 0 : $(':root').css('--modal-window-mask-opacity');
mask.css('opacity', 0);
mask.attr('counter', parseInt(mask.attr('counter'))+1);
@ -794,8 +799,9 @@ define([
} else
if (!this.$window.is(':visible')) {
this.$window.css({opacity: 0});
(_.isNumber(x) && _.isNumber(y)) && this.setPosition(x, y);
_setVisible.call(this);
this.$window.show()
this.$window.show();
}
$(document).on('keydown.' + this.cid, this.binding.keydown);
@ -874,7 +880,7 @@ define([
if ( hide_mask ) {
if (this.options.animate !== false) {
var maskOpacity = $(':root').css('--modal-window-mask-opacity');
var maskOpacity = this.initConfig.transparentMask ? 0 : $(':root').css('--modal-window-mask-opacity');
mask.css(_getTransformation(0));
setTimeout(function () {
@ -916,7 +922,7 @@ define([
if ( hide_mask ) {
if (this.options.animate !== false) {
var maskOpacity = $(':root').css('--modal-window-mask-opacity');
var maskOpacity = this.initConfig.transparentMask ? 0 : $(':root').css('--modal-window-mask-opacity');
mask.css(_getTransformation(0));
setTimeout(function () {
@ -951,7 +957,7 @@ define([
},
setWidth: function(width) {
if (width >= 0) {
if (this.$window && width >= 0) {
var min = parseInt(this.$window.css('min-width'));
width < min && (width = min);
width -= (parseInt(this.$window.css('border-left-width')) + parseInt(this.$window.css('border-right-width')));
@ -960,11 +966,11 @@ define([
},
getWidth: function() {
return parseInt(this.$window.css('width'));
return this.$window ? parseInt(this.$window.css('width')) : undefined;
},
setHeight: function(height) {
if (height >= 0) {
if (this.$window && height >= 0) {
var min = parseInt(this.$window.css('min-height'));
height < min && (height = min);
height -= (parseInt(this.$window.css('border-bottom-width')) + parseInt(this.$window.css('border-top-width')));
@ -978,7 +984,7 @@ define([
},
getHeight: function() {
return parseInt(this.$window.css('height'));
return this.$window ? parseInt(this.$window.css('height')) : undefined;
},
setSize: function(w, h) {
@ -1023,14 +1029,14 @@ define([
setResizable: function(resizable, minSize, maxSize) {
if (resizable !== this.resizable) {
if (resizable) {
var bordersTemplate = '<div class="resize-border left" style="top:' + ((this.initConfig.header) ? '33' : '5') + 'px; bottom: 5px; height: auto; border-right-style: solid; cursor: w-resize;"></div>' +
'<div class="resize-border left bottom" style="border-bottom-left-radius: 5px; cursor: sw-resize;"></div>' +
var bordersTemplate = '<div class="resize-border left bottom" style="cursor: sw-resize;"></div>' +
'<div class="resize-border left" style="top:' + ((this.initConfig.header) ? '33' : '5') + 'px; bottom: 5px; height: auto; border-right-style: solid; cursor: w-resize;"></div>' +
'<div class="resize-border bottom" style="left: 4px; right: 4px; width: auto; z-index: 2; border-top-style: solid; cursor: s-resize;"></div>' +
'<div class="resize-border right bottom" style="border-bottom-right-radius: 5px; cursor: se-resize;"></div>' +
'<div class="resize-border right bottom" style="cursor: se-resize;"></div>' +
'<div class="resize-border right" style="top:' + ((this.initConfig.header) ? '33' : '5') + 'px; bottom: 5px; height: auto; border-left-style: solid; cursor: e-resize;"></div>' +
'<div class="resize-border left top" style="border-top-left-radius: 5px; cursor: nw-resize;"></div>' +
'<div class="resize-border left top" style="cursor: nw-resize;"></div>' +
'<div class="resize-border top" style="left: 4px; right: 4px; width: auto; z-index: 2; border-bottom-style:' + ((this.initConfig.header) ? "none" : "solid") + '; cursor: n-resize;"></div>' +
'<div class="resize-border right top" style="border-top-right-radius: 5px; cursor: ne-resize;"></div>';
'<div class="resize-border right top" style="cursor: ne-resize;"></div>';
if (this.initConfig.header)
bordersTemplate += '<div class="resize-border left" style="top: 5px; height: 28px; cursor: w-resize;"></div>' +
'<div class="resize-border right" style="top: 5px; height: 28px; cursor: e-resize;"></div>';

View File

@ -80,6 +80,9 @@ define([
isDummyComment : false,
initialize: function () {
this.currentGroupFilter = null;
this.currentTypeFilter = null;
this.isPDFEditor = !!window.PDFE;
this.addListeners({
'Common.Views.Comments': {
@ -103,7 +106,8 @@ define([
'comment:closeEditing': _.bind(this.closeEditing, this),
'comment:sort': _.bind(this.setComparator, this),
'comment:filtergroups': _.bind(this.setFilterGroups, this)
'comment:filtergroups': _.bind(this.setFilterGroups, this),
'comment:filtercomments': _.bind(this.setFilterComments, this)
},
'Common.Views.ReviewPopover': {
@ -659,6 +663,8 @@ define([
// SDK
onApiAddComment: function (id, data) {
if (this.isPDFEditor && (this.findComment(id) || this.findCommentInGroup(id))) return; // fix for PDF, do not add comment with existing id
var requestObj = {},
comment = this.readSDKComment(id, data, requestObj);
if (comment) {
@ -781,8 +787,9 @@ define([
var usergroups = comment.get('parsedGroups');
t.fillUserGroups(usergroups);
var group = Common.Utils.InternalSettings.get(t.appPrefix + "comments-filtergroups");
var filter = !!group && (group!==-1) && (!usergroups || usergroups.length<1 || usergroups.indexOf(group)<0);
comment.set('filtered', filter);
var groupFilter = !!group && (group !== -1) && (!usergroups || usergroups.length < 1 || usergroups.indexOf(group) < 0);
var typeFilter = (t.currentTypeFilter === 'open' && comment.get('resolved')) || (t.currentTypeFilter === 'resolved' && !comment.get('resolved'));
comment.set('filtered', groupFilter || typeFilter);
}
replies = _.clone(comment.get('replys'));
@ -1033,7 +1040,7 @@ define([
this.getPopover().showComments(false, undefined, undefined, text);
}
this.getPopover().setLeftTop(posX, posY, leftX, undefined, true);
this.getPopover().setLeftTop(posX, posY, leftX, undefined);
// if (this.isSelectedComment && (0 === _.difference(this.uids, uids).length)) {
//NOTE: click to sdk view ?
@ -1335,9 +1342,11 @@ define([
var usergroups = comment.get('parsedGroups');
this.fillUserGroups(usergroups);
var group = Common.Utils.InternalSettings.get(this.appPrefix + "comments-filtergroups");
var filter = !!group && (group!==-1) && (!usergroups || usergroups.length<1 || usergroups.indexOf(group)<0);
comment.set('filtered', filter);
var groupFilter = !!group && (group !== -1) && (!usergroups || usergroups.length < 1 || usergroups.indexOf(group) < 0);
var typeFilter = (this.currentTypeFilter === 'open' && comment.get('resolved')) || (this.currentTypeFilter === 'resolved' && !comment.get('resolved'));
comment.set('filtered', groupFilter || typeFilter);
}
var replies = this.readSDKReplies(data, requestObj);
if (replies.length) {
comment.set('replys', replies);
@ -1755,27 +1764,41 @@ define([
}
},
setFilterGroups: function (group) {
Common.Utils.InternalSettings.set(this.appPrefix + "comments-filtergroups", group);
applyCombinedFilter: function () {
var i, end = true;
for (i = this.collection.length - 1; i >= 0; --i) {
var item = this.collection.at(i);
if (!item.get('hide')) {
var usergroups = item.get('parsedGroups');
item.set('filtered', !!group && (group!==-1) && (!usergroups || usergroups.length<1 || usergroups.indexOf(group)<0), {silent: true});
}
if (end && !item.get('hide') && !item.get('filtered')) {
item.set('last', true, {silent: true});
var usergroups = item.get('parsedGroups');
var groupFiltered = !!this.currentGroupFilter && this.currentGroupFilter !== -1 && (!usergroups || usergroups.length < 1 || usergroups.indexOf(this.currentGroupFilter) < 0);
var typeFiltered = (this.currentTypeFilter === 'open' && item.get('resolved')) || (this.currentTypeFilter === 'resolved' && !item.get('resolved'));
var shouldFilter = groupFiltered || typeFiltered;
item.set('filtered', shouldFilter, { silent: true });
if (end && !shouldFilter && !item.get('hide')) {
item.set('last', true, { silent: true });
end = false;
} else {
if (item.get('last')) {
item.set('last', false, {silent: true});
}
} else if (item.get('last')) {
item.set('last', false, { silent: true });
}
}
this.updateComments(true);
},
setFilterGroups: function (group) {
Common.Utils.InternalSettings.set(this.appPrefix + "comments-filtergroups", group);
this.currentGroupFilter = group;
this.applyCombinedFilter();
},
setFilterComments: function (type) {
this.currentTypeFilter = type;
this.applyCombinedFilter();
},
onAppReady: function (config) {
var me = this;
(new Promise(function (accept, reject) {

View File

@ -214,7 +214,7 @@ define([
}
const ctrl_print = webapp.getController('Print');
if ( ctrl_print )
ctrl_print.setPrinterInfo(currentPrinter, printers);
ctrl_print.setPrintersInfo(currentPrinter, printers);
} else
if (/file:saveas/.test(cmd)) {
webapp.getController('Main').api.asc_DownloadAs();
@ -543,6 +543,7 @@ define([
const _f_ = rawarray[i];
if ( utils.matchFileFormat( _f_.type ) ) {
if (_re_name.test(_f_.path)) {
_f_.path = $('<div>').html(_f_.path).text();
const name = _re_name.exec(_f_.path)[1],
dir = _f_.path.slice(0, _f_.path.length - name.length - 1);

View File

@ -48,8 +48,10 @@ define([
var appLang = '{{DEFAULT_LANG}}',
customization = undefined,
targetApp = '',
canRequestOpen = false,
externalEditor = null,
isAppFirstOpened = true;
isAppFirstOpened = true,
isChartUpdating = false;
var createExternalEditor = function() {
@ -80,6 +82,7 @@ define([
'onAppReady' : function() {},
'onDocumentStateChange' : function() {},
'onError' : function() {},
'onRequestOpen' : canRequestOpen ? this.onRequestOpen : undefined,
'onInternalMessage' : _.bind(this.onInternalMessage, this)
}
});
@ -107,8 +110,8 @@ define([
'show': _.bind(function(cmp){
var h = this.diagramEditorView.getHeight(),
innerHeight = Common.Utils.innerHeight() - Common.Utils.InternalSettings.get('window-inactive-area-top');
if (innerHeight<h) {
this.diagramEditorView.setHeight(innerHeight);
if (innerHeight<h || isAppFirstOpened) {
this.diagramEditorView.setHeight(innerHeight<h ? innerHeight : h);
}
if (externalEditor) {
@ -153,7 +156,7 @@ define([
setApi: function(api) {
this.api = api;
this.api.asc_registerCallback('asc_onCloseChartEditor', _.bind(this.onDiagrammEditingDisabled, this));
this.api.asc_registerCallback('asc_sendFromGeneralToFrameEditor', _.bind(this.onSendFromGeneralToFrameEditor, this));
this.api.asc_registerCallback('asc_sendFromGeneralToChartEditor', _.bind(this.onSendFromGeneralToFrameEditor, this));
return this;
},
@ -180,6 +183,7 @@ define([
if (data.config.lang) appLang = data.config.lang;
if (data.config.customization) customization = data.config.customization;
if (data.config.targetApp) targetApp = data.config.targetApp;
canRequestOpen = !!data.config.canRequestOpen;
}
},
@ -216,20 +220,29 @@ define([
if (this.needDisableEditing) {
this.onDiagrammEditingDisabled();
}
if (isChartUpdating) {
Common.NotificationCenter.trigger('data:updatereferences', [isChartUpdating]);
Common.NotificationCenter.trigger('action:end', Asc.c_oAscAsyncActionType.BlockInteraction, Common.UI.blockOperations.UpdateChart);
isChartUpdating = false;
}
} else
if (eventData.type == 'chartDataReady') {
if (eventData.type == 'frameEditorReady') {
if (this.needDisableEditing===undefined)
this.diagramEditorView.setControlsDisabled(false);
} else
if (eventData.type == "shortcut") {
if (eventData.data.key == 'escape')
if (eventData.data.key == 'escape') {
if (externalEditor) {
externalEditor.serviceCommand('getChartData');
}
this.diagramEditorView.hide();
}
} else
if (eventData.type == "canClose") {
if (eventData.data.answer === true) {
if (externalEditor) {
externalEditor.serviceCommand('setAppDisabled',true);
externalEditor.serviceCommand((eventData.data.mr == 'ok') ? 'getChartData' : 'clearChartData');
externalEditor.serviceCommand('getChartData');
}
this.diagramEditorView.hide();
}
@ -266,10 +279,29 @@ define([
}
},
onRequestOpen: function(event) {
if (event && event.data)
Common.Gateway.requestOpen(event.data);
},
onSendFromGeneralToFrameEditor: function(data) {
externalEditor && externalEditor.serviceCommand('generalToFrameData', data);
},
updateChartSilent: function(externalRef) {
if (!this.api) return;
if (!externalEditor && !isChartUpdating) {
isChartUpdating = externalRef;
Common.NotificationCenter.trigger('action:start', Asc.c_oAscAsyncActionType.BlockInteraction, Common.UI.blockOperations.UpdateChart);
this.diagramEditorView.options.animate = false;
this.diagramEditorView.show(-10000, -10000);
this.diagramEditorView.hide();
this.diagramEditorView.options.animate = true;
} else
Common.NotificationCenter.trigger('data:updatereferences', [externalRef]);
},
warningTitle: 'Warning',
warningText: 'The object is disabled because of editing by another user.',
textClose: 'Close',

View File

@ -0,0 +1,264 @@
/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* ExternalLinks.js
*
* Created on 23.11.23
*
*/
if (Common === undefined)
var Common = {};
Common.Controllers = Common.Controllers || {};
define([
'core',
// 'common/main/lib/view/ExternalLinksDlg'
], function () { 'use strict';
Common.Controllers.ExternalLinks = Backbone.Controller.extend(_.extend({
models: [],
collections: [],
views: [
'Common.Views.ExternalLinksDlg'
],
initialize: function() {
this.externalData = {
stackRequests: [],
stackResponse: [],
callback: undefined,
isUpdating: false,
linkStatus: {}
};
this.externalSource = {
externalRef: undefined
};
this._state = {};
},
onLaunch: function() {
//
},
setConfig: function(config) {
this.toolbar = config.toolbar;
return this;
},
setApi: function(api) {
this.api = api;
if ((this.toolbar.mode.canRequestReferenceData || this.toolbar.mode.isOffline) && this.api) {
!!window.SSE && this.api.asc_registerCallback('asc_onNeedUpdateExternalReference', _.bind(this.onNeedUpdateExternalReference, this));
this.api.asc_registerCallback('asc_onNeedUpdateExternalReferenceOnOpen', _.bind(this.onNeedUpdateExternalReferenceOnOpen, this));
this.api.asc_registerCallback('asc_onStartUpdateExternalReference', _.bind(this.onStartUpdateExternalReference, this));
this.api.asc_registerCallback('asc_onUpdateExternalReference', _.bind(this.onUpdateExternalReference, this));
this.api.asc_registerCallback('asc_onErrorUpdateExternalReference', _.bind(this.onErrorUpdateExternalReference, this));
Common.Gateway.on('setreferencedata', _.bind(this.setReferenceData, this));
}
if (this.toolbar.mode.canRequestReferenceSource) {
Common.Gateway.on('setreferencesource', _.bind(this.setReferenceSource, this));
}
Common.NotificationCenter.on('data:externallinks', _.bind(this.onExternalLinks, this));
Common.NotificationCenter.on('data:updatereferences', _.bind(this.updateReferences, this));
Common.NotificationCenter.on('data:openlink', _.bind(this.openLink, this));
return this;
},
onExternalLinks: function() {
var me = this;
this.externalLinksDlg = (new Common.Views.ExternalLinksDlg({
api: this.api,
isUpdating: this.externalData.isUpdating,
canRequestReferenceData: this.toolbar.mode.canRequestReferenceData || this.toolbar.mode.isOffline,
canRequestOpen: this.toolbar.mode.canRequestOpen || this.toolbar.mode.isOffline,
canRequestReferenceSource: this.toolbar.mode.canRequestReferenceSource || this.toolbar.mode.isOffline,
isOffline: this.toolbar.mode.isOffline,
handler: function(result) {
Common.NotificationCenter.trigger('edit:complete');
}
}));
this.externalLinksDlg.on('close', function(win){
me.externalLinksDlg = null;
});
this.externalLinksDlg.on('change:source', function(win, externalRef){
me.externalSource = {
externalRef: externalRef
};
Common.Gateway.requestReferenceSource();
});
this.externalLinksDlg.show()
},
onUpdateExternalReference: function(arr, callback) {
if (this.toolbar.mode.isEdit && this.toolbar.editMode) {
var me = this;
me.externalData = {
stackRequests: [],
stackResponse: [],
callback: undefined,
isUpdating: false,
linkStatus: {}
};
arr && arr.length>0 && arr.forEach(function(item) {
var data;
switch (item.asc_getType()) {
case Asc.c_oAscExternalReferenceType.link:
data = {link: item.asc_getData()};
break;
case Asc.c_oAscExternalReferenceType.path:
data = {path: item.asc_getData()};
break;
case Asc.c_oAscExternalReferenceType.referenceData:
data = {
referenceData: item.asc_getData(),
path: item.asc_getPath(),
link: item.asc_getLink()
};
break;
}
data && me.externalData.stackRequests.push({data: data, id: item.asc_getId(), isExternal: item.asc_isExternalLink(), source: item.asc_getSource() || ''});
});
me.externalData.callback = callback;
me.requestReferenceData();
}
},
requestReferenceData: function() {
if (this.externalData.stackRequests.length>0) {
var item = this.externalData.stackRequests.shift();
this.externalData.linkStatus.id = item.id;
this.externalData.linkStatus.source = item.source;
this.externalData.linkStatus.isExternal = item.isExternal;
Common.Gateway.requestReferenceData(item.data);
}
},
setReferenceData: function(data) {
if (this.toolbar.mode.isEdit && this.toolbar.editMode) {
if (data) {
this.externalData.stackResponse.push(data);
this.externalData.linkStatus.result = this.externalData.linkStatus.isExternal ? '' : data.error || '';
if (this.externalLinksDlg) {
this.externalLinksDlg.setLinkStatus(this.externalData.linkStatus.id, this.externalData.linkStatus.result);
} else if (this.externalData.linkStatus.result && !this._state.isFromDlg)
Common.NotificationCenter.trigger('showmessage', {msg: this.externalData.linkStatus.result + (this.externalData.linkStatus.source ? ' (' + this.externalData.linkStatus.source + ')' : '') });
}
if (this.externalData.stackRequests.length>0)
this.requestReferenceData();
else if (this.externalData.callback)
this.externalData.callback(this.externalData.stackResponse);
}
},
onStartUpdateExternalReference: function(status) {
this.externalData.isUpdating = status;
if (this.externalLinksDlg) {
this.externalLinksDlg.setIsUpdating(status);
}
!status && (this._state.isFromDlg = status);
},
onNeedUpdateExternalReferenceOnOpen: function() {
var value = this.api.asc_getUpdateLinks();
Common.UI.warning({
msg: value ? (!!window.SSE ? this.warnUpdateExternalAutoupdate : !!window.PE ? this.warnUpdateExternalAutoupdatePE : this.warnUpdateExternalAutoupdateDE) :
(!!window.SSE ? this.warnUpdateExternalData : !!window.PE ? this.warnUpdateExternalDataPE : this.warnUpdateExternalDataDE),
buttons: [{value: 'ok', caption: value ? this.textContinue : this.textUpdate, primary: true}, {value: 'cancel', caption: value ? this.textTurnOff : this.textDontUpdate}],
maxwidth: 500,
callback: _.bind(function(btn) {
if (btn==='ok') {
var links = this.api.asc_getExternalReferences();
links && (links.length>0) && this.updateReferences(links);
}
value && this.api.asc_setUpdateLinks(btn==='ok', true);
}, this)
});
},
onErrorUpdateExternalReference: function(id) {
if (this.externalLinksDlg) {
this.externalLinksDlg.setLinkStatus(id, this.txtErrorExternalLink);
}
},
onNeedUpdateExternalReference: function() {
Common.NotificationCenter.trigger('showmessage', {msg: this.textAddExternalData});
},
setReferenceSource: function(data) { // gateway
if (this.toolbar.mode.isEdit && this.toolbar.editMode && this.api) {
this.api.asc_changeExternalReference(this.externalSource.externalRef, data);
}
},
openLink: function(externalRef) {
if (!externalRef) return;
var data = this.api.asc_openExternalReference(externalRef);
if (data) {
switch (data.asc_getType()) {
case Asc.c_oAscExternalReferenceType.link:
data = {link: data.asc_getData()};
break;
case Asc.c_oAscExternalReferenceType.path:
data = {path: data.asc_getData()};
break;
case Asc.c_oAscExternalReferenceType.referenceData:
data = {
referenceData: data.asc_getData(),
path: data.asc_getPath()
};
break;
}
data.windowName = 'wname-' + Date.now();
window.open("", data.windowName);
Common.Gateway.requestOpen(data);
}
},
updateReferences: function(data, fromDlg) {
this._state.isFromDlg = !!fromDlg;
this.api && this.api.asc_updateExternalReferences(data);
},
txtErrorExternalLink: 'Error: updating is failed',
warnUpdateExternalData: 'This workbook contains links to one or more external sources that could be unsafe.<br>If you trust the links, update them to get the latest data.',
warnUpdateExternalDataDE: 'This document contains links to one or more external sources that could be unsafe.<br>If you trust the links, update them to get the latest data.',
warnUpdateExternalDataPE: 'This presentation contains links to one or more external sources that could be unsafe.<br>If you trust the links, update them to get the latest data.',
textUpdate: 'Update',
textDontUpdate: 'Don\'t Update',
textAddExternalData: 'The link to an external source has been added. You can update such links in the Data tab.',
textTurnOff: 'Turn off auto update',
textContinue: 'Continue'
}, Common.Controllers.ExternalLinks || {}));
});

View File

@ -151,7 +151,6 @@ define([
setApi: function(api) {
this.api = api;
this.api.asc_registerCallback('asc_onCloseMergeEditor', _.bind(this.onMergeEditingDisabled, this));
this.api.asc_registerCallback('asc_sendFromGeneralToFrameEditor', _.bind(this.onSendFromGeneralToFrameEditor, this));
return this;
},
@ -266,10 +265,6 @@ define([
}
},
onSendFromGeneralToFrameEditor: function(data) {
externalEditor && externalEditor.serviceCommand('generalToFrameData', data);
},
warningTitle: 'Warning',
warningText: 'The object is disabled because of editing by another user.',
textClose: 'Close',

View File

@ -60,7 +60,7 @@ define([
height : '100%',
documentType: 'cell',
document : {
url : '_chart_',
url : '_ole_',
permissions : {
edit : true,
download: false
@ -153,7 +153,7 @@ define([
setApi: function(api) {
this.api = api;
this.api.asc_registerCallback('asc_onCloseOleEditor', _.bind(this.onOleEditingDisabled, this));
this.api.asc_registerCallback('asc_sendFromGeneralToFrameEditor', _.bind(this.onSendFromGeneralToFrameEditor, this));
this.api.asc_registerCallback('asc_sendFromGeneralToOleEditor', _.bind(this.onSendFromGeneralToFrameEditor, this));
return this;
},
@ -217,7 +217,7 @@ define([
this.onOleEditingDisabled();
}
} else
if (eventData.type == 'oleEditorReady') {
if (eventData.type == 'frameEditorReady') {
if (this.needDisableEditing===undefined)
this.oleEditorView.setControlsDisabled(false);
} else

View File

@ -48,6 +48,7 @@ Common.UI.ExternalUsers = new( function() {
externalUsersInfo = [],
isUsersInfoLoading = false,
stackUsersInfoResponse = [],
requestedUsersInfo = [],
api,
userColors = [];
@ -55,11 +56,13 @@ Common.UI.ExternalUsers = new( function() {
if (type==='info') {
(typeof ids !== 'object') && (ids = [ids]);
ids && (ids = _.uniq(ids));
ids = _.difference(ids, requestedUsersInfo);
requestedUsersInfo = requestedUsersInfo.concat(ids);
if (ids.length>100) {
while (ids.length>0) {
Common.Gateway.requestUsers('info', ids.splice(0, 100));
}
} else
} else if (ids.length>0)
Common.Gateway.requestUsers('info', ids);
} else {
if (isUsersLoading) return;

View File

@ -274,7 +274,7 @@ define([
//$('<div class="separator long"></div>').appendTo(me.$toolbarPanelPlugins);
group = $('<div class="group" style="' + (Common.UI.isRTL() ? 'padding-right: 0;' : 'padding-left: 0;') + '"></div>');
this.viewPlugins.backgroundBtn = this.viewPlugins.createBackgroundPluginsButton();
var $backgroundSlot = $('<span class="btn-slot text x-huge"></span>').appendTo(group);
var $backgroundSlot = $('<span class="btn-slot text x-huge" id="slot-background-plugin"></span>').appendTo(group);
this.viewPlugins.backgroundBtn.render($backgroundSlot);
this.viewPlugins.backgroundBtn.hide();

View File

@ -0,0 +1,605 @@
/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* Created on 1/9/2025.
*/
define([
'core'
], function () {
'use strict';
Common.Controllers.Shortcuts = Backbone.Controller.extend(_.extend({
initialize: function() {
this.localStorageKey = '';
if(window.DE) {
this.localStorageKey = 'de-shortcuts';
} else if(window.PDFE) {
this.localStorageKey = 'pdfe-shortcuts';
} else if(window.PE) {
this.localStorageKey = 'pe-shortcuts';
} else if(window.SSE) {
this.localStorageKey = 'sse-shortcuts';
} else if(window.VE) {
this.localStorageKey = 've-shortcuts';
}
this.actionsMap = {};
this.eventsMap = {};
},
setApi: function(api) {
this.api = api;
this._fillActionsMap();
api && this._applyShortcutsInSDK();
this._eventsTrigger();
return this;
},
keyCodeToKeyName: function(code) {
const specialKeys = {
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Ctrl',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
32: 'Space',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
44: 'PrintScreen',
45: 'Insert',
46: 'Delete',
91: 'Meta',
93: 'ContextMenu',
96: "Num 0",
97: "Num 1",
98: "Num 2",
99: "Num 3",
100: "Num 4",
101: "Num 5",
102: "Num 6",
103: "Num 7",
104: "Num 8",
105: "Num 9",
106: "Num *",
107: "Num +",
108: "Num Enter",
109: "Num -",
110: "Num .",
111: "Num /",
112: 'F1',
113: 'F2',
114: 'F3',
115: 'F4',
116: 'F5',
117: 'F6',
118: 'F7',
119: 'F8',
120: 'F9',
121: 'F10',
122: 'F11',
123: 'F12',
144: 'NumLock',
145: 'ScrollLock',
173: 'ff-',
61: 'ff=',
186: ';',
187: '=',
188: ',',
189: '-',
190: '.',
191: '/',
192: '`',
219: '[',
220: '\\',
221: ']',
222: '\'',
};
if (specialKeys[code]) {
return specialKeys[code];
}
return String.fromCharCode(code);
},
resetAllShortcuts: function() {
const me = this;
this.api.asc_resetAllShortcutTypes();
for (const actionType in Asc.c_oAscDefaultShortcuts) {
const actionItem = this.getActionsMap()[actionType];
actionItem.shortcuts = Asc.c_oAscDefaultShortcuts[actionType].map(function(ascShortcut) {
return {
keys: me._getAscShortcutKeys(ascShortcut),
isCustom: false,
ascShortcut: ascShortcut,
}
});
}
this._eventsTrigger();
Common.localStorage.setItem(this.localStorageKey, '');
Common.NotificationCenter.trigger('shortcuts:update');
},
updateShortcutsForAction: function(actionType, updatedShortcuts) {
let resultShortcuts = [];
const originalShortcuts = this.getActionsMap()[actionType].shortcuts;
// Update hidden status and create copies for those not in updatedShortcuts
originalShortcuts.forEach(function(item) {
const existsInUpdated = _.some(updatedShortcuts, function(el) {
return el.ascShortcut.asc_GetShortcutIndex() === item.ascShortcut.asc_GetShortcutIndex();
});
if(!existsInUpdated && !item.ascShortcut.asc_IsHidden()) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(item.ascShortcut.asc_ToJson());
item.ascShortcut = copyAscShortcut;
}
item.ascShortcut.asc_SetIsHidden(!existsInUpdated);
resultShortcuts.push(item);
});
// Add new custom shortcuts that are not in originalShortcuts
updatedShortcuts.forEach(function(item) {
const existsInOriginal = _.some(originalShortcuts, function(el) {
return el.ascShortcut.asc_GetShortcutIndex() === item.ascShortcut.asc_GetShortcutIndex();
});
if(!existsInOriginal) {
item.isCustom = true;
resultShortcuts.push(item);
}
});
const action = this.getActionsMap()[actionType];
resultShortcuts = resultShortcuts.sort(this._sortComparator);
action && (action.shortcuts = resultShortcuts);
// Remove shortcuts from other actions if they conflict with updated shortcuts
const removableIndexes = updatedShortcuts.map(function(item) {
return item.ascShortcut.asc_GetShortcutIndex()
});
const removableFromStorage = {};
for (const type in this.getActionsMap()) {
if(removableIndexes.length == 0) break;
if(type == actionType) continue;
const shortcuts = this.getActionsMap()[type].shortcuts;
const foundIndex = _.findIndex(shortcuts, function(shortcut) {
const foundIndex = _.indexOf(removableIndexes, shortcut.ascShortcut.asc_GetShortcutIndex());
(foundIndex != -1) && removableIndexes.splice(foundIndex, 1);
return foundIndex != -1;
});
if(foundIndex != -1) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(shortcuts[foundIndex].ascShortcut.asc_ToJson());
copyAscShortcut.asc_SetIsHidden(true);
shortcuts[foundIndex].ascShortcut = copyAscShortcut;
!removableFromStorage[type] && (removableFromStorage[type] = []);
removableFromStorage[type].push(shortcuts[foundIndex].ascShortcut);
}
}
this.api.asc_applyAscShortcuts(resultShortcuts.map(function(shortcut) {
return shortcut.ascShortcut;
}));
//Filter for save in local storage
const savedInStorage = {
[actionType] : _.filter(resultShortcuts, function(item) {
return item.isCustom !== item.ascShortcut.asc_IsHidden();
}).map(function(shortcut) {
return shortcut.ascShortcut;
})
};
this._saveModifiedShortcuts(savedInStorage, removableFromStorage);
Common.NotificationCenter.trigger('shortcuts:update');
this._eventsTrigger([actionType].concat(_.keys(removableFromStorage)));
},
getActionsMap: function() {
return this.actionsMap;
},
getDefaultShortcutActions: function() {
if(window.DE || window.PDFE) {
return Asc.c_oAscDocumentShortcutType;
} else if(window.PE) {
return Asc.c_oAscPresentationShortcutType;
} else if(window.SSE) {
return Asc.c_oAscSpreadsheetShortcutType;
} else if(window.VE) {
return Asc.c_oAscDiagramShortcutType;
}
return {};
},
/**
* Returns a list of shortcuts for the given action type.
*
* @param {string|number} actionType
* The action type identifier. Can be:
* - `string` — action type name ('Save', 'Undo', 'Copy' and so on)
* - `number` — numeric action type id
*
* @returns {Array<{keys: string[], isCustom: boolean, ascShortcut: CAscShortcut}>|null}
*
* @example
* getShortcutsByActionType('Save');
* getShortcutsByActionType(7);
*/
getShortcutsByActionType: function(actionType, withHidden) {
const actionTypeNumber = (typeof actionType === 'number')
? actionType
: this.getDefaultShortcutActions()[actionType];
const actionItem = this.actionsMap[actionTypeNumber];
let shortcuts = actionItem ? actionItem.shortcuts : null;
if(!withHidden && shortcuts) {
shortcuts = shortcuts.filter(function(shortcut) {
return !shortcut.ascShortcut.asc_IsHidden();
});
}
return shortcuts;
},
/**
* Updates button hints for shortcuts.
*
* For each action type, finds the first visible shortcut (non-hidden)
* and appends its key combination to the base label. Then applies the
* updated hint to the button or via a custom callback.
*
* @param {Object<string, {
* btn: Object,
* label: string,
* applyCallback?: function(Object, string):void,
* ignoreUpdates?: boolean
* }>} shortcutHints
*
* An object where:
* - key is the action type (actionType),
* - value is a config object:
*
* - `btn` {Object} — button object that provides `updateHint(string)` method.
* - `label` {string} — the base label text for the hint.
* - `applyCallback` [optional] — custom function to apply the generated hint text.
* Receives `(item, hintText)` as arguments.
* - `ignoreUpdates` [optional] — if `true`, will not be updated when shortcuts are updated
*
* @example
* updateShortcutHints({
* EditUndo: {
* btn: btnUndo,
* label: 'Undo'
* },
* EditRedo: {
* label: 'Redo',
* applyCallback: function(item, hintText) {
* console.log('Custom hint:', text);
* },
* ignoreUpdates: true
* }
* });
*/
updateShortcutHints: function(shortcutHints) {
for (const actionType in shortcutHints) {
const item = shortcutHints[actionType];
if(item) {
const callback = function() {
const defaultShortcutsActions = this.getDefaultShortcutActions();
const type = defaultShortcutsActions[actionType];
const action = type ? this.actionsMap[type] : null;
const firstShortcut = action
? _.find(action.shortcuts, (shortcut) => {
return !shortcut.ascShortcut.asc_IsHidden();
})
: null;
const hintText = (item.label || '') + (firstShortcut ? ' (' + firstShortcut.keys.join('+') + ')' : '');
if(item.applyCallback) {
item.applyCallback(item, hintText);
} else {
item.btn.updateHint(hintText);
}
}.bind(this);
callback();
if(!item.ignoreUpdates) {
!this.eventsMap[actionType] && (this.eventsMap[actionType] = []);
this.eventsMap[actionType].push(callback);
}
}
}
},
_getDefaultShortcutActionsInvert: function() {
if(!this._defaultShortcutsActionsInvert) {
this._defaultShortcutsActionsInvert = _.invert(this.getDefaultShortcutActions());
}
return this._defaultShortcutsActionsInvert;
},
_eventsTrigger: function(actionTypes) {
const me = this;
let lists = [];
if(actionTypes) {
lists = actionTypes.map(function(type) {
type = (typeof +type === 'number')
? me._getDefaultShortcutActionsInvert()[type]
: type;
return me.eventsMap[type];
});
} else {
lists = _.values(this.eventsMap);
}
_.each(lists, function(callbacks) {
_.each(callbacks, function(cb) {
cb && cb();
});
});
},
_fillActionsMap: function() {
this.actionsMap = {};
const me = this;
const shortcutActions = this.getDefaultShortcutActions();
const unlockedTypes = Asc.c_oAscUnlockedShortcutActionTypes || {};
for (let actionName in shortcutActions) {
const type = shortcutActions[actionName];
this.actionsMap[type] = {
action: {
name: this['txtLabel' + actionName],
description: this['txtDescription' + actionName],
type: type,
isLocked: !unlockedTypes[type]
},
shortcuts: []
}
}
_.pairs(Asc.c_oAscDefaultShortcuts).forEach(function(item) {
const actionType = item[0];
const shortcuts = item[1];
const actionItem = me.actionsMap[actionType];
if(actionItem) {
actionItem.shortcuts = shortcuts.map(function(ascShortcut) {
return {
keys: me._getAscShortcutKeys(ascShortcut),
isCustom: false,
ascShortcut: ascShortcut,
}
});
}
});
let removableIndexes = {};
_.pairs(me._getModifiedShortcuts()).forEach(function(item) {
const actionType = item[0];
const shortcuts = item[1];
const actionItem = me.actionsMap[actionType];
if(actionItem) {
shortcuts.forEach(function(ascShortcut) {
const ascShortcutIndex = ascShortcut.asc_GetShortcutIndex();
const defaultShortcutIndex = _.findIndex(actionItem.shortcuts, function(shortcut) {
return shortcut.ascShortcut.asc_GetShortcutIndex() == ascShortcutIndex;
});
if(defaultShortcutIndex != -1) {
actionItem.shortcuts[defaultShortcutIndex].ascShortcut = ascShortcut;
} else {
removableIndexes[ascShortcutIndex] = actionType;
actionItem.shortcuts.push({
keys: me._getAscShortcutKeys(ascShortcut),
isCustom: true,
ascShortcut: ascShortcut,
});
}
});
}
})
for (const actionType in this.actionsMap) {
const item = this.actionsMap[actionType];
const shortcuts = this.actionsMap[actionType].shortcuts;
if(shortcuts.length == 0 && item.action.isLocked) {
// Delete actions if it has no shortcuts and the action is locked
delete this.actionsMap[actionType];
} else if(Object.keys(removableIndexes).length > 0) {
// Remove shortcuts from other actions if they conflict with updated shortcuts
const foundIndex = _.findIndex(shortcuts, function(shortcut) {
const ascShortcutIndex = shortcut.ascShortcut.asc_GetShortcutIndex();
if(removableIndexes[ascShortcutIndex] && removableIndexes[ascShortcutIndex] != actionType) {
delete removableIndexes[ascShortcutIndex];
return true;
}
return false;
});
if(foundIndex != -1) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(shortcuts[foundIndex].ascShortcut.asc_ToJson());
copyAscShortcut.asc_SetIsHidden(true);
shortcuts[foundIndex].ascShortcut = copyAscShortcut;
}
}
}
},
_applyShortcutsInSDK: function() {
const applyMethod = function(storage) {
storage = JSON.parse(storage || Common.localStorage.getItem(this.localStorageKey) || "{}");
for (const actionType in storage) {
storage[actionType] = storage[actionType].map(function(ascShortcutJson) {
const ascShortcut = new Asc.CAscShortcut();
ascShortcut.asc_FromJson(ascShortcutJson);
return ascShortcut;
});
}
this.api.asc_resetAllShortcutTypes();
const modifiedShortcuts = _.flatten(_.values(storage));
if(modifiedShortcuts.length) {
this.api.asc_applyAscShortcuts(modifiedShortcuts);
}
}.bind(this);
$(window).on('storage', function (e) {
if(e.key == this.localStorageKey) {
applyMethod(e.originalEvent.newValue);
this._fillActionsMap();
this._eventsTrigger();
Common.NotificationCenter.trigger('shortcuts:update');
}
}.bind(this))
applyMethod();
},
/**
* Retrieves user-modified shortcuts from localStorage.
* @returns {Object<number, CAscShortcut[]>}
* An object where keys are action types and values are arrays of ascShortcut instances.
*/
_getModifiedShortcuts: function() {
const storage = JSON.parse(Common.localStorage.getItem(this.localStorageKey) || "{}");
for (const actionType in storage) {
storage[actionType] = storage[actionType].map(function(ascShortcutJson) {
const ascShortcut = new Asc.CAscShortcut();
ascShortcut.asc_FromJson(ascShortcutJson);
return ascShortcut;
});
}
return storage;
},
/**
* Saves modified shortcuts to localStorage by applying added and removed changes.
* @param {Object<number, CAscShortcut[]>} savedActionsMap
* An object containing new or updated shortcuts, grouped by action type.
* @param {Object<number, CAscShortcut[]>} removedActionsMap
* An object containing shortcuts to be removed, grouped by action type.
* @example
* this._saveModifiedShortcuts(
* { "7": [ascShortcut1, ascShortcut2] },
* { "52": [ascShortcut3] }
* );
* // Result:
* // - For action type "7", shortcuts are replaced with [ascShortcut1, ascShortcut2]
* // - For action type "52", ascShortcut3 is removed
* // - The final shortcuts are saved to localStorage
*/
_saveModifiedShortcuts: function(savedActionsMap, removedActionsMap) {
const customShortcuts = _.extend({}, this._getModifiedShortcuts(), savedActionsMap || {});
for (const actionType in removedActionsMap || {}) {
if (!customShortcuts[actionType]) continue;
const removed = removedActionsMap[actionType];
customShortcuts[actionType] = _.filter(customShortcuts[actionType], function(ascShortcut) {
return !_.some(removed, function(r) {
return ascShortcut.asc_GetShortcutIndex() === r.asc_GetShortcutIndex();
});
});
}
for (const actionType in customShortcuts) {
customShortcuts[actionType] = customShortcuts[actionType].map(function(ascShortcut) {
return ascShortcut.asc_ToJson();
});
}
Common.localStorage.setItem(this.localStorageKey, JSON.stringify(customShortcuts));
},
_getAscShortcutKeys: function(ascShortcut) {
const keys = [];
ascShortcut.asc_IsCommand() && keys.push('⌘');
ascShortcut.asc_IsCtrl() && keys.push('Ctrl');
ascShortcut.asc_IsAlt() && keys.push('Alt');
ascShortcut.asc_IsShift() && keys.push('Shift');
keys.push(this.keyCodeToKeyName(ascShortcut.asc_GetKeyCode()));
return keys;
},
_sortComparator: function(first, second) {
const priorityModifierKeys = ['asc_IsCommand', 'asc_IsCtrl', 'asc_IsAlt', 'asc_IsShift'];
function getWeight(ascShortcut) {
// Search for the first modifier key
let keyIndex = priorityModifierKeys.length;
for (let i = 0; i < priorityModifierKeys.length; i++) {
if (ascShortcut[priorityModifierKeys[i]]()) {
keyIndex = i;
break;
}
}
if (keyIndex === priorityModifierKeys.length) return -1;
// Count extra modifier keys
let extras = 0;
for (let j = 0; j < priorityModifierKeys.length; j++) {
if (j !== keyIndex && ascShortcut[priorityModifierKeys[j]]()) extras++;
}
// weight = range for main key + “cost” of extra keys
return keyIndex * 100 + extras;
}
let wFirst = getWeight(first.ascShortcut);
let wSecond = getWeight(second.ascShortcut);
if (wFirst !== wSecond) return wFirst - wSecond;
return first.ascShortcut.asc_GetKeyCode() - second.ascShortcut.asc_GetKeyCode();
}
}, Common.Controllers.Shortcuts || {}));
});

View File

@ -70,7 +70,7 @@ define([
--sk-canvas-page-border: #dde0e5; --sk-canvas-line: rgba(0,0,0,.05);
--sk-height-formula: 24px; --sk-padding-formula: 0 0 4px 0;
--sk-border-style-formula: solid; --sk-gap-formula-field: 20px;
--sk-border-radius-formula-field: 0px;
--sk-border-radius-formula-field: 0px; --sk-layout-padding-placeholder: 46px auto;
}`
},
},
@ -91,7 +91,7 @@ define([
--sk-canvas-page-border: #dde0e5; --sk-canvas-line: rgba(0,0,0,.05);
--sk-height-formula: 24px; --sk-padding-formula: 0 0 4px 0;
--sk-border-style-formula: solid; --sk-gap-formula-field: 20px;
--sk-border-radius-formula-field: 0px;
--sk-border-radius-formula-field: 0px; --sk-layout-padding-placeholder: 46px auto;
}`
},
},
@ -113,7 +113,7 @@ define([
--sk-canvas-page-border: #555; --sk-canvas-line: rgba(0,0,0,.05);
--sk-height-formula: 24px; --sk-padding-formula: 0 0 4px 0;
--sk-border-style-formula: solid; --sk-gap-formula-field: 20px;
--sk-border-radius-formula-field: 0px;
--sk-border-radius-formula-field: 0px; --sk-layout-padding-placeholder: 46px auto;
}
.content-theme-dark {
--sk-canvas-content-background: #3a3a3a; --sk-canvas-page-border: #616161;
@ -139,7 +139,7 @@ define([
--sk-canvas-page-border: #555; --sk-canvas-line: rgba(0,0,0,.05);
--sk-height-formula: 24px; --sk-padding-formula: 0 0 4px 0;
--sk-border-style-formula: solid; --sk-gap-formula-field: 20px;
--sk-border-radius-formula-field: 0px;
--sk-border-radius-formula-field: 0px; --sk-layout-padding-placeholder: 46px auto;
}
.content-theme-dark {
--sk-canvas-content-background: #3a3a3a;
@ -164,7 +164,7 @@ define([
--sk-canvas-page-border: #ccc; --sk-canvas-line: rgba(0,0,0,.05);
--sk-height-formula: 24px; --sk-padding-formula: 0 0 4px 0;
--sk-border-style-formula: solid; --sk-gap-formula-field: 20px;
--sk-border-radius-formula-field: 0px;
--sk-border-radius-formula-field: 0px; --sk-layout-padding-placeholder: 46px auto;
}`
},
},
@ -360,6 +360,22 @@ define([
return out_object;
}
const validate_vars = function (obj) {
if ( obj ) {
let i = 0, count = 5;
for (const value of Object.values(obj)) {
if (value != "") {
return true;
}
if ( ++i < count )
break;
}
}
return false;
}
var create_colors_css = function (id, colors) {
if ( !!colors && !!id ) {
var _css_array = [':root .', id, '{'];
@ -563,27 +579,31 @@ define([
}
const colors_obj = get_current_theme_colors();
colors_obj.type = themes_map[theme_id].type;
colors_obj.name = theme_id;
this.api.asc_setSkin(colors_obj);
if ( validate_vars(colors_obj) ) {
colors_obj.type = themes_map[theme_id].type;
colors_obj.name = theme_id;
this.api.asc_setSkin(colors_obj);
if ( !(Common.Utils.isIE10 || Common.Utils.isIE11) ) {
// if ( themes_map[id].source != 'static' ) { // TODO: check writing styles
const theme_obj = Object.assign({
id:id,
colors: colors_obj},
themes_map[id]);
delete theme_obj.source;
if ( !(Common.Utils.isIE10 || Common.Utils.isIE11) ) {
const theme_str = Common.localStorage.getItem("ui-theme");
let theme_id;
if ( theme_str ) {
const reid = /id":\s?"([\w-]+)/.exec(theme_str);
if ( reid[1] ) {
theme_id = reid[1];
}
}
// const theme_obj = {
// id: id,
// type: themes_map[id].type,
// text: themes_map[id].text,
// colors: colors_obj,
// };
if ( theme_id !== id ) {
Common.localStorage.setItem('ui-theme', JSON.stringify(theme_obj));
// }
// if ( themes_map[id].source != 'static' ) { // TODO: check writing styles
const theme_obj = Object.assign({id:id, colors: colors_obj},
themes_map[id]);
delete theme_obj.source;
Common.localStorage.setItem('ui-theme', JSON.stringify(theme_obj));
}
}
}
theme_props = {};
}
@ -622,6 +642,12 @@ define([
this.api = api;
const theme_id = window.uitheme.relevant_theme_id();
if ( window.uitheme.type && themes_map[theme_id] &&
window.uitheme.type !== themes_map[theme_id].type )
{
apply_theme.call(this, window.uitheme.id);
}
const obj = get_current_theme_colors(name_colors);
obj.type = window.uitheme.type ? window.uitheme.type : themes_map[theme_id] ? themes_map[theme_id].type : THEME_TYPE_LIGHT;
obj.name = theme_id;
@ -772,6 +798,10 @@ define([
}
} else if (prop==='tab-style') {
return (Common.Utils.isIE || Common.Controllers.Desktop && Common.Controllers.Desktop.isWinXp()) ? 'fill' : window.getComputedStyle(document.body).getPropertyValue("--toolbar-preferred-tab-style") || 'line';
} else if (prop==='small-btn-size') {
if (!theme_props[prop]) {
theme_props[prop] = window.getComputedStyle(document.body).getPropertyValue("--x-small-btn-size") || '20px';
}
}
return theme_props[prop];
}

View File

@ -6,22 +6,22 @@
</td>
</tr>
<tr>
<td class="padding-large">
<td class="padding-large" width="50%">
<label class="input-label"><%= scope.textAxisTitle %></label>
<div id="chart-dlg-combo-hor-title-<%=idx%>" class="input-group-nr"></div>
<div id="chart-dlg-combo-hor-title-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td class="padding-large">
<label class="input-label margin-left-15"><%= scope.textGridLines %></label>
<div id="chart-dlg-combo-hor-grid-<%=idx%>" class="input-group-nr margin-left-15"></div>
<td class="padding-large" width="50%">
<label class="input-label margin-left-7"><%= scope.textGridLines %></label>
<div id="chart-dlg-combo-hor-grid-<%=idx%>" class="input-group-nr margin-left-7"></div>
</td>
</tr>
</table>
<table cols="3" style="width: 100%" role="presentation">
<tr>
<td class="padding-small" width="100">
<td class="padding-small" width="110">
<label class="input-label"><%= scope.textAxisCrosses %></label>
</td>
<td class="padding-small padding-right-10" width="115">
<td class="padding-small padding-right-10" width="120">
<div id="chart-dlg-combo-h-crosstype-<%=idx%>"></div>
</td>
<td class="padding-small" width="90">
@ -29,7 +29,7 @@
</td>
</tr>
<tr>
<td class="padding-large" width="100">
<td class="padding-large" width="110">
<label class="input-label"><%= scope.textAxisPos %></label>
</td>
<td colspan=2 class="padding-large">
@ -51,13 +51,13 @@
</td>
</tr>
<tr>
<td class="padding-small" width="140">
<td class="padding-small" width="50%">
<label class="input-label"><%= scope.textMajorType %></label>
<div id="chart-dlg-combo-h-major-type-<%=idx%>" class="input-group-nr"></div>
<div id="chart-dlg-combo-h-major-type-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td class="padding-small">
<label class="input-label margin-left-15"><%= scope.textMinorType %></label>
<div id="chart-dlg-combo-h-minor-type-<%=idx%>" class="input-group-nr margin-left-15"></div>
<td class="padding-small" width="50%">
<label class="input-label margin-left-7"><%= scope.textMinorType %></label>
<div id="chart-dlg-combo-h-minor-type-<%=idx%>" class="input-group-nr margin-left-7"></div>
</td>
</tr>
<tr>
@ -66,10 +66,10 @@
</td>
</tr>
<tr>
<td class="padding-large" width="140">
<div id="chart-dlg-input-marks-interval-<%=idx%>"></div>
<td class="padding-large" width="50%">
<div id="chart-dlg-input-marks-interval-<%=idx%>" class="margin-right-7"></div>
</td>
<td class="padding-large">
<td class="padding-large" width="50%">
</td>
</tr>
</table>
@ -82,13 +82,13 @@
</td>
</tr>
<tr>
<td class="padding-small" width="140">
<td class="padding-small" width="50%">
<label class="input-label"><%= scope.textLabelPos %></label>
<div id="chart-dlg-combo-h-label-pos-<%=idx%>" class="input-group-nr"></div>
<div id="chart-dlg-combo-h-label-pos-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td class="padding-small">
<label class="input-label margin-left-15"><%= scope.textLabelDist %></label>
<div id="chart-dlg-input-label-dist-<%=idx%>" class="margin-left-15"></div>
<td class="padding-small" width="50%">
<label class="input-label margin-left-7"><%= scope.textLabelDist %></label>
<div id="chart-dlg-input-label-dist-<%=idx%>" class="margin-left-7"></div>
</td>
</tr>
<tr>

View File

@ -6,22 +6,22 @@
</td>
</tr>
<tr>
<td class="padding-large">
<td class="padding-large" width="50%">
<label class="input-label"><%= scope.textAxisTitle %></label>
<div id="chart-dlg-combo-vert-title-<%=idx%>" class="input-group-nr"></div>
<div id="chart-dlg-combo-vert-title-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td class="padding-large">
<label class="input-label margin-left-15"><%= scope.textGridLines %></label>
<div id="chart-dlg-combo-vert-grid-<%=idx%>" class="input-group-nr margin-left-15"></div>
<td class="padding-large" width="50%">
<label class="input-label margin-left-7"><%= scope.textGridLines %></label>
<div id="chart-dlg-combo-vert-grid-<%=idx%>" class="input-group-nr margin-left-7"></div>
</td>
</tr>
</table>
<table cols="3" style="width: 100%" role="presentation">
<tr>
<td class="padding-small" width="100">
<td class="padding-small" width="110">
<label class="input-label"><%= scope.textMinValue %></label>
</td>
<td class="padding-small padding-right-10" width="115">
<td class="padding-small padding-right-10" width="120">
<div id="chart-dlg-combo-mintype-<%=idx%>"></div>
</td>
<td class="padding-small" width="90">
@ -29,10 +29,10 @@
</td>
</tr>
<tr>
<td class="padding-small" width="100">
<td class="padding-small" width="110">
<label class="input-label"><%= scope.textMaxValue %></label>
</td>
<td class="padding-small padding-right-10" width="115">
<td class="padding-small padding-right-10" width="120">
<div id="chart-dlg-combo-maxtype-<%=idx%>"></div>
</td>
<td class="padding-small" width="90">
@ -40,10 +40,10 @@
</td>
</tr>
<tr>
<td class="padding-large" width="100">
<td class="padding-large" width="110">
<label class="input-label"><%= scope.textAxisCrosses %></label>
</td>
<td class="padding-large padding-right-10" width="115">
<td class="padding-large padding-right-10" width="120">
<div id="chart-dlg-combo-v-crosstype-<%=idx%>"></div>
</td>
<td class="padding-large" width="90">
@ -53,10 +53,10 @@
</table>
<table cols="2" role="presentation">
<tr>
<td class="padding-small padding-right-10" style="min-width: 100px;">
<td class="padding-small padding-right-10" style="min-width: 110px;">
<label class="input-label"><%= scope.textUnits %></label>
</td>
<td class="padding-small padding-right-10" width="115">
<td class="padding-small padding-right-10" width="120>
<div id="chart-dlg-combo-units-<%=idx%>"></div>
</td>
</tr>
@ -90,13 +90,13 @@
</td>
</tr>
<tr>
<td class="padding-large">
<td class="padding-large" width="50%">
<label class="input-label"><%= scope.textMajorType %></label>
<div id="chart-dlg-combo-v-major-type-<%=idx%>" class="input-group-nr"></div>
<div id="chart-dlg-combo-v-major-type-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td class="padding-large">
<label class="input-label margin-left-15"><%= scope.textMinorType %></label>
<div id="chart-dlg-combo-v-minor-type-<%=idx%>" class="input-group-nr margin-left-15"></div>
<td class="padding-large" width="50%">
<label class="input-label margin-left-7"><%= scope.textMinorType %></label>
<div id="chart-dlg-combo-v-minor-type-<%=idx%>" class="input-group-nr margin-left-7"></div>
</td>
</tr>
<tr>
@ -112,11 +112,11 @@
</td>
</tr>
<tr>
<td>
<div id="chart-dlg-combo-v-label-pos-<%=idx%>" class="input-group-nr"></div>
<td width="50%">
<div id="chart-dlg-combo-v-label-pos-<%=idx%>" class="input-group-nr margin-right-7"></div>
</td>
<td>
<button type="button" class="btn btn-text-default auto margin-left-15" id="chart-dlg-btn-v-format-<%=idx%>" style="min-width: 100px;"><%= scope.textFormat %></button>
<td width="50%">
<button type="button" class="btn btn-text-default auto margin-left-7" id="chart-dlg-btn-v-format-<%=idx%>" style="min-width: 100px;"><%= scope.textFormat %></button>
</td>
</tr>
</table>

View File

@ -24,7 +24,7 @@
</div>
<div style="padding:10px 0 0 0;">
<label class="input-label" style="width:12px;">#</label>
<input id="extended-text-color" type="text" role="textbox" style="width:67px;display:inline-block;" class="vertical-align-middle text-align-right">
<input id="extended-text-color" type="text" role="textbox" style="width:67px;display:inline-block;" class="vertical-align-middle">
</div>
</div>
</div>

View File

@ -2,6 +2,7 @@
<div id="search-header">
<label id="search-adv-title" role="heading"></label>
<div id="search-btn-close" class="float-right"></div>
<div id="search-btn-redact-open" class="float-right redact-no-replace-btn"></div>
</div>
<div id="search-container">
<div id="search-adv-settings">
@ -19,8 +20,7 @@
<%= scope.textSearchResults %>
</label>
<div class="search-nav-btns float-right">
<div id="search-adv-back"></div>
<div id="search-adv-next"></div>
<div id="search-adv-back"></div><div id="search-adv-next"></div>
</div>
</td>
</tr>
@ -30,6 +30,12 @@
<button type="button" class="btn btn-text-default" id="search-adv-replace-all" data-hint="1" data-hint-direction="bottom" data-hint-offset="big"><%= scope.textReplaceAll %></button>
</td>
</tr>
<tr class="redact-setting">
<td class="padding-large">
<button type="button" class="btn btn-text-default" id="search-adv-mark" data-hint="1" data-hint-direction="bottom" data-hint-offset="big"><%= scope.textMark %></button>
<button type="button" class="btn btn-text-default" id="search-adv-mark-all" data-hint="1" data-hint-direction="bottom" data-hint-offset="big"><%= scope.textMarkAll %></button>
</td>
</tr>
<tr class="search-options-block">
<td class="padding-large">
<div id="open-search-options" data-hint="1" data-hint-direction="left" data-hint-offset="0, -15">

View File

@ -441,6 +441,33 @@ Common.util.LanguageInfo = new(function() {
0x0433 : ["ven-ZA", "South Africa", "South Africa"]
};
var getLocalLanguageName = function(code) {
return localLanguageName[code] || ['', code];
};
var getLocalLanguageDisplayName = function(code) {
var lang = localLanguageName[code];
if(lang) {
var nativeName = lang[1];
var englishName = lang[2];
function replaceBrackets(text) {
let newText = text.replace('(', ' ');
let lastCloseBracketIndex = newText.lastIndexOf(')');
if (lastCloseBracketIndex !== -1) {
newText = newText.slice(0, lastCloseBracketIndex) + newText.slice(lastCloseBracketIndex + 1);
}
return newText;
}
if(englishName) {
return { native: replaceBrackets(nativeName), english: replaceBrackets(englishName) };
} else {
return { native: nativeName, english: ''};
}
}
return null;
};
var defLanguages = {
'ar': 0x0401, // ar-SA
'az': 0x042C, // az-Latn-AZ
@ -459,10 +486,10 @@ Common.util.LanguageInfo = new(function() {
return null;
};
var regionalData;
return {
getLocalLanguageName: function(code) {
return localLanguageName[code] || ['', code];
},
getLocalLanguageName: getLocalLanguageName,
getLocalLanguageCode: _getLocalLanguageCode,
@ -477,28 +504,7 @@ Common.util.LanguageInfo = new(function() {
* If the English name is missing, returns an object with an empty string for English.
* Returns `null` if no language code is found.
*/
getLocalLanguageDisplayName: function(code) {
var lang = localLanguageName[code];
if(lang) {
var nativeName = lang[1];
var englishName = lang[2];
function replaceBrackets(text) {
let newText = text.replace('(', ' ');
let lastCloseBracketIndex = newText.lastIndexOf(')');
if (lastCloseBracketIndex !== -1) {
newText = newText.slice(0, lastCloseBracketIndex) + newText.slice(lastCloseBracketIndex + 1);
}
return newText;
}
if(englishName) {
return { native: replaceBrackets(nativeName), english: replaceBrackets(englishName) };
} else {
return { native: nativeName, english: ''};
}
}
return null;
},
getLocalLanguageDisplayName: getLocalLanguageDisplayName,
getDefaultLanguageCode: function(name) {
name = name.toLowerCase();
@ -510,6 +516,23 @@ Common.util.LanguageInfo = new(function() {
getLanguages: function() {
return localLanguageName;
},
getRegionalData: function() {
if (regionalData) return regionalData;
regionalData = [{ value: 0x0401 }, { value: 0x042C }, { value: 0x0402 }, { value: 0x0405 }, { value: 0x0406 }, { value: 0x0C07 }, { value: 0x0407 }, {value: 0x0807}, { value: 0x0408 }, { value: 0x0C09 }, { value: 0x3809 }, { value: 0x0809 }, { value: 0x0409 }, { value: 0x0C0A }, { value: 0x080A },
{ value: 0x040B }, { value: 0x040C }, { value: 0x100C }, { value: 0x0421 }, { value: 0x0410 }, { value: 0x0810 }, { value: 0x0411 }, { value: 0x0412 }, { value: 0x0426 }, { value: 0x040E }, { value: 0x0413 }, { value: 0x0415 }, { value: 0x0416 },
{ value: 0x0816 }, { value: 0x0419 }, { value: 0x041B }, { value: 0x0424 }, { value: 0x281A }, { value: 0x241A }, { value: 0x081D }, { value: 0x041D }, { value: 0x041F }, { value: 0x0422 }, { value: 0x042A }, { value: 0x0804 }, { value: 0x0404 }];
regionalData.forEach(function(item) {
var langinfo = getLocalLanguageName(item.value);
var displayName = getLocalLanguageDisplayName(item.value);
item.displayValue = displayName.native;
item.displayValueEn = displayName.english;
item.langName = langinfo[0];
});
return regionalData;
}
}
})();

View File

@ -132,6 +132,7 @@ const tip = function ($) {
if (this.options.arrow === false) $tip.addClass('arrow-free');
if (this.options.cls) $tip.addClass(this.options.cls);
if (this.options.dir) $tip.attr('dir', this.options.dir);
var placementEx = (typeof this.options.placement !== 'function') ? /^([a-zA-Z]+)-?([a-zA-Z]*)$/.exec(this.options.placement) : null;
if (!at && placementEx && !placementEx[2].length) {

View File

@ -215,7 +215,7 @@ define([], function () {
return false;
},
getBoundingClientRect = function(element) {
let rect = element.getBoundingClientRect();
let rect = _extend_object({}, element.getBoundingClientRect());
if (!isOffsetUsedZoom())
return rect;
@ -233,13 +233,13 @@ define([], function () {
return newRect;
},
getOffset = function($element) {
let pos = $element.offset();
let pos = _extend_object({}, $element.offset());
if (!isOffsetUsedZoom())
return pos;
return {left: pos.left * me.zoom, top: pos.top * me.zoom};
},
getPosition = function($element) {
let pos = $element.position();
let pos = _extend_object({}, $element.position());
if (!isOffsetUsedZoom())
return pos;
return {left: pos.left * me.zoom, top: pos.top * me.zoom};
@ -1600,6 +1600,12 @@ define([], function () {
paletteWidth: 174
};
Common.UI.blockOperations = {
ApplyEditRights: -255,
LoadingDocument: -256,
UpdateChart: -257
};
Common.UI.isValidNumber = function (val) {
let regstr = new RegExp('^\s*[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)\s*$');
if (typeof val === 'string') {

View File

@ -152,9 +152,9 @@ define([], function () { 'use strict';
$window.find('.body > .box').css('height', height);
},
fixHeight: function() { // check height of the content
fixHeight: function(force) { // check height of the content
let diff = this.content_panels.filter('.active').height() - this.content_panel.height();
(diff>0) && this.setInnerHeight(parseInt(this.$window.find('.body > .box').css('height')) + diff);
(force || diff>0) && this.setInnerHeight(parseInt(this.$window.find('.body > .box').css('height')) + diff);
},
onDlgBtnClick: function(event) {

View File

@ -351,7 +351,6 @@ define([
iconCls: 'toolbar__icon btn-more',
hint: this.textSort,
menu: new Common.UI.Menu({
style: 'min-width: auto;',
items: [
{
caption: this.mniDateDesc,
@ -399,8 +398,41 @@ define([
},
{
caption: '--',
visible: false
visible: true
},
this.menuFilterComments = new Common.UI.MenuItem({
caption: this.mniFilterComments,
checkable: false,
visible: true,
menu: new Common.UI.Menu({
menuAlign: 'tl-tr',
style: 'min-width: auto;',
items: [
{
caption: this.textOpen,
checkable: true,
visible: true,
toggleGroup: 'filterstatus',
value: 'open'
},
{
caption: this.textResolved,
checkable: true,
visible: true,
toggleGroup: 'filterstatus',
value: 'resolved'
},
{
caption: this.textAll,
checkable: true,
visible: true,
toggleGroup: 'filterstatus',
value: 'all',
checked: true
}
]
})
}),
this.menuFilterGroups = new Common.UI.MenuItem({
caption: this.mniFilterGroups,
checkable: false,
@ -441,7 +473,9 @@ define([
this.buttonCancel.on('click', _.bind(this.onClickCancelDocumentComment, this));
this.buttonClose.on('click', _.bind(this.onClickClosePanel, this));
this.buttonSort.menu.on('item:toggle', _.bind(this.onSortClick, this));
this.buttonSort.menu.on('show:before', _.bind(this.onShowBeforeSortButtonMenu, this));
this.menuFilterGroups.menu.on('item:toggle', _.bind(this.onFilterGroupsClick, this));
this.menuFilterComments.menu.on('item:toggle', _.bind(this.onFilterCommentsClick, this));
this.mnuAddCommentToDoc.on('click', _.bind(this.onClickShowBoxDocumentComment, this));
this.buttonAddNew.on('click', _.bind(this.onClickAddNewComment, this));
@ -903,10 +937,18 @@ define([
state && this.fireEvent('comment:sort', [item.value]);
},
onShowBeforeSortButtonMenu: function(menu, item, state) {
Common.UI.TooltipManager.closeTip('commentFilter');
},
onFilterGroupsClick: function(menu, item, state) {
state && this.fireEvent('comment:filtergroups', [item.value]);
},
onFilterCommentsClick: function(menu, item, state) {
state && this.fireEvent('comment:filtercomments', [item.value]);
},
onClickClosePanel: function() {
Common.NotificationCenter.trigger('leftmenu:change', 'hide');
},
@ -921,6 +963,7 @@ define([
textClose : 'Close',
textResolved : 'Resolved',
textResolve : 'Resolve',
textOpen : 'Open',
textEnterCommentHint : 'Enter your comment here',
textEdit : 'Edit',
textAdd : "Add",
@ -937,6 +980,7 @@ define([
textClosePanel: 'Close comments',
textViewResolved: 'You have not permission for reopen comment',
mniFilterGroups: 'Filter by Group',
mniFilterComments: 'Show comments',
textAll: 'All',
txtEmpty: 'There are no comments in the document.',
textSortFilter: 'Sort and filter comments',

View File

@ -55,20 +55,31 @@ define([], function () { 'use strict';
buttons: ['ok']
}, options || {});
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
const shortcutsController = app.getController('Common.Controllers.Shortcuts');
const keysShortcuts = { Copy: '', Cut: '', Paste: ''};
for (const actionType in keysShortcuts) {
const shortcuts = shortcutsController.getShortcutsByActionType(actionType);
if(shortcuts && shortcuts[0]) {
keysShortcuts[actionType] = shortcuts[0].keys.join('+');
}
}
this.template = [
'<div class="box">',
'<p class="message">' + this.textMsg + '</p>',
'<div class="hotkeys">',
'<div>',
'<p class="hotkey">' + Common.Utils.String.platformKey('Ctrl+C', '{0}') + '</p>',
'<p class="hotkey">' + keysShortcuts.Copy + '</p>',
'<p class="message">' + this.textToCopy + '</p>',
'</div>',
'<div>',
'<p class="hotkey">' + Common.Utils.String.platformKey('Ctrl+X', '{0}') + '</p>',
'<p class="hotkey">' + keysShortcuts.Cut + '</p>',
'<p class="message">' + this.textToCut + '</p>',
'</div>',
'<div>',
'<p class="hotkey">' + Common.Utils.String.platformKey('Ctrl+V', '{0}') + '</p>',
'<p class="hotkey">' + keysShortcuts.Paste + '</p>',
'<p class="message">' + this.textToPaste + '</p>',
'</div>',
'</div>',

View File

@ -44,12 +44,14 @@ define([
_.extend(_options, {
id: 'id-external-diagram-editor',
title: this.textTitle,
storageName: 'diagram-editor',
// storageName: 'diagram-editor',
sdkplaceholder: 'id-diagram-editor-placeholder',
initwidth: 900,
initheight: 700,
initwidth: 730,
initheight: 275,
minwidth: 730,
minheight: 275
minheight: 275,
footer: false,
transparentMask: true
}, options);
this._chartData = null;

View File

@ -42,36 +42,44 @@ define([], function () {
initialize : function(options) {
var filter = Common.localStorage.getKeysFilter(),
appPrefix = (filter && filter.length) ? filter.split(',')[0] : '';
this.storageName = appPrefix + (options.storageName || 'external-editor');
this.storageName = options.storageName ? appPrefix + options.storageName : null;
var _options = {},
width = options.initwidth || 900,
height = options.initheight || 700;
var value = Common.localStorage.getItem(this.storageName + '-width');
value && (width = parseInt(value));
value = Common.localStorage.getItem(this.storageName + '-height');
value && (height = parseInt(value));
height = options.initheight || 700,
footer = options.footer !== undefined ? options.footer : true;
if (this.storageName) {
var value = Common.localStorage.getItem(this.storageName + '-width');
value && (width = parseFloat(value));
value = Common.localStorage.getItem(this.storageName + '-height');
value && (height = parseFloat(value));
}
_.extend(_options, {
width: width,
height: height,
cls: 'advanced-settings-dlg',
header: true,
toolclose: 'hide',
toolcallback: _.bind(this.onToolClose, this),
resizable: true
resizable: true,
footer: footer
}, options);
// (!_options.buttons || _.size(_options.buttons)<1) && (_options.cls += ' no-footer');
_options.contentHeight = height;
!footer && (_options.cls += ' no-footer');
this.template = [
'<div id="id-editor-container" class="box" style="height:' + _options.contentHeight + 'px; padding: 0 5px;">',
'<div id="id-editor-container" class="box" style="padding: 0 5px;">',
'<div id="' + (_options.sdkplaceholder || '') + '" style="width: 100%;height: 100%;"></div>',
'</div>',
'<% if (footer) { %>',
'<div class="separator horizontal"></div>',
'<div class="footer" style="text-align: center;">',
'<button id="id-btn-editor-apply" class="btn normal dlg-btn primary auto" result="ok" data-hint="1" data-hint-direction="bottom" data-hint-offset="big">' + this.textSave + '</button>',
'<button id="id-btn-editor-cancel" class="btn normal dlg-btn" result="cancel" data-hint="1" data-hint-direction="bottom" data-hint-offset="big">' + this.textClose + '</button>',
'</div>'
'</div>',
'<% } %>'
].join('');
_options.tpl = _.template(this.template)(_options);
@ -86,15 +94,14 @@ define([], function () {
Common.UI.Window.prototype.render.call(this);
this.boxEl = this.$window.find('.body > .box');
var bodyEl = this.$window.find('> .body');
this._headerFooterHeight = this.initConfig.header ? parseInt(this.$window.find('.header').css('height')) : 0;
this._headerFooterHeight += parseInt(this.$window.find('.footer').css('height')) + parseInt(bodyEl.css('padding-top')) + parseInt(bodyEl.css('padding-bottom'));
this._headerFooterHeight += ((parseInt(this.$window.css('border-top-width')) + parseInt(this.$window.css('border-bottom-width'))));
this._headerFooterHeight = this.initConfig.header ? parseFloat(this.$window.find('.header').css('height')) : 0;
this._headerFooterHeight += (this.initConfig.footer ? parseFloat(this.$window.find('.footer').css('height')) : 0) + parseFloat(bodyEl.css('padding-top')) + parseFloat(bodyEl.css('padding-bottom'));
this._headerFooterHeight += ((parseFloat(this.$window.css('border-top-width')) + parseFloat(this.$window.css('border-bottom-width'))));
var resizeborder = this.$window.find('.resize-border.bottom');
if (resizeborder.length>0)
this._headerFooterHeight += $(resizeborder[0]).height()-2;
var _inner_height = Common.Utils.innerHeight() - Common.Utils.InternalSettings.get('window-inactive-area-top');
if (_inner_height < this.initConfig.contentHeight + this._headerFooterHeight) {
this.initConfig.contentHeight = _inner_height - this._headerFooterHeight;
this.boxEl.css('height', this.initConfig.contentHeight);
}
this.boxEl.css('height', this.getHeight() - this._headerFooterHeight);
this.btnSave = new Common.UI.Button({
el: this.$window.find('#id-btn-editor-apply'),
@ -142,12 +149,12 @@ define([], function () {
},
setHeight: function(height) {
if (height >= 0) {
if (this.$window && height >= 0) {
var min = parseInt(this.$window.css('min-height'));
height < min && (height = min);
this.$window.height(height);
var header_height = (this.initConfig.header) ? parseInt(this.$window.find('> .header').css('height')) : 0;
var header_height = (this.initConfig.header) ? parseFloat(this.$window.find('> .header').css('height')) : 0;
this.$window.find('> .body').css('height', height-header_height);
this.$window.find('> .body > .box').css('height', height-this._headerFooterHeight);
@ -166,8 +173,8 @@ define([], function () {
setInnerSize: function(width, height) {
var maxHeight = Common.Utils.innerHeight(),
maxWidth = Common.Utils.innerWidth(),
borders_width = (parseInt(this.$window.css('border-left-width')) + parseInt(this.$window.css('border-right-width'))),
paddings = (parseInt(this.boxEl.css('padding-left')) + parseInt(this.boxEl.css('padding-right')));
borders_width = (parseFloat(this.$window.css('border-left-width')) + parseFloat(this.$window.css('border-right-width'))),
paddings = (parseFloat(this.boxEl.css('padding-left')) + parseFloat(this.boxEl.css('padding-right')));
height += 90; // add toolbar and statusbar height
if (maxHeight<height + this._headerFooterHeight)
height = maxHeight - this._headerFooterHeight;
@ -188,8 +195,10 @@ define([], function () {
onWindowResize: function (args) {
if (args && args[1]=='end') {
var value = this.getSize();
Common.localStorage.setItem(this.storageName + '-width', value[0]);
Common.localStorage.setItem(this.storageName + '-height', value[1]);
if (this.storageName) {
Common.localStorage.setItem(this.storageName + '-width', value[0]);
Common.localStorage.setItem(this.storageName + '-height', value[1]);
}
}
},

View File

@ -42,9 +42,7 @@ define([
], function () {
'use strict';
SSE.Views = SSE.Views || {};
SSE.Views.ExternalLinksDlg = Common.Views.AdvancedSettingsWindow.extend(_.extend({
Common.Views.ExternalLinksDlg = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
alias: 'ExternalLinksDlg',
@ -219,7 +217,10 @@ define([
_setDefaults: function (props) {
this.refreshList();
this.api && this.chUpdate.setValue(this.api.asc_getUpdateLinks(), true);
if (!window.SSE)
this.chUpdate.setVisible(false);
else if (this.api)
this.chUpdate.setValue(this.api.asc_getUpdateLinks(), true);
},
refreshList: function() {
@ -247,7 +248,7 @@ define([
var rec = this.linksList.getSelectedRec();
if (rec) {
this.isOffline && this.setLinkStatus(rec.get('linkid'), this.textOk);
this.api.asc_updateExternalReferences([rec.get('externalRef')]);
Common.NotificationCenter.trigger('data:updatereferences', [rec.get('externalRef')], true);
}
},
@ -261,7 +262,7 @@ define([
arr.push(item.get('externalRef'));
me.isOffline && me.setLinkStatus(item.get('linkid'), me.textOk);
}, this);
(arr.length>0) && this.api.asc_updateExternalReferences(arr);
(arr.length>0) && Common.NotificationCenter.trigger('data:updatereferences', arr, true);
} else
this.onUpdate();
},
@ -387,8 +388,6 @@ define([
var props = Common.UI.Themes.getThemeProps('font');
el.style.fontSize = props && props.size ? props.size : '11px';
el.style.fontFamily = props && props.name ? props.name : 'Arial, Helvetica, "Helvetica Neue", sans-serif';
el.style.fontFamily = document.documentElement.style.getPropertyValue("--font-family-base-custom") || 'Arial, Helvetica, "Helvetica Neue", sans-serif';
el.style.position = "absolute";
el.style.top = '-1000px';
el.style.left = '-1000px';
@ -435,5 +434,5 @@ define([
textUpdating: 'Updating...',
textAutoUpdate: 'Update automatically'
}, SSE.Views.ExternalLinksDlg || {}));
}, Common.Views.ExternalLinksDlg || {}));
});

View File

@ -51,7 +51,7 @@ define([
initwidth: 1030,
initheight: 700,
minwidth: 1030,
minheight: 275
minheight: 310
}, options);
this._oleData = null;

View File

@ -41,10 +41,10 @@ define([
'common/main/lib/view/AdvancedSettingsWindow',
], function () { 'use strict';
SSE.Views.FormatSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({
Common.Views.FormatSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
contentWidth: 284,
contentHeight: 260
contentHeight: 265
},
initialize : function(options) {
@ -84,7 +84,7 @@ define([
this.props = options.props;
this.linked = options.linked || false;
var height = this.linked ? 275 : 260;
var height = this.linked ? 275 : 265;
_.extend(this.options, {
title: this.textTitle,
contentHeight: height,
@ -132,10 +132,16 @@ define([
'<div id="format-settings-combo-negative" class="input-group-nr" style="width:264px;"></div>',
'</td>',
'</tr>',
'<tr class="format-lang">',
'<td class="padding-large">',
'<label class="header">', me.textLocale,'</label>',
'<div id="format-settings-combo-lang" class="input-group-nr" style="width:264px;"></div>',
'</td>',
'</tr>',
'<tr class="format-type">',
'<td class="padding-large">',
'<label class="header">', me.textFormat,'</label>',
'<div id="format-settings-combo-type" class="input-group-nr" style="width:264px;"></div>',
'<div id="format-settings-list-type" class="input-group-nr" style="width:264px; height: 93px;"></div>',
'</td>',
'</tr>',
'<tr class="format-code">',
@ -220,16 +226,14 @@ define([
});
this.cmbSymbols.on('selected', _.bind(this.onSymbolsSelect, this));
this.cmbType = new Common.UI.ComboBox({
el: $('#format-settings-combo-type'),
cls: 'input-group-nr',
menuStyle: 'min-width: 264px;max-height:235px;',
editable: false,
data: [],
scrollAlwaysVisible: true,
takeFocusOnClose: true
this.listType = new Common.UI.ListView({
el: $('#format-settings-list-type'),
store: new Common.UI.DataViewStore(),
tabindex: 1,
itemTemplate: _.template('<div id="<%= id %>" class="list-item" style="pointer-events:none;overflow: hidden; text-overflow: ellipsis;"><%= Common.Utils.String.htmlEncode(displayValue) %></div>')
});
this.cmbType.on('selected', _.bind(this.onTypeSelect, this));
this.listType.on('item:select', _.bind(this.onListTypeSelect, this));
this.listType.on('entervalue', _.bind(this.onPrimary, this));
this.codesList = new Common.UI.ListView({
el: $('#format-settings-list-code'),
@ -270,6 +274,34 @@ define([
});
this.chLinked.setVisible(this.linked);
this.cmbLang = new Common.UI.ComboBox({
el : $('#format-settings-combo-lang'),
menuStyle : 'min-width: 100%; max-height: 185px;',
cls : 'input-group-nr',
editable : false,
takeFocusOnClose: true,
data : Common.util.LanguageInfo.getRegionalData(),
itemsTemplate: _.template([
'<% _.each(items, function(item) { %>',
'<li id="<%= item.id %>" data-value="<%= item.value %>">',
'<a tabindex="-1" type="menuitem" role="menuitemcheckbox" aria-checked="false">',
'<div>',
'<%= item.displayValue %>',
'</div>',
'<label style="opacity: 0.6"><%= item.displayValueEn %></label>',
'</a>',
'</li>',
'<% }); %>'
].join('')),
search: true,
searchFields: ['displayValue', 'displayValueEn'],
scrollAlwaysVisible: true
});
this.cmbLang.setValue(0x0409);
this.cmbLang.on('selected', _.bind(function(combo, record) {
this.onSelectLang(record.value);
}, this));
this._decimalPanel = this.$window.find('.format-decimal');
this._negativePanel = this.$window.find('.format-negative');
this._separatorPanel = this.$window.find('.format-separator');
@ -277,6 +309,7 @@ define([
this._symbolsPanel = this.$window.find('.format-symbols');
this._codePanel = this.$window.find('.format-code');
this._nocodePanel = this.$window.find('.format-no-code');
this._langPanel = this.$window.find('.format-lang');
this.$window.find('.format-sample').toggleClass('hidden', this.linked);
this.lblExample = this.$window.find('#format-settings-label-example');
@ -285,7 +318,7 @@ define([
},
getFocusedComponents: function() {
return [this.cmbFormat, this.spnDecimal, this.chSeparator, this.cmbSymbols, this.cmbNegative, this.cmbType, this.inputCustomFormat, this.codesList, this.chLinked].concat(this.getFooterButtons());
return [this.cmbFormat, this.spnDecimal, this.chSeparator, this.cmbSymbols, this.cmbNegative, this.cmbLang, this.listType, this.inputCustomFormat, this.codesList, this.chLinked].concat(this.getFooterButtons());
},
getDefaultFocusableComponent: function () {
@ -302,12 +335,18 @@ define([
_setDefaults: function (props) {
if (props && props.formatInfo) {
if (this.langId)
if (props.langId)
this.langId = props.langId;
this.cmbFormat.setValue(props.formatInfo.asc_getType(), this.txtCustom);
var type = props.formatInfo.asc_getType(),
item = this.cmbLang.store.findWhere({value: type == Asc.c_oAscNumFormatType.Date || type == Asc.c_oAscNumFormatType.Time ? props.formatInfo.asc_getSymbol() || this.langId : this.langId});
item = item ? item.get('value') : 0x0409;
this.cmbLang.setValue(item)
this.cmbFormat.setValue(type, this.txtCustom);
this.FormatInfo = props.formatInfo;
if ((props.formatInfo.asc_getType() == Asc.c_oAscNumFormatType.Custom) && props.format)
if ((type == Asc.c_oAscNumFormatType.Custom) && props.format)
this.CustomFormat = this.Format = props.format;
this.onFormatSelect(this.cmbFormat, this.cmbFormat.getSelectedRecord(), null, props.formatInfo);
@ -326,15 +365,21 @@ define([
else
this.cmbNegative.setValue(this.api.asc_getLocaleExample(props.format));
} else if (this._state.hasType) {
var selectedItem = this.cmbType.store.findWhere({value: props.format});
if (selectedItem)
this.cmbType.selectRecord(selectedItem);
else if (props.formatInfo.asc_getType() == Asc.c_oAscNumFormatType.Fraction)
this.cmbType.setValue(this.txtCustom);
else if (props.formatInfo.asc_getType() == Asc.c_oAscNumFormatType.Time)
this.cmbType.setValue(this.api.asc_getLocaleExample(props.format, 1.534));
else
this.cmbType.setValue(this.api.asc_getLocaleExample(props.format, 38822));
var selectedItem = this.listType.store.findWhere({value: props.format});
if(selectedItem) {
this.listType.selectRecord(selectedItem);
this.listType.scrollToRecord(selectedItem);
} else if(type == Asc.c_oAscNumFormatType.Time.Fraction) {
this.listType.deselectAll();
} else {
var defaultNumber = (type == Asc.c_oAscNumFormatType.Time ? 1.534 : 38822);
selectedItem = this.listType.store.unshift({
value: props.format,
displayValue: this.api.asc_getLocaleExample(props.format, defaultNumber)
});
this.listType.selectRecord(selectedItem);
this.listType.scrollToRecord(selectedItem);
}
}
this.Format = props.format;
this.lblExample.text(this.api.asc_getLocaleExample(this.Format));
@ -449,8 +494,8 @@ define([
this.chLinked.setValue(false, true);
},
onTypeSelect: function(combo, record){
this.Format = record.value;
onListTypeSelect: function(listView, itemView, record) {
this.Format = record.get('value');
this.lblExample.text(this.api.asc_getLocaleExample(this.Format));
this.chLinked.setValue(false, true);
},
@ -471,11 +516,12 @@ define([
this.FormatType = record.value;
var hasDecimal = (record.value == Asc.c_oAscNumFormatType.Number || record.value == Asc.c_oAscNumFormatType.Scientific || record.value == Asc.c_oAscNumFormatType.Accounting ||
var isDateTime = record.value == Asc.c_oAscNumFormatType.Date || record.value == Asc.c_oAscNumFormatType.Time,
hasDecimal = (record.value == Asc.c_oAscNumFormatType.Number || record.value == Asc.c_oAscNumFormatType.Scientific || record.value == Asc.c_oAscNumFormatType.Accounting ||
record.value == Asc.c_oAscNumFormatType.Currency || record.value == Asc.c_oAscNumFormatType.Percent),
hasNegative = (record.value == Asc.c_oAscNumFormatType.Number || record.value == Asc.c_oAscNumFormatType.Currency || record.value == Asc.c_oAscNumFormatType.Accounting),
hasSeparator = (record.value == Asc.c_oAscNumFormatType.Number),
hasType = (record.value == Asc.c_oAscNumFormatType.Date || record.value == Asc.c_oAscNumFormatType.Time || record.value == Asc.c_oAscNumFormatType.Fraction),
hasType = (isDateTime || record.value == Asc.c_oAscNumFormatType.Fraction),
hasSymbols = (record.value == Asc.c_oAscNumFormatType.Accounting || record.value == Asc.c_oAscNumFormatType.Currency),
hasCode = (record.value == Asc.c_oAscNumFormatType.Custom),
me = this,
@ -489,7 +535,7 @@ define([
info.asc_setDecimalPlaces(hasDecimal ? valDecimal : 0);
info.asc_setSeparator(hasSeparator ? valSeparator : false);
if (hasNegative || record.value == Asc.c_oAscNumFormatType.Date || record.value == Asc.c_oAscNumFormatType.Time) {
if (hasNegative || isDateTime) {
if (hasSymbols) {
if (!me.CurrencySymbolsData) {
me.CurrencySymbolsData = [];
@ -513,6 +559,8 @@ define([
this.cmbSymbols.setValue(valSymbol);
}
info.asc_setSymbol(this.cmbSymbols.getValue());
} else if (isDateTime) {
info.asc_setSymbol(this.cmbLang.getValue());
}
var formatsarr = this.api.asc_getFormatCells(info),
@ -526,14 +574,20 @@ define([
this.cmbNegative.selectRecord(this.cmbNegative.store.at(0));
this.cmbNegative.cmpEl.find('li:nth-child(2) a, li:nth-child(4) a').css({color: '#ff0000'});
} else {
this.cmbType.setData(data);
this.cmbType.selectRecord(this.cmbType.store.at(0));
this.listType.store.reset(data);
this.listType.selectRecord(this.listType.store.at(0));
this.listType.scrollToRecord(this.listType.store.at(0));
this.listType.$el[0].style.height = "93px";
}
this.Format = formatsarr[0];
} else if (record.value == Asc.c_oAscNumFormatType.Fraction) {
this.cmbType.setData(this.FractionData);
this.cmbType.selectRecord(this.cmbType.store.at(0));
this.Format = this.cmbType.getValue();
this.listType.store.reset(this.FractionData);
this.listType.selectRecord(this.listType.store.at(0));
this.listType.scrollToRecord(this.listType.store.at(0));
this.listType.$el[0].style.height = "139px";
this.Format = this.listType.getSelectedRec().get('value');
} else {
this.Format = this.api.asc_getFormatCells(info)[0];
}
@ -581,11 +635,35 @@ define([
this._symbolsPanel.toggleClass('hidden', !hasSymbols);
this._codePanel.toggleClass('hidden', !hasCode);
this._nocodePanel.toggleClass('hidden', hasCode);
this._langPanel.toggleClass('hidden', !isDateTime);
this._state = { hasDecimal: hasDecimal, hasNegative: hasNegative, hasSeparator: hasSeparator, hasType: hasType, hasSymbols: hasSymbols, hasCode: hasCode};
!initFormatInfo && this.chLinked.setValue(false, true);
},
onSelectLang: function(lang) {
var info = new Asc.asc_CFormatCellsInfo();
info.asc_setType(this.FormatType);
info.asc_setDecimalPlaces(0);
info.asc_setSeparator(false);
info.asc_setSymbol(lang);
var me = this,
formatsarr = this.api.asc_getFormatCells(info),
data = [],
exampleVal = (this.FormatType == Asc.c_oAscNumFormatType.Date) ? 38822 : ((this.FormatType == Asc.c_oAscNumFormatType.Time) ? 1.534 : parseFloat("-1234.12345678901234567890"));
formatsarr.forEach(function(item) {
data.push({value: item, displayValue: me.api.asc_getLocaleExample(item, exampleVal)});
});
this.listType.store.reset(data, {silent: false});
this.listType.selectRecord(this.listType.store.at(0));
this.listType.scrollToRecord(this.listType.store.at(0));
this.Format = formatsarr[0];
this.FormatInfo = info;
this.lblExample.text(this.api.asc_getLocaleExample(this.Format));
},
textTitle: 'Number Format',
textCategory: 'Category',
textDecimal: 'Decimal',
@ -615,7 +693,8 @@ define([
txtSample: 'Sample:',
txtNone: 'None',
textLinked: 'Linked to source',
txtCustomWarning: 'Please enter the custom number format carefully. Spreadsheet Editor does not check custom formats for errors that may affect the xlsx file.'
txtCustomWarning: 'Please enter the custom number format carefully. Spreadsheet Editor does not check custom formats for errors that may affect the xlsx file.',
textLocale: 'Locale'
}, SSE.Views.FormatSettingsDialog || {}))
}, Common.Views.FormatSettingsDialog || {}))
});

View File

@ -156,7 +156,7 @@ define([
'</div>' +
'<div class="lr-separator" id="id-box-doc-name">' +
// '<label id="title-doc-name" /></label>' +
'<input id="title-doc-name" autofill="off" autocomplete="off"/></input>' +
'<input id="title-doc-name" autofill="off" autocomplete="off" spellcheck="false"/></input>' +
'</div>' +
'<div class="hedset">' +
'<div class="btn-slot" data-layout-name="header-user">' +
@ -453,7 +453,6 @@ define([
}
if ( me.btnPrint ) {
me.btnPrint.updateHint(me.tipPrint + Common.Utils.String.platformKey('Ctrl+P'));
me.btnPrint.on('click', function (e) {
me.fireEvent('print', me);
});
@ -467,28 +466,24 @@ define([
}
if ( me.btnSave ) {
me.btnSave.updateHint(appConfig.canSaveToFile || appConfig.isDesktopApp && appConfig.isOffline ? me.tipSave + (isPDFEditor ? '' : Common.Utils.String.platformKey('Ctrl+S')) : me.tipDownload);
me.btnSave.on('click', function (e) {
me.fireEvent('save', me);
});
}
if ( me.btnUndo ) {
me.btnUndo.updateHint(me.tipUndo + Common.Utils.String.platformKey('Ctrl+Z'));
me.btnUndo.on('click', function (e) {
me.fireEvent('undo', me);
});
}
if ( me.btnRedo ) {
me.btnRedo.updateHint(me.tipRedo + Common.Utils.String.platformKey('Ctrl+Y'));
me.btnRedo.on('click', function (e) {
me.fireEvent('redo', me);
});
}
if (me.btnStartOver) {
me.btnStartOver.updateHint(me.tipStartOver + (Common.Utils.String.platformKey(Common.Utils.isMac ? 'Ctrl+Shift+enter' : 'Ctrl+F5')));
me.btnStartOver.on('click', function (e) {
me.fireEvent('startover', me);
});
@ -606,8 +601,6 @@ define([
});
}
if (me.btnSearch)
me.btnSearch.updateHint(me.tipSearch + Common.Utils.String.platformKey('Ctrl+F'));
var menuTemplate = _.template('<a id="<%= id %>" tabindex="-1" type="menuitem" class="menu-item"><div>' +
'<% if (!_.isEmpty(iconCls)) { %>' +
@ -711,6 +704,11 @@ define([
}
if (appConfig.twoLevelHeader && !appConfig.compactHeader)
Common.NotificationCenter.on('window:resize', onResize);
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
if(app && app.getController('Common.Controllers.Shortcuts')) {
app.getController('Common.Controllers.Shortcuts').updateShortcutHints(this.shortcutHints);
}
}
function onFocusDocName(e){
@ -796,6 +794,8 @@ define([
var filter = Common.localStorage.getKeysFilter();
this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : '';
this.shortcutHints = {};
me.btnGoBack = new Common.UI.Button({
id: 'btn-go-back',
cls: 'btn-header',
@ -820,6 +820,10 @@ define([
dataHintDirection: 'bottom',
dataHintOffset: 'big'
});
this.shortcutHints.OpenFindDialog = {
btn: me.btnSearch,
label: me.tipSearch
};
me.btnFavorite = new Common.UI.Button({
id: 'id-btn-favorite',
@ -876,7 +880,7 @@ define([
this.logo.addClass('hidden');
} else if (this.branding.logo.image || this.branding.logo.imageDark || this.branding.logo.imageLight) {
_logoImage = logo.image;
this.logo.html('<img src="' + _logoImage + '" style="max-width:100px; max-height:20px; margin: 0;"/>');
this.logo.html('<img src="' + _logoImage + '" style="max-width:300px; max-height:20px; margin: 0;"/>');
this.logo.css({'background-image': 'none', width: 'auto'});
(this.branding.logo.url || this.branding.logo.url===undefined) && this.logo.addClass('link');
}
@ -919,8 +923,13 @@ define([
if ( (config.canDownload || config.canDownloadOrigin) && !config.isOffline )
this.btnDownload = createTitleButton('toolbar__icon icon--inverse btn-download', $html.findById('#slot-hbtn-download'), undefined, 'bottom', 'big');
if ( config.canPrint )
if ( config.canPrint ) {
this.btnPrint = createTitleButton('toolbar__icon icon--inverse btn-print', $html.findById('#slot-hbtn-print'), undefined, 'bottom', 'big', 'P');
this.shortcutHints.PrintPreviewAndPrint = {
btn: me.btnPrint,
label: me.tipPrint + (!!window.VE ? (Common.Utils.String.platformKey('Ctrl+P')) : '')
};
}
if ( config.canQuickPrint )
this.btnPrintQuick = createTitleButton('toolbar__icon icon--inverse btn-quick-print', $html.findById('#slot-hbtn-print-quick'), undefined, 'bottom', 'big', 'Q');
@ -1060,6 +1069,10 @@ define([
if ( config.canPrint && config.twoLevelHeader ) {
me.btnPrint = createTitleButton('toolbar__icon icon--inverse btn-print', $html.findById('#slot-btn-dt-print'), true, undefined, undefined, 'P');
me.shortcutHints.PrintPreviewAndPrint = {
btn: me.btnPrint,
label: me.tipPrint
};
!Common.localStorage.getBool(me.appPrefix + 'quick-access-print', true) && me.btnPrint.hide();
}
if ( config.canQuickPrint && config.twoLevelHeader ) {
@ -1070,16 +1083,40 @@ define([
let save_icon = config.canSaveToFile || config.isDesktopApp && config.isOffline ? 'btn-save' : 'btn-download';
me.btnSave = createTitleButton('toolbar__icon icon--inverse ' + save_icon, $html.findById('#slot-btn-dt-save'), true, undefined, undefined, 'S');
!Common.localStorage.getBool(me.appPrefix + 'quick-access-save', true) && me.btnSave.hide();
// Set hint text based on save availability and editor type
if (appConfig.canSaveToFile || appConfig.isDesktopApp && appConfig.isOffline) {
me.shortcutHints.Save = {
btn: me.btnSave,
label: me.tipSave
};
} else {
me.btnSave.updateHint(me.tipDownload);
}
}
me.btnUndo = createTitleButton('toolbar__icon icon--inverse btn-undo icon-rtl', $html.findById('#slot-btn-dt-undo'), true, undefined, undefined, 'Z',
[Common.enumLock.undoLock, Common.enumLock.fileMenuOpened, Common.enumLock.lostConnect]);
!Common.localStorage.getBool(me.appPrefix + 'quick-access-undo', true) && me.btnUndo.hide();
me.shortcutHints.EditUndo = {
btn: me.btnUndo,
label: me.tipUndo
};
me.btnRedo = createTitleButton('toolbar__icon icon--inverse btn-redo icon-rtl', $html.findById('#slot-btn-dt-redo'), true, undefined, undefined, 'Y',
[Common.enumLock.redoLock, Common.enumLock.fileMenuOpened, Common.enumLock.lostConnect]);
!Common.localStorage.getBool(me.appPrefix + 'quick-access-redo', true) && me.btnRedo.hide();
me.shortcutHints.EditRedo = {
btn: me.btnRedo,
label: me.tipRedo
};
if (isPEEditor) {
me.btnStartOver= createTitleButton('toolbar__icon icon--inverse btn-preview', $html.findById('#slot-btn-dt-start-over'), true, undefined, undefined, 'O');
!Common.localStorage.getBool(me.appPrefix + 'quick-access-start-over', true) && me.btnStartOver.hide();
me.btnStartOver= createTitleButton('toolbar__icon icon--inverse btn-preview', $html.findById('#slot-btn-dt-start-over'), true, undefined, undefined, 'O');
!Common.localStorage.getBool(me.appPrefix + 'quick-access-start-over', true) && me.btnStartOver.hide();
me.shortcutHints.DemonstrationStartPresentation = {
btn: me.btnStartOver,
label: me.tipStartOver
};
}
me.btnQuickAccess = new Common.UI.Button({
cls: 'btn-header no-caret',
@ -1111,7 +1148,7 @@ define([
element.addClass('hidden');
} else if (value.logo.image || value.logo.imageDark || value.logo.imageLight) {
_logoImage = logo.image;
element.html('<img src="' + _logoImage + '" style="max-width:100px; max-height:20px; margin: 0;"/>');
element.html('<img src="' + _logoImage + '" style="max-width:300px; max-height:20px; margin: 0;"/>');
element.css({'background-image': 'none', width: 'auto'});
(value.logo.url || value.logo.url===undefined) && element.addClass('link');
}

View File

@ -265,6 +265,7 @@ define([
createBackgroundPluginsButton: function () {
var _set = Common.enumLock;
var btn = new Common.UI.Button({
id: 'id-toolbar-btn-background-plugin',
cls: 'btn-toolbar x-huge icon-top',
iconCls: 'toolbar__icon btn-background-plugins',
caption: this.textBackgroundPlugins,
@ -329,7 +330,8 @@ define([
lock: model.get('isDisplayedInViewer') ? [_set.viewMode, _set.previewReviewMode, _set.viewFormMode, _set.selRangeEdit, _set.editFormula] : [_set.viewMode, _set.previewReviewMode, _set.viewFormMode, _set.docLockView, _set.docLockForms, _set.docLockComments, _set.selRangeEdit, _set.editFormula ],
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'small'
dataHintOffset: 'small',
customAttributes: {'data-plugin-guid': guid}
});
if ( btn.split ) {

View File

@ -84,8 +84,8 @@ define([
'<div class= <% if (typeof format !== "undefined") {%> "img-format-<%=format %>"<% } else {%> "svg-file-recent"<%} %>></div>',
'</div>',
'</div>',
'<div class="file-name"><% if (typeof title !== "undefined") {%><%= Common.Utils.String.htmlEncode(title || "") %><% } %></div>',
'<div class="file-info"><% if (typeof folder !== "undefined") {%><%= Common.Utils.String.htmlEncode(folder || "") %><% } %></div>',
'<div class="file-name"><% if (typeof title !== "undefined") {%><%= title || "" %><% } %></div>',
'<div class="file-info"><% if (typeof folder !== "undefined") {%><%= folder || "" %><% } %></div>',
'</div>'
].join(''))
});

View File

@ -664,7 +664,15 @@ define([
}
me.btnSharing && me.btnSharing.updateHint(me.tipSharing);
me.btnHistory && me.btnHistory.updateHint(me.tipHistory);
me.btnChat && me.btnChat.updateHint(me.txtChat + Common.Utils.String.platformKey('Alt+Q', ' (' + (Common.Utils.isMac ? Common.Utils.String.textCtrl + '+' : '') + '{0})'));
if(me.btnChat) {
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
app.getController('Common.Controllers.Shortcuts').updateShortcutHints({
OpenChatPanel: {
btn: me.btnChat,
label: me.txtChat
}
});
}
me.btnMailRecepients && me.btnMailRecepients.updateHint(me.tipMailRecepients);
if (me.btnCoAuthMode) {
me.btnCoAuthMode.setMenu(

View File

@ -768,6 +768,7 @@ define([
if (commentsView && arrowView && editorView && editorView.get(0)) {
editorBounds = Common.Utils.getBoundingClientRect(editorView.get(0));
if (editorBounds) {
editorBounds.height = Math.min(editorBounds.height, Math.max(300, editorBounds.height * 0.75));
sdkBoundsHeight = editorBounds.height - this.sdkBounds.padding * 2;
this.$window.css({maxHeight: sdkBoundsHeight + 'px'});
@ -910,6 +911,7 @@ define([
if (editorView && editorView.get(0)) {
editorBounds = Common.Utils.getBoundingClientRect(editorView.get(0));
if (editorBounds) {
editorBounds.height = Math.min(editorBounds.height, Math.max(300, editorBounds.height * 0.75));
sdkBoundsHeight = editorBounds.height - this.sdkBounds.padding * 2;
sdkBoundsTopPos = sdkBoundsTop;
windowHeight = this.$window.outerHeight();

View File

@ -66,7 +66,9 @@ define([
'<div class="tools">',
'<div id="search-bar-back"></div>',
'<div id="search-bar-next"></div>',
this.options.showOpenPanel ? '<div id="search-bar-open-panel"></div>' : '',
this.options.showOpenPanel
? '<div id="search-bar-open-panel"></div><div id="search-bar-open-panel-redact"></div>'
: '',
'<div id="search-bar-close"></div>',
'</div>',
'</div>'
@ -74,10 +76,10 @@ define([
this.options.tpl = _.template(this.template)(this.options);
this.iconType = this.options.iconType;
Common.UI.Window.prototype.initialize.call(this, this.options);
Common.NotificationCenter.on('layout:changed', _.bind(this.onLayoutChanged, this));
Common.NotificationCenter.on('pdf:mode-apply', _.bind(this.onModeChanged, this));
$(window).on('resize', _.bind(this.onLayoutChanged, this));
},
@ -112,6 +114,8 @@ define([
this.btnNext.on('click', _.bind(this.onBtnNextClick, this, 'next'));
if (this.options.showOpenPanel) {
var me = this;
this.btnOpenPanel = new Common.UI.Button({
parentEl: $('#search-bar-open-panel'),
cls: 'btn-toolbar',
@ -119,6 +123,30 @@ define([
hint: this.tipOpenAdvancedSettings
});
this.btnOpenPanel.on('click', _.bind(this.onOpenPanel, this));
this.btnOpenPanelRedact = new Common.UI.Button({
parentEl: $('#search-bar-open-panel-redact'),
cls: 'btn-toolbar',
menu: true,
iconCls: 'toolbar__icon btn-more-vertical',
hint: this.tipOpenAdvancedSettings
});
this.btnOpenPanelRedact.setMenu(
new Common.UI.Menu({
items: [
{caption: me.capFind, value: 'find', hint: this.tipOpenAdvancedSettings},
{caption: me.capFindRedact, value: 'find-redact', hint: this.tipOpenAdvancedSettingsRedact},
]
}).on('item:click', function (menu, item, e) {
if (item.value === 'find') {
me.hide();
me.fireEvent('search:show', [true, me.inputSearch.val()]);
} else {
me.hide();
me.fireEvent('search:showredact', [true, me.inputSearch.val()])
}
})
);
}
this.btnClose = new Common.UI.Button({
@ -141,6 +169,8 @@ define([
this.updateResultsNumber(resultNumber, allResults);
}, this));
this.btnOpenPanelRedact && this.btnOpenPanelRedact.setVisible(this.mode === 'edit')
return this;
},
@ -189,6 +219,12 @@ define([
this.$window.css({left: left, top: top});
},
onModeChanged: function (mode) {
this.mode = mode;
this.btnOpenPanel.setVisible(this.mode !== 'edit')
this.btnOpenPanelRedact.setVisible(this.mode == 'edit')
},
onBtnNextClick: function(action) {
this.fireEvent('search:'+action, [this.inputSearch.val(), false]);
},

View File

@ -127,6 +127,16 @@ define([
});
this.btnReplaceAll.on('click', _.bind(this.onReplaceClick, this, 'replaceall'));
this.btnMark = new Common.UI.Button({
el: $('#search-adv-mark')
});
this.btnMark.on('click', _.bind(this.onMarkClick, this, 'mark'));
this.btnMarkAll = new Common.UI.Button({
el: $('#search-adv-mark-all')
});
this.btnMarkAll.on('click', _.bind(this.onMarkClick, this, 'markall'));
this.$reaultsNumber = $('#search-adv-results-number');
this.updateResultsNumber('no-results');
@ -173,6 +183,19 @@ define([
});
this.buttonClose.on('click', _.bind(this.onClickClosePanel, this));
this.buttonRedactSearch = new Common.UI.Button({
parentEl: $('#search-btn-redact-open', this.$el),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-find-redacted',
hint: this.textFindRedact,
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'medium'
});
this.buttonRedactSearch.on('click', _.bind(function() {
this.fireEvent('search:showredact');
}, this));
this.$resultsContainer = $('#search-results');
this.$resultsContainer.hide();
@ -184,6 +207,8 @@ define([
});
Common.NotificationCenter.on('search:updateresults', _.bind(this.disableNavButtons, this));
Common.NotificationCenter.on('pdf:mode-apply', _.bind(this.onModeChanged, this));
if (window.SSE) {
this.cmbWithin = new Common.UI.ComboBox({
el: $('#search-adv-cmb-within'),
@ -332,8 +357,10 @@ define([
setSearchMode: function (mode) {
if (this.mode !== mode) {
this.$el.find('.edit-setting')[mode !== 'no-replace' ? 'show' : 'hide']();
this.$el.find('#search-adv-title').text(mode !== 'no-replace' ? this.textFindAndReplace : this.textFind);
this.$el.find('.edit-setting')[mode !== 'no-replace' && mode !== 'redact' ? 'show' : 'hide']();
this.$el.find('.redact-setting')[mode === 'redact' && this.options.mode.isPDFEdit ? 'show' : 'hide']();
this.$el.find('.redact-no-replace-btn')[mode === 'no-replace' && this.options.mode.isPDFEdit === true ? 'show' : 'hide']();
this.$el.find('#search-adv-title').text(mode === 'no-replace' ? this.textFind : mode === 'redact' ? this.textFindAndRedact : this.textFindAndReplace);
this.mode = mode;
}
},
@ -390,6 +417,7 @@ define([
}
this.updateResultsContainerHeight();
!window.SSE && this.disableReplaceButtons(!count);
!window.SSE && this.disableRedactButtons(!count);
},
showToManyResults: function () {
@ -419,6 +447,17 @@ define([
this.fireEvent('search:'+action, [this.inputText.getValue(), this.inputReplace.getValue()]);
},
onMarkClick: function (action) {
this.fireEvent('search:'+action, [this.inputText.getValue()]);
},
onModeChanged: function (isEdit) {
if (isEdit !== 'edit') {
Common.NotificationCenter.trigger('search:resetmode');
}
this.$el.find('.redact-no-replace-btn')[this.mode === 'no-replace' && isEdit === 'edit' ? 'show' : 'hide']();
},
getSettings: function() {
return {
textsearch: this.inputText.getValue(),
@ -449,6 +488,16 @@ define([
this.btnNext.setDisabled(disable);
},
disableRedactButtons: function (disable) {
if (typeof disable === 'object') {
this.btnMark.setDisabled(disable.current)
this.btnMarkAll.setDisabled(disable.all)
} else {
this.btnMark.setDisabled(disable)
this.btnMarkAll.setDisabled(disable)
}
},
disableReplaceButtons: function (disable) {
this.btnReplace.setDisabled(disable);
this.btnReplaceAll.setDisabled(disable);

View File

@ -0,0 +1,258 @@
/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* ShortcutsDialog.js
*
* Created on 23/06/25
*
*/
define([
'common/main/lib/view/AdvancedSettingsWindow'
], function () { 'use strict';
Common.Views.ShortcutsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
contentWidth: 550,
separator: false
},
initialize : function(options) {
_.extend(this.options, {
id: 'shortcuts-gialog',
title: this.txtTitle,
contentStyle: 'padding: 16px 16px 0;',
contentTemplate: _.template([
'<div id="header-row">',
'<input id="search-input" type="text" spellcheck="false" class="form-control" placeholder="<%= scope.txtSearch %>...">',
'<label id="reset-all-btn" class="link"><%= scope.txtRestoreAll %></label>',
'</div>',
'<div id="actions-list"></div>',
'<div id="action-description">',
'<b><%= scope.txtDescription %>: </b>',
'<span id="action-description-text"></span>',
'</div>'
].join(''))({scope: this}),
buttons: []
}, options);
this.handler = options.handler;
this.api = options.api;
this._state = {
searchValue: ''
};
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
this._shortcutsController = app.getController('Common.Controllers.Shortcuts');
Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options);
},
render: function() {
Common.Views.AdvancedSettingsWindow.prototype.render.call(this);
this.actionsList = new Common.UI.ListView({
el: $('#actions-list', this.$window),
emptyText: this.txtEmpty,
store: new Common.UI.DataViewStore(),
itemTemplate: _.template([
'<div id="<%= id %>" class="list-item">',
'<div class="action-name"><%= action.name %></div>',
'<div class="action-keys">',
'<% _.each(_.filter(shortcuts, function(shortcut) { return !shortcut.ascShortcut.asc_IsHidden() }), function(shortcut, shortcutIndex) { %>',
'<div class="action-keys-item">',
'<% _.each(shortcut.keys, function(key, keyIndex) { %>',
'<% if (keyIndex != 0) { %>',
'<div class="action-keys-item-plus">+</div>',
'<% } %>',
'<div class="action-keys-item-key"><%= key %></div>',
'<% }); %>',
'<div class="action-keys-item-comma">,</div>',
'</div>',
'<% }); %>',
'</div>',
'<% if (action.isLocked) { %>',
'<i class="icon toolbar__icon btn-lock icon-lock">&nbsp;</i>',
'<% } else { %>',
'<button type="button" class="action-edit btn-toolbar">',
'<i class="icon toolbar__icon btn-edit">&nbsp;</i>',
'</button>',
'<% } %>',
'</div>'
].join('')),
tabindex: 1
});
this.actionsList.on('item:select', _.bind(this.onSelectActionItem, this));
this.actionsList.on('item:click', _.bind(this.onClickActionItem, this));
this.actionsList.on('item:dblclick', _.bind(this.onEditActionItem, this));
this.actionsList.on('entervalue', _.bind(function(list, record) {
this.onEditActionItem(list, null, record);
}, this));
this.searchInput = this.$window.find('#search-input');
this.searchInput.on('input', _.bind(this.onInputSearch, this));
this.resetAllBtn = new Common.UI.Button({
el: this.$window.find('#reset-all-btn')
});
this.resetAllBtn.on('click', _.bind(this.onResetAll, this));
Common.NotificationCenter.on('shortcuts:update', _.bind(function() {
this._setDefaults();
this.shortcutsEditDialog && this.shortcutsEditDialog.renderShortcutsWarning();
}, this));
this._setDefaults();
},
getFocusedComponents: function() {
return [this.searchInput, this.resetAllBtn, this.actionsList];
},
getDefaultFocusableComponent: function () {
return this.actionsList;
},
_setDefaults: function() {
this._updateActionsList();
},
_getActionsMap: function() {
return this._shortcutsController.getActionsMap();
},
_updateActionsList: function() {
const selectedActionIndex = this.actionsList.store.findIndex(function(item) {
return item.get('selected');
});
const scrollPos = this.actionsList.scroller.getScrollTop();
if(this._state.searchValue) {
this._filterActionsList();
} else {
this.actionsList.store.reset(_.values(this._getActionsMap()));
}
this.actionsList.scroller.scrollTop(scrollPos);
if(selectedActionIndex != -1) {
this.actionsList.selectByIndex(selectedActionIndex);
}
},
_filterActionsList: function() {
let filteredData;
const me = this;
const actionsData = _.values(this._getActionsMap());
if(me._state.searchValue) {
filteredData = actionsData.filter(function(item) {
return (item.action.name || '').toLowerCase().includes(me._state.searchValue);
});
} else {
filteredData = actionsData;
}
this.actionsList.store.reset(filteredData);
},
onSelectActionItem: function(list, item, record, event) {
const text = record ? record.get('action').description : '';
this.$window.find('#action-description-text').text(text);
},
onClickActionItem: function(list, item, record, event) {
if($(event.target).hasClass('action-edit') || $(event.target).parent().hasClass('action-edit')) {
this.onEditActionItem(list, item, record);
}
},
onEditActionItem: function(list, item, record) {
if(record.get('action').isLocked) return;
const me = this;
this.shortcutsEditDialog = new Common.Views.ShortcutsEditDialog({
action: record.get('action')
});
this.shortcutsEditDialog.show();
this.shortcutsEditDialog.on('close', function() {
me.shortcutsEditDialog = null;
me.actionsList.focus();
});
},
onInputSearch: function(event) {
this._state.searchValue = $(event.target).val().toLowerCase().trim();
this._filterActionsList();
this.onSelectActionItem(null, null, null);
},
onResetAll: function() {
const me = this;
Common.UI.warning({
title: this.txtRestoreToDefault,
msg: this.txtRestoreDescription + '<br/>' + this.txtRestoreContinue,
buttons: ['ok', 'cancel'],
width: 400,
callback: function(btn) {
if(btn == 'ok') {
me._shortcutsController.resetAllShortcuts();
}
}
});
},
onDlgBtnClick: function(event) {
let state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event;
if (state == 'ok') {
this.handler && this.handler.call(this, state, (state == 'ok') ? null : undefined);
}
this.close();
},
onPrimary: function() {
this.onDlgBtnClick('ok');
return false;
},
txtTitle: 'Keyboard Shortcuts',
txtDescription: 'Description',
txtEmpty: 'No matches found. Adjust your search.',
txtSearch: 'Search',
txtRestoreAll: 'Restore All to Defaults',
txtRestoreToDefault: 'Restore to default',
txtRestoreDescription: 'All shortcuts settings will be restored to deafult.',
txtRestoreContinue: 'Do you want to continue?'
}, Common.Views.ShortcutsDialog || {}))
});

View File

@ -0,0 +1,484 @@
/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
/**
* ShortcutsEditDialog.js
*
* Created on 23/06/25
*
*/
define([
'common/main/lib/view/AdvancedSettingsWindow',
], function () { 'use strict';
Common.Views.ShortcutsEditDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
height: 'auto',
contentWidth: 268,
contentHeight: 'auto',
separator: false
},
initialize : function(options) {
_.extend(this.options, {
id: 'shortcut-edit-gialog',
title: this.txtTitle,
contentStyle: 'padding: 16px 16px 0;',
contentTemplate: _.template([
'<div class="settings-panel active">',
'<label id="action-label">',
'<span><%= scope.txtAction %>: </span>',
'<span id="action-label-name"><%= options.action.name %></span>',
'</label>',
'<div id="shortcuts-list"></div>',
'<div id="buttons-row">',
'<label id="new-shortcut-btn" class="link"><%= scope.txtNewShortcut %></label>',
'<label id="reset-btn" class="link"><%= scope.txtRestoreToDefault %></label>',
'</div>',
'</div>'
].join(''))({scope: this, options: options}),
}, options);
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
this._shortcutsController = app.getController('Common.Controllers.Shortcuts');
this._prevKeysForActiveInput = [];
Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options);
},
render: function() {
Common.Views.AdvancedSettingsWindow.prototype.render.call(this);
this.newShortcutsBtn = this.$window.find('#new-shortcut-btn');
this.newShortcutsBtn.on('click', _.bind(this.onAddShortcut, this));
this.resetBtn = this.$window.find('#reset-btn');
this.resetBtn.on('click', _.bind(this.onReset, this));
this.scrollerOptions = {
el: this.$window.find('#shortcuts-list'),
wheelSpeed: 8,
alwaysVisibleY: true
};
this.scroller = new Common.UI.Scroller(this.scrollerOptions);
this._setDefaults();
},
getFocusedComponents: function() {
const dynamicComponents = [];
this.shortcutsCollection.each(function(record) {
dynamicComponents.push(record.get('keysInput'), record.get('removeBtn'));
});
return dynamicComponents.concat(this.getFooterButtons());
},
getDefaultFocusableComponent: function() {
return this.shortcutsCollection.at(0).get('keysInput');
},
_setDefaults: function() {
this.shortcutsCollection = new Backbone.Collection([]);
this.shortcutsCollection.on('reset', function(newCollection, details) {
this._renderShortcutsList(details.previousModels);
}, this);
this.shortcutsCollection.on('add', function(record, newCollection) {
const prevCollection = newCollection.filter(function(item) { return item != record });
this._renderShortcutsList(prevCollection);
}, this);
this.shortcutsCollection.on('remove', function(record, newCollection) {
const prevCollection = newCollection.toArray();
prevCollection.push(record);
this._renderShortcutsList(prevCollection);
}, this);
this.shortcutsCollection.on('add remove reset change:keys', this.renderShortcutsWarning, this);
//Get shortcuts for the current action and copy the instances so as not to modify the original instances
let shortcuts = _.filter(this._getOriginalShortcuts(), function(shortcut) {
return !shortcut.ascShortcut.asc_IsHidden();
});
shortcuts = shortcuts.map(function(shortcut) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(shortcut.ascShortcut.asc_ToJson());
return {
keys: shortcut.keys,
ascShortcut: copyAscShortcut
};
});
this.shortcutsCollection.reset(shortcuts);
if(this.shortcutsCollection.length == 0) {
this.onAddShortcut();
}
},
_getActionsMap: function() {
return this._shortcutsController.getActionsMap();
},
_getOriginalShortcuts: function() {
return this._getActionsMap()[this.options.action.type].shortcuts;
},
// Is this shortcut default for this action?
_isDefaultShortcut: function(ascShortcut) {
const shortcutIndex = ascShortcut.asc_GetShortcutIndex();
return _.some(Asc.c_oAscDefaultShortcuts[ascShortcut.asc_GetType()], function(someAscShortcut) {
return shortcutIndex == someAscShortcut.asc_GetShortcutIndex();
});
},
/**
* Finds all actions that already have the given shortcut assigned.
*
* If `extraAction` is provided and its `extraAction.actionType` matches the current item,
* the method will check `extraAction.shortcuts` instead of the original shortcuts.
*
* @param {CAscShortcut} ascShortcut The shortcut to search for.
*
* @param {Object} [extraAction] Optional object that can replace the shortcuts of a matching action.
* @param {number} extraAction.actionType The type of the action to match.
* @param {CAscShortcut[]} extraAction.shortcuts Custom list of shortcuts to check for this action.
* @returns {Object[]} Array of action objects that already use the given shortcut.
*/
_findAssignedActions: function(ascShortcut, extraAction) {
const shortcutIndex = ascShortcut.asc_GetShortcutIndex();
const foundItems = [];
const values = _.values(this._getActionsMap());
for (let i = 0; i < values.length; i++) {
const item = {
action: values[i].action,
shortcuts: values[i].shortcuts
};
if (extraAction && extraAction.actionType === item.action.type ) {
item.shortcuts = extraAction.shortcuts;
}
const existsVisible = _.some(item.shortcuts, function(shortcut) {
return shortcut.ascShortcut.asc_GetShortcutIndex() == shortcutIndex &&
!shortcut.ascShortcut.asc_IsHidden();
});
if (existsVisible) {
foundItems.push(item);
}
}
return _.map(foundItems, function(item) { return item.action; });
},
/**
* Returns the default shortcuts for the current action type.
*
* @returns {Array<Object>} Array of shortcut objects.
* @returns {string[]} return[].keys - Array of key strings representing the shortcut (["Ctrl", "S"]).
* @returns {ascShortcut} return[].ascShortcut - Instance of CAscShortcut.
*/
_getDefaultShortcuts: function() {
const me = this;
const ascShortcuts = Asc.c_oAscDefaultShortcuts[this.options.action.type];
return ascShortcuts.map(function(ascShortcut) {
const copyAscShortcut = new Asc.CAscShortcut();
copyAscShortcut.asc_FromJson(ascShortcut.asc_ToJson());
copyAscShortcut.asc_SetIsHidden(false);
return {
keys: me._shortcutsController._getAscShortcutKeys(copyAscShortcut),
ascShortcut: copyAscShortcut
}
});
},
_renderShortcutsList: function(prevCollection) {
const me = this;
this.$window.find('#shortcuts-list').empty();
this.shortcutsCollection.each(function(item, index) {
const ascShortcut = item.get('ascShortcut');
const isLocked = ascShortcut.asc_IsLocked();
const keysStr = item.get('keys').join(' + ');
const $item = $(
'<div class="item ' + (index == 0 ? 'first' : '') + '">' +
'<div class="keys-input"></div>' +
(isLocked
? '<button type="button" class="btn-toolbar">' +
'<i class="icon toolbar__icon btn-menu-about">&nbsp;</i>' +
'</button>'
: '<button type="button" class="btn-toolbar remove-btn">' +
'<i class="icon toolbar__icon btn-cc-remove">&nbsp;</i>' +
'</button>'
) +
'</div>'
);
// if(me.shortcutsCollection.length == 1) {
// $item.find('.remove-btn').attr('disabled', true).addClass('disabled');
// }
me.$window.find('#shortcuts-list').append($item);
const keysInput = new Common.UI.InputField({
el : $item.find('.keys-input'),
value : keysStr,
editable : false,
placeHolder : me.txtInputPlaceholder,
disabled : isLocked
});
const removeButton = new Common.UI.Button({
el: $item.find('.remove-btn'),
});
item.set({ keysInput: keysInput, removeBtn: removeButton });
const $keysInput = $item.find('.keys-input input');
$keysInput.on('keydown', function(e) {
const alowedSingleKeys = [
Common.UI.Keys.F1, Common.UI.Keys.F2, Common.UI.Keys.F3, Common.UI.Keys.F4, Common.UI.Keys.F5,
Common.UI.Keys.F6, Common.UI.Keys.F7, Common.UI.Keys.F8, Common.UI.Keys.F9, Common.UI.Keys.F10,
Common.UI.Keys.F11, Common.UI.Keys.F12,Common.UI.Keys.INSERT, Common.UI.Keys.HOME,
Common.UI.Keys.PAGEUP, Common.UI.Keys.DELETE, Common.UI.Keys.END, Common.UI.Keys.PAGEDOWN,
Common.UI.Keys.LEFT, Common.UI.Keys.UP, Common.UI.Keys.RIGHT, Common.UI.Keys.DOWN
];
const forbiddensKeys = [Common.UI.Keys.ESC, Common.UI.Keys.TAB];
if(!Common.Utils.isMac) {
forbiddensKeys.push(91); //Meta (Super, Win)
}
if (forbiddensKeys.includes(e.keyCode)) {
// Restore previous input state when press Tab
if(e.keyCode == Common.UI.Keys.TAB && me._prevKeysForActiveInput.length) {
item.set('keys', me._prevKeysForActiveInput);
$item.find('input').val(me._prevKeysForActiveInput.join(' + '));
}
return;
}
e.stopPropagation();
e.preventDefault();
if(!alowedSingleKeys.includes(e.keyCode) && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
return;
}
const keys = [];
if (e.ctrlKey) keys.push('Ctrl');
if (e.shiftKey) keys.push('Shift');
if (e.altKey) keys.push('Alt');
if (e.metaKey && Common.Utils.isMac) keys.push('⌘');
if (![Common.UI.Keys.CTRL, Common.UI.Keys.SHIFT, Common.UI.Keys.ALT, 91].includes(e.keyCode)) {
const app = (window.DE || window.PE || window.SSE || window.PDFE || window.VE);
keys.push(app.getController('Common.Controllers.Shortcuts').keyCodeToKeyName(e.keyCode));
ascShortcut.asc_SetKeyCode(e.keyCode);
} else {
ascShortcut.asc_SetKeyCode(null);
}
ascShortcut.asc_SetIsCtrl(!!e.ctrlKey);
ascShortcut.asc_SetIsShift(!!e.shiftKey);
ascShortcut.asc_SetIsAlt(!!e.altKey);
ascShortcut.asc_SetIsCommand(!!e.metaKey && Common.Utils.isMac);
item.set('keys', keys);
$item.find('input').val(keys.join(' + '));
});
const removeKeysIfOnlyModifiers = function(removedKeys) {
const modifierKeys = ['Ctrl', 'Shift', 'Alt', '⌘'];
const keys = item.get('keys');
const hasExtra = _.some(keys, function(k) {
return !_.contains(modifierKeys, k);
});
if (!hasExtra && removedKeys && removedKeys.length) {
const filteredKeys = keys.filter(function(k) {
return !_.contains(removedKeys, k);
});
item.set('keys', filteredKeys);
$item.find('input').val(filteredKeys.join(' + '));
}
};
$keysInput.on('keyup', function(e) {
const modifierKeyMap = {
[Common.UI.Keys.CTRL]: 'Ctrl',
[Common.UI.Keys.ALT]: 'Alt',
[Common.UI.Keys.SHIFT]: 'Shift',
91: '⌘'
};
const modifierKey = modifierKeyMap[e.keyCode];
removeKeysIfOnlyModifiers(modifierKey ? [modifierKey] : []);
if(!modifierKey) {
me._prevKeysForActiveInput = item.get('keys');
}
});
$keysInput.on('focusin', function() {
me._prevKeysForActiveInput = item.get('keys');
});
$keysInput.on('focusout', function() {
me._prevKeysForActiveInput = [];
removeKeysIfOnlyModifiers(item.get('keys'));
});
$item.find('.remove-btn').on('click', function() {
me.shortcutsCollection.remove(item);
if(me.shortcutsCollection.length == 0) {
me.onAddShortcut();
}
me.$window.find('#shortcuts-list .item input').last().focus();
});
});
this.fixHeight(true);
this.scroller.update(this.scrollerOptions);
//Update focus controll
Common.UI.FocusManager.remove(this, 0, prevCollection.length * 2 + 2);
Common.UI.FocusManager.add(this, this.getFocusedComponents());
},
renderShortcutsWarning: function() {
const me = this;
let isButtonDisabled = false;
this.shortcutsCollection.each(function(item) {
const ascShortcut = item.get('ascShortcut');
const assignedActionNames = [];
const assignedActions = me._findAssignedActions(ascShortcut, {
actionType: me.options.action.type,
shortcuts: me.shortcutsCollection.toJSON().slice(0, _.indexOf(me.shortcutsCollection.models, item))
});
const isDefaultShortcut = me._isDefaultShortcut(ascShortcut);
const isDisabled = !isDefaultShortcut &&
_.some(assignedActions, function(action) { return action.isLocked; });
isButtonDisabled = isButtonDisabled || isDisabled;
for (let i = 0; i < assignedActions.length; i++) {
const action = assignedActions[i];
if(action.isLocked == isDisabled) {
assignedActionNames.push('“' + action.name + '”');
}
}
let txtKey = null;
if (assignedActionNames.length === 1) {
txtKey = isDisabled ? 'txtInputWarnOneLocked' : 'txtInputWarnOne';
} else if (assignedActionNames.length > 1) {
txtKey = isDisabled ? 'txtInputWarnManyLocked' : 'txtInputWarnMany';
}
item.get('keysInput').showWarning(
txtKey
? [me[txtKey].replace('%1', assignedActionNames.join(', '))]
: null
);
});
this.getFooterButtons()[0].setDisabled(isButtonDisabled);
},
onAddShortcut: function() {
const lastShortcutRecord = this.shortcutsCollection.at(this.shortcutsCollection.length - 1);
if(!lastShortcutRecord || lastShortcutRecord.get('keys').length) {
this.shortcutsCollection.add({
keys: [],
ascShortcut: new Asc.CAscShortcut(this.options.action.type)
});
}
this.$window.find('#shortcuts-list .item input').last().focus();
},
onReset: function() {
const me = this;
Common.UI.warning({
title: this.txtRestoreToDefault,
msg: this.txtRestoreDescription.replace('%1', me.options.action.name) + '<br/>' +
this.txtRestoreContinue,
buttons: ['ok', 'cancel'],
width: 400,
callback: function(btn) {
if(btn == 'ok') {
const shortcuts = me._getDefaultShortcuts();
me.shortcutsCollection.reset(shortcuts);
}
}
});
},
onDlgBtnClick: function(event) {
let state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event;
if (state == 'ok') {
const seen = {};
const filteredShortcuts = [];
(this.shortcutsCollection.toJSON() || []).forEach(function(item) {
if (!item.keys.length) return;
let idx = item.ascShortcut.asc_GetShortcutIndex();
if (seen[idx]) return;
seen[idx] = true;
filteredShortcuts.push({
keys: item.keys,
ascShortcut: item.ascShortcut
});
});
this._shortcutsController.updateShortcutsForAction(this.options.action.type, filteredShortcuts);
}
this.close();
},
onPrimary: function() {
this.onDlgBtnClick('ok');
return false;
},
txtTitle: 'Edit shortcut',
txtAction: 'Action',
txtInputPlaceholder: 'Type desired shortcut',
txtInputWarnOne: 'The shortcut used by action %1',
txtInputWarnOneLocked: 'The shortcut used by action %1 and cant be changed',
txtInputWarnMany: 'The shortcut used by actions %1',
txtInputWarnManyLocked: 'The shortcut used by actions %1 and cant be changed',
txtNewShortcut: 'New shortcut',
txtRestoreToDefault: 'Restore to default',
txtTypeDesiredShortcut: 'Type desired shortcut',
txtRestoreDescription: 'All shortcuts for action “%1” will be restored to deafult.',
txtRestoreContinue: 'Do you want to continue?'
}, Common.Views.ShortcutsEditDialog || {}))
});

View File

@ -344,14 +344,19 @@ define([
var minScrollbarLength = 20;
var wheelSpeed = 20;
var _4letterLangs = ['pt-pt', 'zh-tw', 'sr-cyrl'];
var loadTranslation = function(lang, callback) {
lang = lang.split(/[\-_]/)[0].toLocaleLowerCase();
lang = lang.toLowerCase().split(/[\-_]/);
lang = lang[0] + (lang.length>1 ? '-' + lang[1] : '');
var idx4Letters = _4letterLangs.indexOf(lang); // try to load 4 letters language
lang = (idx4Letters<0) ? lang.split(/[\-]/)[0] : _4letterLangs[idx4Letters];
Common.Utils.loadConfig('resources/symboltable/' + lang + '.json', function (langJson) {
for (var i=1; i<274; i++) {
var val = oRangeNames[i];
oRangeNames[i] = langJson[val] || val;
if ( langJson !== 'error' ) {
for (var i=1; i<274; i++) {
var val = oRangeNames[i];
oRangeNames[i] = langJson[val] || val;
}
}
callback && callback();
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

View File

Before

Width:  |  Height:  |  Size: 674 B

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

View File

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none" viewBox="0 0 28 28">
<path fill="#000" d="M20.69 14a7 7 0 0 0-.038-.84l-.085-.585 2.256-1.716-1.625-2.731-2.175.842-.516.2-.443-.331a7 7 0 0 0-1.513-.862l-.526-.217L15.62 5h-3.24l-.405 2.771-.541.212c-.377.148-.88.427-1.522.874l-.437.305-2.672-1.034-1.625 2.731 2.257 1.716-.085.584a7 7 0 0 0-.04.841c0 .427.017.696.038.84l.085.585-2.257 1.715 1.625 2.731 2.176-.84.515-.2.444.33q.54.404 1.12.687l.392.175.527.217.403 2.76h3.242l.406-2.771.54-.212c.378-.148.881-.427 1.522-.874l.438-.305.496.192 2.175.841 1.625-2.731-2.256-1.715.085-.584A7 7 0 0 0 20.69 14m.987.575a5 5 0 0 1-.035.411l2.162 1.643q.336.234.096.657l-2.067 3.475q-.168.287-.52.216l-.104-.029-2.548-.985q-1.008.704-1.73.985l-.384 2.63q-.096.421-.48.422h-4.133l-.092-.007q-.261-.04-.36-.316l-.029-.1-.384-2.629a8 8 0 0 1-1.73-.985l-2.548.985q-.432.141-.624-.187l-2.066-3.475q-.24-.422.095-.657l2.163-1.643A7 7 0 0 1 6.31 14q0-.657.048-.986L4.196 11.37q-.294-.205-.147-.555l.052-.102 2.066-3.475q.192-.328.624-.187l2.548.985q1.01-.704 1.73-.985l.384-2.63q.084-.369.389-.415L11.934 4h4.133q.384 0 .48.423l.385 2.629q.912.375 1.73.985l2.547-.985q.432-.141.624.187l2.067 3.475q.24.422-.096.657l-2.162 1.643q.048.329.048.986z"/>
<path fill="#000" d="M16 14a2 2 0 1 0-4 0 2 2 0 0 0 4 0m1 0a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9 13H8V7h1zm3 0h-1V7h1z" fill="#000"/>
<path d="M17 17H3V3h14zM4 16h12V4H4z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 212 B

View File

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.5 10a4.5 4.5 0 1 1 0 9 4.5 4.5 0 0 1 0-9m0 1a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7" fill="#000"/>
<path d="M17 9h-1V6H4v10h5v1H3V3h14zM4 5h12V4H4z" fill="#000"/>
<path d="M9 12H6v-1h3zm3-3H6V8h6zm2.5 3.25a2.25 2.25 0 1 1 0 4.5 2.25 2.25 0 0 1 0-4.5" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 390 B

View File

@ -0,0 +1,4 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 13H7V7h6z" fill="#000"/>
<path d="M17 17H3V3h14zM4 16h12V4H4z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 201 B

View File

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

View File

Before

Width:  |  Height:  |  Size: 789 B

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

View File

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Some files were not shown because too many files have changed in this diff Show More