/*
* (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([
'
',
'',
'',
'
',
'',
'',
'
',
'
'
].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) {
if(record.get('removeBtn')) {
dynamicComponents.push(record.get('keysInput'), record.get('removeBtn'));
}
});
return dynamicComponents.concat(this.getFooterButtons());
},
getDefaultFocusableComponent: function() {
const firstFocusableItem = this.shortcutsCollection.find(function(item) {
return item.get('removeBtn');
});
if(firstFocusableItem) {
return firstFocusableItem.get('keysInput');
} else {
return this.getFooterButtons()[0];
}
},
_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 currently use the specified shortcut and returns both the action and the shortcut.
*
* 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 objects containing `action` and the matching `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 foundShortcut = _.find(item.shortcuts, function(shortcut) {
return shortcut.ascShortcut.asc_GetShortcutIndex() == shortcutIndex &&
!shortcut.ascShortcut.asc_IsHidden();
});
if (foundShortcut) {
foundItems.push({
action: item.action,
shortcut: foundShortcut
});
}
}
return foundItems;
},
/**
* Returns the default shortcuts for the current action type.
*
* @returns {Array