Merge pull request #1762 from ONLYOFFICE/develop

Develop
This commit is contained in:
Julia Radzhabova 2022-05-26 15:19:58 +03:00 committed by GitHub
commit 4b56a2a2a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 3512 additions and 489 deletions

View file

@ -0,0 +1,77 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
!window.common && (window.common = {});
!common.view && (common.view = {});
common.view.SearchBar = new(function() {
var tpl = '<div class="asc-window search-window" style="display: none;">' +
'<div class="body">{body}</div>' +
'</div>';
var tplBody = '<input type="text" id="search-bar-text" placeholder="{textFind}" autocomplete="off">' +
'<div class="tools">' +
'<button id="search-bar-back" class="svg-icon search-arrow-up"></button>' +
'<button id="search-bar-next" class="svg-icon search-arrow-down"></button>' +
'<button id="search-bar-close" class="svg-icon search-close"></button>' +
'</div>';
return {
create: function(parent) {
!parent && (parent = 'body');
var _$dlg = $(tpl
.replace(/\{body}/, tplBody)
.replace(/\{textFind}/, this.textFind))
.appendTo(parent)
.attr('id', 'dlg-search');
return _$dlg;
},
disableNavButtons: function (resultNumber, allResults) {
var disable = $('#search-bar-text').val() === '';
$('#search-bar-back').attr({disabled: disable || !allResults || resultNumber === 0});
$('#search-bar-next').attr({disabled: disable || resultNumber + 1 === allResults});
},
textFind: 'Find'
};
})();

View file

@ -1,4 +1,4 @@
<svg width="380" height="40" viewBox="0 0 380 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="440" height="40" viewBox="0 0 440 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon-menu-sprite Embedded Viewer">
<g id="view-settings">
<path id="Vector" d="M17 26H3V27H17V26Z" fill="white"/>
@ -148,5 +148,23 @@
<g id="close_2">
<path id="Vector 73_2" d="M366 5L375 14M375 5L366 14" stroke="black" stroke-width="1.5"/>
</g>
<g id="search">
<path id="Union_27" fill-rule="evenodd" clip-rule="evenodd" d="M393 8.5C393 10.9853 390.985 13 388.5 13C386.015 13 384 10.9853 384 8.5C384 6.01472 386.015 4 388.5 4C390.985 4 393 6.01472 393 8.5ZM392.02 12.7266C391.066 13.5217 389.839 14 388.5 14C385.462 14 383 11.5376 383 8.5C383 5.46243 385.462 3 388.5 3C391.538 3 394 5.46243 394 8.5C394 9.83875 393.522 11.0658 392.727 12.0195L396.854 16.1465L396.146 16.8536L392.02 12.7266Z" fill="black"/>
</g>
<g id="search_2">
<path id="Union_28" fill-rule="evenodd" clip-rule="evenodd" d="M393 28.5C393 30.9853 390.985 33 388.5 33C386.015 33 384 30.9853 384 28.5C384 26.0147 386.015 24 388.5 24C390.985 24 393 26.0147 393 28.5ZM392.02 32.7266C391.066 33.5217 389.839 34 388.5 34C385.462 34 383 31.5376 383 28.5C383 25.4624 385.462 23 388.5 23C391.538 23 394 25.4624 394 28.5C394 29.8387 393.522 31.0658 392.727 32.0195L396.854 36.1465L396.146 36.8536L392.02 32.7266Z" fill="white"/>
</g>
<g id="arrow-up">
<path id="Union_29" fill-rule="evenodd" clip-rule="evenodd" d="M410 6.29297L410.354 6.64652L415.854 12.1465L415.146 12.8536L410 7.70718L404.854 12.8536L404.146 12.1465L409.646 6.64652L410 6.29297Z" fill="black"/>
</g>
<g id="arrow-up_2">
<path id="Union_30" fill-rule="evenodd" clip-rule="evenodd" d="M410 26.293L410.354 26.6465L415.854 32.1465L415.146 32.8536L410 27.7072L404.854 32.8536L404.146 32.1465L409.646 26.6465L410 26.293Z" fill="white"/>
</g>
<g id="arrow-down">
<path id="Union_31" fill-rule="evenodd" clip-rule="evenodd" d="M430 13.7071L430.354 13.3536L435.854 7.85359L435.146 7.14648L430 12.2929L424.854 7.14648L424.146 7.85359L429.646 13.3536L430 13.7071Z" fill="black"/>
</g>
<g id="arrow-down_2">
<path id="Union_32" fill-rule="evenodd" clip-rule="evenodd" d="M430 33.7071L430.354 33.3536L435.854 27.8536L435.146 27.1465L430 32.2929L424.854 27.1465L424.146 27.8536L429.646 33.3536L430 33.7071Z" fill="white"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -503,7 +503,7 @@
@icon-height: 20px;
.svg-icon {
background: data-uri('../../../../common/embed/resources/img/icon-menu-sprite.svg') no-repeat;
background-size: @icon-width*19 @icon-height*2;
background-size: @icon-width*22 @icon-height*2;
&.download {
background-position: -@icon-width 0;
@ -557,6 +557,18 @@
&.more-vertical {
background-position: -@icon-width*14 0;
}
&.search-close {
background-position: -@icon-width*18 0;
}
&.search {
background-position: -@icon-width*19 0;
}
&.search-arrow-up {
background-position: -@icon-width*20 0;
}
&.search-arrow-down {
background-position: -@icon-width*21 0;
}
}
.mi-icon {
@ -785,4 +797,73 @@
font-weight: normal;
}
}
}
#id-search {
button.active {
background-color: @btnActiveColor !important;
background-position: -@icon-width*19 -@icon-height;
}
}
.search-window {
width: 301px;
height: 54px;
z-index: 50;
position: fixed;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
border-radius: 5px;
border: solid 1px #CBCBCB;
.body {
width: 100%;
height: 100%;
border-radius: 5px;
background-color: #FFFFFF;
display: flex;
padding: 16px;
input {
width: 192px;
height: 22px;
border-radius: 2px;
box-shadow: none;
border: solid 1px #CFCFCF;
padding: 1px 3px;
color: #444444;
font-size: 11px;
&::placeholder {
color: #CFCFCF;
}
&:focus {
border-color: #848484;
outline: 0;
}
}
.tools {
display: flex;
button {
border: none;
margin-left: 7px;
cursor: pointer;
width: 20px;
height: 20px;
opacity: 0.8;
&:hover:not(:disabled) {
background-color: #d8dadc;
}
&:disabled {
opacity: 0.4;
cursor: default;
}
}
}
}
}

View file

@ -444,6 +444,9 @@ define([
'class="form-control <%= cls %>" ',
'placeholder="<%= placeHolder %>" ',
'value="<%= value %>"',
'data-hint="<%= dataHint %>"',
'data-hint-offset="<%= dataHintOffset %>"',
'data-hint-direction="<%= dataHintDirection %>"',
'>',
'<span class="input-error"></span>',
'<div class="select-button">' +
@ -464,7 +467,10 @@ define([
name : this.name,
placeHolder : this.placeHolder,
spellcheck : this.spellcheck,
scope : me
scope : me,
dataHint : this.options.dataHint,
dataHintOffset: this.options.dataHintOffset,
dataHintDirection: this.options.dataHintDirection
}));
if (parentEl) {

View file

@ -0,0 +1,63 @@
<div id="search-box" class="layout-ct vbox search-panel">
<div id="search-header">
<label id="search-adv-title"></label>
<div id="search-btn-close"></div>
</div>
<div id="search-adv-settings">
<table cols="1">
<tbody>
<tr>
<td class="padding-small"><div id="search-adv-text"></div></td>
</tr>
<tr class="edit-setting">
<td class="padding-large"><div id="search-adv-replace-text"></div></td>
</tr>
<tr>
<td class="padding-large">
<label id="search-adv-results-number" style="display: inline-block;">
<%= scope.textSearchResults %>
</label>
<div class="search-nav-btns" style="display: inline-block; float: right;">
<div id="search-adv-back" style="display: inline-block; margin-right: 4px;"></div>
<div id="search-adv-next" style="display: inline-block;"></div>
</div>
</td>
</tr>
<tr class="edit-setting">
<td class="padding-large">
<button type="button" class="btn btn-text-default" id="search-adv-replace" style="display: inline-block; min-width: 62px;" data-hint="1" data-hint-direction="bottom" data-hint-offset="big"><%= scope.textReplace %></button>
<button type="button" class="btn btn-text-default" id="search-adv-replace-all" style="display: inline-block; min-width: 78px;" data-hint="1" data-hint-direction="bottom" data-hint-offset="big"><%= scope.textReplaceAll %></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">
<div class="search-options-caret img-commonctrl"></div>
<div class="search-options-txt"><%= scope.textSearchOptions %></div>
</div>
<div id="search-options">
<label class="input-label"><%= scope.textWithin %></label>
<div id="search-adv-cmb-within"></div>
<div id="search-adv-select-range"></div>
<label class="input-label"><%= scope.textSearch %></label>
<div id="search-adv-cmb-search"></div>
<label class="input-label"><%= scope.textLookIn %></label>
<div id="search-adv-cmb-look-in"></div>
</div>
</td>
</tr>
<tr>
<td class="padding-small"><div id="search-adv-case-sensitive"></div></td>
</tr>
<!---<tr>
<td class="padding-small"><div id="search-adv-use-regexp"></div></td>
</tr>-->
<tr>
<td class="padding-large"><div id="search-adv-match-word"></div></td>
</tr>
</tbody>
</table>
</div>
<div id="search-results" class="ps-container oo">
</div>
</div>

View file

@ -105,6 +105,7 @@ define([
'<div class="btn-slot" id="slot-btn-mode"></div>' +
'<div class="btn-slot" id="slot-btn-back"></div>' +
'<div class="btn-slot" id="slot-btn-favorite"></div>' +
'<div class="btn-slot" id="slot-btn-search"></div>' +
'</div>' +
'<div class="hedset">' +
// '<div class="btn-slot slot-btn-user-name"></div>' +
@ -348,6 +349,9 @@ define([
});
}
}
if (me.btnSearch)
me.btnSearch.updateHint(me.tipSearch + Common.Utils.String.platformKey('Ctrl+F'));
}
function onFocusDocName(e){
@ -447,6 +451,15 @@ define([
reset : onResetUsers
});
me.btnSearch = new Common.UI.Button({
cls: 'btn-header no-caret',
iconCls: 'toolbar__icon icon--inverse btn-menu-search',
enableToggle: true,
dataHint: '0',
dataHintDirection: 'bottom',
dataHintOffset: 'big'
});
me.btnFavorite = new Common.UI.Button({
id: 'btn-favorite',
cls: 'btn-header',
@ -540,6 +553,7 @@ define([
if ( config.canEdit && config.canRequestEditRights )
this.btnEdit = createTitleButton('toolbar__icon icon--inverse btn-edit', $html.findById('#slot-hbtn-edit'), undefined, 'bottom', 'big');
}
me.btnSearch.render($html.find('#slot-btn-search'));
if (!config.isEdit || config.customization && !!config.customization.compactHeader) {
if (config.user.guest && config.canRenameAnonymous) {
@ -875,6 +889,7 @@ define([
textRemoveFavorite: 'Remove from Favorites',
textAddFavorite: 'Mark as favorite',
textHideNotes: 'Hide Notes',
tipSearch: 'Search',
textShare: 'Share'
}
}(), Common.Views.Header || {}))

View file

@ -0,0 +1,194 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 03.02.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
define([
'common/main/lib/component/Window'
], function () {
'use strict';
Common.UI.SearchBar = Common.UI.Window.extend(_.extend({
options: {
modal: false,
width: 328,
height: 54,
header: false,
cls: 'search-bar',
alias: 'SearchBar'
},
initialize : function(options) {
_.extend(this.options, options || {});
this.template = [
'<div class="box">',
'<input type="text" id="search-bar-text" class="input-field form-control" maxlength="255" placeholder="'+this.textFind+'" autocomplete="off">',
'<div class="tools">',
'<div id="search-bar-back"></div>',
'<div id="search-bar-next"></div>',
'<div id="search-bar-open-panel"></div>',
'<div id="search-bar-close"></div>',
'</div>',
'</div>'
].join('');
this.options.tpl = _.template(this.template)(this.options);
Common.UI.Window.prototype.initialize.call(this, this.options);
Common.NotificationCenter.on('layout:changed', _.bind(this.onLayoutChanged, this));
$(window).on('resize', _.bind(this.onLayoutChanged, this));
},
render: function() {
Common.UI.Window.prototype.render.call(this);
this.inputSearch = this.$window.find('#search-bar-text');
this.inputSearch.on('input', _.bind(function () {
this.disableNavButtons();
this.fireEvent('search:input', [this.inputSearch.val()]);
}, this)).on('keydown', _.bind(function (e) {
this.fireEvent('search:keydown', [this.inputSearch.val(), e]);
}, this));
this.btnBack = new Common.UI.Button({
parentEl: $('#search-bar-back'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-arrow-up',
hint: this.tipPreviousResult
});
this.btnBack.on('click', _.bind(this.onBtnNextClick, this, 'back'));
this.btnNext = new Common.UI.Button({
parentEl: $('#search-bar-next'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-arrow-down',
hint: this.tipNextResult
});
this.btnNext.on('click', _.bind(this.onBtnNextClick, this, 'next'));
this.btnOpenPanel = new Common.UI.Button({
parentEl: $('#search-bar-open-panel'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon more-vertical',
hint: this.tipOpenAdvancedSettings
});
this.btnOpenPanel.on('click', _.bind(this.onOpenPanel, this));
this.btnClose = new Common.UI.Button({
parentEl: $('#search-bar-close'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-close',
hint: this.tipCloseSearch
});
this.btnClose.on('click', _.bind(function () {
this.hide();
}, this))
this.on('animate:before', _.bind(this.focus, this));
Common.NotificationCenter.on('search:updateresults', _.bind(this.disableNavButtons, this));
return this;
},
show: function(text) {
var top = $('#app-title').height() + $('#toolbar').height() + 2,
left = Common.Utils.innerWidth() - ($('#right-menu').is(':visible') ? $('#right-menu').width() : 0) - this.options.width - 32;
Common.UI.Window.prototype.show.call(this, left, top);
if (text) {
this.inputSearch.val(text);
this.fireEvent('search:input', [text]);
} else {
this.inputSearch.val('');
}
this.disableNavButtons();
this.focus();
},
focus: function() {
var me = this;
setTimeout(function(){
me.inputSearch.focus();
me.inputSearch.select();
}, 10);
},
setText: function (text) {
this.inputSearch.val(text);
this.fireEvent('search:input', [text]);
},
getSettings: function() {
return {
};
},
onLayoutChanged: function () {
var top = $('#app-title').height() + $('#toolbar').height() + 2,
left = Common.Utils.innerWidth() - ($('#right-menu').is(':visible') ? $('#right-menu').width() : 0) - this.options.width - 32;
this.$window.css({left: left, top: top});
},
onBtnNextClick: function(action) {
this.fireEvent('search:'+action, [this.inputSearch.val(), false]);
},
onOpenPanel: function () {
this.hide();
this.fireEvent('search:show', [true, this.inputSearch.val()]);
},
disableNavButtons: function (resultNumber, allResults) {
var disable = this.inputSearch.val() === '';
this.btnBack.setDisabled(disable || !allResults || resultNumber === 0);
this.btnNext.setDisabled(disable || resultNumber + 1 === allResults);
},
textFind: 'Find',
tipPreviousResult: 'Previous result',
tipNextResult: 'Next result',
tipOpenAdvancedSettings: 'Open advanced settings',
tipCloseSearch: 'Close search'
}, Common.UI.SearchBar || {}));
});

View file

@ -0,0 +1,418 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* User: Julia.Svinareva
* Date: 11.02.2022
*/
define([
'text!common/main/lib/template/SearchPanel.template',
'common/main/lib/util/utils',
'common/main/lib/component/BaseView',
'common/main/lib/component/Layout'
], function (template) {
'use strict';
Common.Views.SearchPanel = Common.UI.BaseView.extend(_.extend({
el: '#left-panel-search',
template: _.template(template),
initialize: function(options) {
_.extend(this, options);
Common.UI.BaseView.prototype.initialize.call(this, arguments);
this.mode = false;
window.SSE && (this.extendedOptions = Common.localStorage.getBool('sse-search-options-extended', true));
},
render: function(el) {
var me = this;
if (!this.rendered) {
el = el || this.el;
$(el).html(this.template({
scope: this
}));
this.$el = $(el);
this.inputText = new Common.UI.InputField({
el: $('#search-adv-text'),
placeHolder: this.textFind,
allowBlank: true,
validateOnBlur: false,
style: 'width: 100%;',
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
});
this.inputText._input.on('input', _.bind(function () {
this.fireEvent('search:input', [this.inputText._input.val()]);
}, this)).on('keydown', _.bind(function (e) {
this.fireEvent('search:keydown', [this.inputText._input.val(), e]);
}, this));
this.inputReplace = new Common.UI.InputField({
el: $('#search-adv-replace-text'),
placeHolder: this.textReplaceWith,
allowBlank: true,
validateOnBlur: false,
style: 'width: 100%;',
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
});
this.btnBack = new Common.UI.Button({
parentEl: $('#search-adv-back'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-arrow-up',
hint: this.tipPreviousResult,
dataHint: '1',
dataHintDirection: 'bottom'
});
this.btnBack.on('click', _.bind(this.onBtnNextClick, this, 'back'));
this.btnNext = new Common.UI.Button({
parentEl: $('#search-adv-next'),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-arrow-down',
hint: this.tipNextResult,
dataHint: '1',
dataHintDirection: 'bottom'
});
this.btnNext.on('click', _.bind(this.onBtnNextClick, this, 'next'));
this.btnReplace = new Common.UI.Button({
el: $('#search-adv-replace')
});
this.btnReplace.on('click', _.bind(this.onReplaceClick, this, 'replace'));
this.btnReplaceAll = new Common.UI.Button({
el: $('#search-adv-replace-all')
});
this.btnReplaceAll.on('click', _.bind(this.onReplaceClick, this, 'replaceall'));
this.$reaultsNumber = $('#search-adv-results-number');
this.updateResultsNumber('no-results');
this.chCaseSensitive = new Common.UI.CheckBox({
el: $('#search-adv-case-sensitive'),
labelText: this.textCaseSensitive,
value: false,
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
}).on('change', function(field) {
me.fireEvent('search:options', ['case-sensitive', field.getValue() === 'checked']);
});
/*this.chUseRegExp = new Common.UI.CheckBox({
el: $('#search-adv-use-regexp'),
labelText: this.textMatchUsingRegExp,
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
}).on('change', function(field) {
me.fireEvent('search:options', ['regexp', field.getValue() === 'checked']);
});*/
this.chMatchWord = new Common.UI.CheckBox({
el: $('#search-adv-match-word'),
labelText: window.SSE ? this.textItemEntireCell : this.textWholeWords,
value: false,
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
}).on('change', function(field) {
me.fireEvent('search:options', ['match-word', field.getValue() === 'checked']);
});
this.buttonClose = new Common.UI.Button({
parentEl: $('#search-btn-close', this.$el),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-close',
hint: this.textCloseSearch,
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'medium'
});
this.buttonClose.on('click', _.bind(this.onClickClosePanel, this));
this.$resultsContainer = $('#search-results');
this.$resultsContainer.hide();
Common.NotificationCenter.on('search:updateresults', _.bind(this.disableNavButtons, this));
if (window.SSE) {
this.cmbWithin = new Common.UI.ComboBox({
el: $('#search-adv-cmb-within'),
menuStyle: 'min-width: 100%;',
style: "width: 219px;",
editable: false,
cls: 'input-group-nr',
data: [
{ value: 0, displayValue: this.textSheet },
{ value: 1, displayValue: this.textWorkbook },
{ value: 2, displayValue: this.textSpecificRange}
],
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'big'
}).on('selected', function(combo, record) {
me.fireEvent('search:options', ['within', record.value]);
});
this.inputSelectRange = new Common.UI.InputFieldBtn({
el: $('#search-adv-select-range'),
placeHolder: this.textSelectDataRange,
allowBlank: true,
validateOnChange: true,
validateOnBlur: true,
style: "width: 219px; margin-top: 8px",
disabled: true,
dataHint: '1',
dataHintDirection: 'left',
dataHintOffset: 'small'
}).on('keyup:after', function(input, e) {
me.fireEvent('search:options', ['range', input.getValue(), e.keyCode !== Common.UI.Keys.RETURN]);
});
this.cmbSearch = new Common.UI.ComboBox({
el: $('#search-adv-cmb-search'),
menuStyle: 'min-width: 100%;',
style: "width: 219px;",
editable: false,
cls: 'input-group-nr',
data: [
{ value: 0, displayValue: this.textByRows },
{ value: 1, displayValue: this.textByColumns }
],
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'big'
}).on('selected', function(combo, record) {
me.fireEvent('search:options', ['search', !record.value]);
});
this.cmbLookIn = new Common.UI.ComboBox({
el: $('#search-adv-cmb-look-in'),
menuStyle: 'min-width: 100%;',
style: "width: 219px;",
editable: false,
cls: 'input-group-nr',
data: [
{ value: 0, displayValue: this.textFormulas },
{ value: 1, displayValue: this.textValues }
],
dataHint: '1',
dataHintDirection: 'bottom',
dataHintOffset: 'big'
}).on('selected', function(combo, record) {
me.fireEvent('search:options', ['lookIn', !record.value]);
});
this.$searchOptionsBlock = $('.search-options-block');
this.$searchOptionsBlock.show();
$('#open-search-options').on('click', _.bind(this.expandSearchOptions, this));
if (!this.extendedOptions) {
this.$searchOptionsBlock.addClass('no-expand');
}
this.cmbWithin.setValue(0);
this.cmbSearch.setValue(0);
this.cmbLookIn.setValue(0);
var tableTemplate = '<div class="search-table">' +
'<div class="header-item">' + this.textSheet + '</div>' +
'<div class="header-item">' + this.textName + '</div>' +
'<div class="header-item">' + this.textCell + '</div>' +
'<div class="header-item">' + this.textValue + '</div>' +
'<div class="header-item">' + this.textFormula + '</div>' +
'<div class="ps-container oo search-items"></div>' +
'</div>',
$resultTable = $(tableTemplate).appendTo(this.$resultsContainer);
this.$resultsContainer.scroller = new Common.UI.Scroller({
el: $resultTable.find('.search-items'),
includePadding: true,
useKeyboard: true,
minScrollbarLength: 40,
alwaysVisibleY: true
});
} else {
this.$resultsContainer.scroller = new Common.UI.Scroller({
el: this.$resultsContainer,
includePadding: true,
useKeyboard: true,
minScrollbarLength: 40,
alwaysVisibleY: true
});
}
Common.NotificationCenter.on('window:resize', function() {
me.$resultsContainer.outerHeight($('#search-box').outerHeight() - $('#search-header').outerHeight() - $('#search-adv-settings').outerHeight());
me.$resultsContainer.scroller.update({alwaysVisibleY: true});
});
}
this.rendered = true;
this.trigger('render:after', this);
return this;
},
show: function () {
Common.UI.BaseView.prototype.show.call(this,arguments);
this.fireEvent('show', this );
this.$resultsContainer.outerHeight($('#search-box').outerHeight() - $('#search-header').outerHeight() - $('#search-adv-settings').outerHeight());
this.$resultsContainer.scroller.update({alwaysVisibleY: true});
},
hide: function () {
Common.UI.BaseView.prototype.hide.call(this,arguments);
this.fireEvent('hide', this );
},
focus: function(type) {
var me = this,
el = type === 'replace' ? me.inputReplace.$el : (type === 'range' ? me.inputSelectRange.$el : me.inputText.$el);
setTimeout(function(){
el.find('input').focus();
el.find('input').select();
}, 10);
},
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.mode = mode;
}
},
ChangeSettings: function(props) {
},
updateResultsNumber: function (current, count) {
var text;
if (count > 300) {
text = this.textTooManyResults;
} else {
text = current === 'no-results' ? this.textNoSearchResults : (!count ? this.textNoMatches : Common.Utils.String.format(this.textSearchResults, current + 1, count));
}
this.$reaultsNumber.text(text);
this.disableReplaceButtons(!count);
},
onClickClosePanel: function() {
Common.NotificationCenter.trigger('leftmenu:change', 'hide');
this.fireEvent('hide', this );
},
onBtnNextClick: function (action) {
this.fireEvent('search:'+action, [this.inputText.getValue(), true]);
},
onReplaceClick: function (action) {
this.fireEvent('search:'+action, [this.inputText.getValue(), this.inputReplace.getValue()]);
},
getSettings: function() {
return {
textsearch: this.inputText.getValue(),
matchcase: this.chCaseSensitive.checked,
matchword: this.chMatchWord.checked
};
},
expandSearchOptions: function () {
this.extendedOptions = !this.extendedOptions;
this.$searchOptionsBlock[this.extendedOptions ? 'removeClass' : 'addClass']('no-expand');
Common.localStorage.setBool('sse-search-options-extended', this.extendedOptions);
this.$resultsContainer.outerHeight($('#search-box').outerHeight() - $('#search-header').outerHeight() - $('#search-adv-settings').outerHeight());
this.$resultsContainer.scroller.update({alwaysVisibleY: true});
},
setFindText: function (val) {
this.inputText.setValue(val);
},
clearResultsNumber: function () {
this.updateResultsNumber('no-results');
},
disableNavButtons: function (resultNumber, allResults) {
var disable = this.inputText._input.val() === '';
this.btnBack.setDisabled(disable || !allResults || resultNumber === 0);
this.btnNext.setDisabled(disable || !allResults || resultNumber + 1 === allResults);
},
disableReplaceButtons: function (disable) {
this.btnReplace.setDisabled(disable);
this.btnReplaceAll.setDisabled(disable);
},
textFind: 'Find',
textFindAndReplace: 'Find and replace',
textCloseSearch: 'Close search',
textReplace: 'Replace',
textReplaceAll: 'Replace All',
textSearchResults: 'Search results: {0}/{1}',
textReplaceWith: 'Replace with',
textCaseSensitive: 'Case sensitive',
textMatchUsingRegExp: 'Match using regular expressions',
textWholeWords: 'Whole words only',
textWithin: 'Within',
textSelectDataRange: 'Select Data range',
textSearch: 'Search',
textLookIn: 'Look in',
textSheet: 'Sheet',
textWorkbook: 'Workbook',
textSpecificRange: 'Specific range',
textByRows: 'By rows',
textByColumns: 'By columns',
textFormulas: 'Formulas',
textValues: 'Values',
textSearchOptions: 'Search options',
textNoMatches: 'No matches',
textNoSearchResults: 'No search results',
textItemEntireCell: 'Entire cell contents',
textTooManyResults: 'There are too many results to show here',
tipPreviousResult: 'Previous result',
tipNextResult: 'Next result',
textName: 'Name',
textCell: 'Cell',
textValue: 'Value',
textFormula: 'Formula'
}, Common.Views.SearchPanel || {}));
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

View file

@ -92,6 +92,10 @@ label {
#left-panel-comments {
height: 100%;
}
#left-panel-search {
height: 100%;
}
}
.right-panel {

View file

@ -80,4 +80,164 @@
}
}
}
}
.search-bar {
z-index: 950;
.box {
padding: 16px;
display: flex;
input[type=text] {
width: 192px;
}
.tools {
display: flex;
align-items: center;
div {
margin-left: 5px;
&:first-of-type {
margin-left: 7px;
}
}
}
}
}
.search-panel {
display: table;
position: relative;
border-collapse: collapse;
line-height: 15px;
> div {
display: table-row;
}
#search-header {
position: absolute;
height: 45px;
left: 0;
top: 0;
right: 0;
padding: 12px;
overflow: hidden;
border-bottom: @scaled-one-px-value-ie solid @border-toolbar-ie;
border-bottom: @scaled-one-px-value solid @border-toolbar;
label {
font-size: 12px;
.font-weight-bold();
margin-top: 2px;
}
#search-btn-close {
float: right;
}
}
#search-adv-settings {
position: absolute;
left: 0;
right: 0;
top: 45px;
padding: 10px 15px 0 15px;
table {
width: 100%;
}
.padding-small {
padding-bottom: 8px;
}
.padding-large {
padding-bottom: 14px;
}
#search-adv-results-number {
padding-top: 2px;
width: calc(100% - 48px);
color: @text-secondary-ie;
color: @text-secondary;
}
}
.search-options-block {
display: none;
}
#open-search-options {
cursor: pointer;
margin-left: 15px;
.search-options-txt {
display: inline-block;
padding: 5px 0;
}
.search-options-caret {
width: 24px;
height: 24px;
background-position: 3px -270px;
display: inline-block;
position: absolute;
left: 0;
cursor: pointer;
margin-left: 8px;
}
}
#search-options {
label {
margin-top: 6px;
&:not(:first-of-type) {
margin-top: 8px;
}
}
}
.no-expand {
#search-options {
display: none;
}
.search-options-caret {
transform: rotate(270deg);
}
}
#search-results {
position: absolute;
left: 0;
right: 0;
bottom: 0;
width: 100%;
border-top: @scaled-one-px-value-ie solid @border-toolbar-ie;
border-top: @scaled-one-px-value solid @border-toolbar;
padding: 12px 0;
overflow: hidden;
.item {
padding: 6px 15px;
word-break: break-all;
cursor: pointer;
&:hover {
background-color: @highlight-button-hover-ie;
background-color: @highlight-button-hover;
}
&.selected {
background-color: @highlight-button-pressed-ie;
background-color: @highlight-button-pressed;
color: @text-normal-pressed-ie;
color: @text-normal-pressed;
}
b {
font-style: italic;
}
}
}
}

View file

@ -198,6 +198,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="id-pages" class="item margin-right-small" style="vertical-align: middle;"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="id-submit-group" style="display: inline-block;"><button id="id-btn-submit" class="control-btn has-caption margin-left-small margin-right-small colored"><span class="caption"></span></button></div>
<div id="box-tools" class="dropdown">
@ -255,6 +256,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -190,6 +190,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="id-pages" class="item margin-right-small" style="vertical-align: middle;"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="id-submit-group" style="display: inline-block;"><button id="id-btn-submit" class="control-btn has-caption margin-right-small margin-left-small colored"><span class="caption"></span></button></div>
<div id="box-tools" class="dropdown">

View file

@ -75,6 +75,8 @@ DE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -449,6 +451,10 @@ DE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onStartAction', onLongActionBegin);
api.asc_registerCallback('asc_onEndAction', onLongActionEnd);
api.asc_registerCallback('asc_onMouseMoveStart', onDocMouseMoveStart);
@ -911,6 +917,8 @@ DE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,175 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
highlightResults(false);
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
highlightResults(false);
$searchBar.hide();
} else {
highlightResults(true);
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(_state.searchText);
searchSettings.put_MatchCase(false);
searchSettings.put_WholeWords(false);
if (!api.asc_findText(searchSettings, d != 'back')) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
var highlightResults = function (val) {
if (_state.isHighlightedResults !== val) {
api.asc_selectSearchingResults(val);
_state.isHighlightedResults = val;
}
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();

View file

@ -4,6 +4,7 @@
"common.view.modals.txtHeight": "Height",
"common.view.modals.txtShare": "Share Link",
"common.view.modals.txtWidth": "Width",
"common.view.SearchBar.textFind": "Find",
"DE.ApplicationController.convertationErrorText": "Conversion failed.",
"DE.ApplicationController.convertationTimeoutText": "Conversion timeout exceeded.",
"DE.ApplicationController.criticalErrorTitle": "Error",

View file

@ -158,6 +158,7 @@ require([
'LeftMenu',
'Main',
'ViewTab',
'Search',
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
@ -191,6 +192,7 @@ require([
'documenteditor/main/app/controller/LeftMenu',
'documenteditor/main/app/controller/Main',
'documenteditor/main/app/controller/ViewTab',
'documenteditor/main/app/controller/Search',
'documenteditor/main/app/view/FileMenuPanels',
'documenteditor/main/app/view/ParagraphSettings',
'documenteditor/main/app/view/HeaderFooterSettings',

View file

@ -96,19 +96,14 @@ define([
'file:close': this.clickToolbarTab.bind(this, 'other'),
'save:disabled': this.changeToolbarSaveState.bind(this)
},
'SearchDialog': {
'hide': _.bind(this.onSearchDlgHide, this),
'search:back': _.bind(this.onQuerySearch, this, 'back'),
'search:next': _.bind(this.onQuerySearch, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this),
'search:highlight': _.bind(this.onSearchHighlight, this)
},
'Common.Views.ReviewChanges': {
'collaboration:chat': _.bind(this.onShowHideChat, this)
},
'ViewTab': {
'viewtab:navigation': _.bind(this.onShowHideNavigation, this)
},
'SearchBar': {
'search:show': _.bind(this.onShowHideSearch, this)
}
});
@ -122,7 +117,7 @@ define([
onLaunch: function() {
this.leftMenu = this.createView('LeftMenu').render();
this.leftMenu.btnSearch.on('toggle', _.bind(this.onMenuSearch, this));
this.leftMenu.btnSearchBar.on('toggle', _.bind(this.onMenuSearchBar, this));
Common.util.Shortcuts.delegateShortcuts({
shortcuts: {
@ -144,7 +139,6 @@ define([
setApi: function(api) {
this.api = api;
this.api.asc_registerCallback('asc_onReplaceAll', _.bind(this.onApiTextReplaced, this));
this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiServerDisconnect, this));
Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiServerDisconnect, this));
this.api.asc_registerCallback('asc_onDownloadUrl', _.bind(this.onDownloadUrl, this));
@ -171,6 +165,8 @@ define([
if (this.mode.canUseHistory)
this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode);
this.getApplication().getController('PageThumbnails').setApi(this.api).setMode(this.mode);
this.getApplication().getController('Search').setApi(this.api).setMode(this.mode);
this.leftMenu.setOptionsPanel('advancedsearch', this.getApplication().getController('Search').getView('Common.Views.SearchPanel'));
return this;
},
@ -570,112 +566,6 @@ define([
},
/** coauthoring end **/
onQuerySearch: function(d, w, opts) {
if (opts.textsearch && opts.textsearch.length) {
var me = this;
this.api.asc_findText(opts.textsearch, d != 'back', opts.matchcase, function(resultCount) {
!resultCount && Common.UI.info({
msg: me.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
});
}
},
onQueryReplace: function(w, opts) {
if (!_.isEmpty(opts.textsearch)) {
var me = this;
var str = this.api.asc_GetErrorForReplaceString(opts.textreplace);
if (str) {
Common.UI.warning({
title: this.notcriticalErrorTitle,
msg: Common.Utils.String.format(this.warnReplaceString, str),
buttons: ['ok'],
callback: function(btn){
me.dlgSearch.focus('replace');
}
});
return;
}
if (!this.api.asc_replaceText(opts.textsearch, opts.textreplace, false, opts.matchcase, opts.matchword)) {
Common.UI.info({
msg: this.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
}
}
},
onQueryReplaceAll: function(w, opts) {
if (!_.isEmpty(opts.textsearch)) {
var me = this;
var str = this.api.asc_GetErrorForReplaceString(opts.textreplace);
if (str) {
Common.UI.warning({
title: this.notcriticalErrorTitle,
msg: Common.Utils.String.format(this.warnReplaceString, str),
buttons: ['ok'],
callback: function(btn){
me.dlgSearch.focus('replace');
}
});
return;
}
this.api.asc_replaceText(opts.textsearch, opts.textreplace, true, opts.matchcase, opts.matchword);
}
},
onSearchHighlight: function(w, highlight) {
this.api.asc_selectSearchingResults(highlight);
},
showSearchDlg: function(show,action) {
if ( !this.dlgSearch ) {
this.dlgSearch = (new Common.UI.SearchDialog({
matchcase: true,
markresult: {applied: true}
}));
}
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? (action || undefined) : 'no-replace';
if (this.dlgSearch.isVisible()) {
this.dlgSearch.setMode(mode);
this.dlgSearch.setSearchText(this.api.asc_GetSelectedText());
this.dlgSearch.focus();
} else {
this.dlgSearch.show(mode, this.api.asc_GetSelectedText());
}
} else this.dlgSearch['hide']();
},
onMenuSearch: function(obj, show) {
this.showSearchDlg(show);
},
onSearchDlgHide: function() {
this.leftMenu.btnSearch.toggle(false, true);
this.api.asc_selectSearchingResults(false);
$(this.leftMenu.btnSearch.el).blur();
this.api.asc_enableKeyEvents(true);
},
onApiTextReplaced: function(found,replaced) {
var me = this;
if (found) {
!(found - replaced > 0) ?
Common.UI.info( {msg: Common.Utils.String.format(this.textReplaceSuccess, replaced)} ) :
Common.UI.warning( {msg: Common.Utils.String.format(this.textReplaceSkipped, found-replaced)} );
} else {
Common.UI.info({msg: this.textNoTextFound});
}
},
onApiServerDisconnect: function(enableDownload) {
this.mode.isEdit = false;
this.leftMenu.close();
@ -688,17 +578,13 @@ define([
this.leftMenu.btnNavigation.setDisabled(true);
this.leftMenu.getMenu('file').setMode({isDisconnected: true, enableDownload: !!enableDownload});
if ( this.dlgSearch ) {
this.leftMenu.btnSearch.toggle(false, true);
this.dlgSearch['hide']();
}
},
setPreviewMode: function(mode) {
if (this.viewmode === mode) return;
this.viewmode = mode;
this.dlgSearch && this.dlgSearch.setMode(this.viewmode ? 'no-replace' : 'search');
this.leftMenu.panelSearch && this.leftMenu.panelSearch.setSearchMode(this.viewmode ? 'no-replace' : 'search');
},
SetDisabled: function(disable, options) {
@ -792,12 +678,6 @@ define([
},
menuFilesShowHide: function(state) {
if ( this.dlgSearch ) {
if ( state == 'show' )
this.dlgSearch.suspendKeyEvents();
else
Common.Utils.asyncCall(this.dlgSearch.resumeKeyEvents, this.dlgSearch);
}
if (this.api && state == 'hide')
this.api.asc_enableKeyEvents(true);
},
@ -815,6 +695,9 @@ define([
this.leftMenu.btnThumbnails.toggle(false);
this.leftMenu.panelThumbnails.hide();
this.leftMenu.onBtnMenuClick(this.leftMenu.btnThumbnails);
} else if (this.leftMenu.btnSearchBar.isActive()) {
this.leftMenu.btnSearchBar.toggle(false);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
else if (this.leftMenu.btnNavigation.isActive()) {
this.leftMenu.btnNavigation.toggle(false);
@ -831,10 +714,31 @@ define([
switch (s) {
case 'replace':
case 'search':
Common.UI.Menu.Manager.hideAll();
this.showSearchDlg(true,s);
this.leftMenu.btnSearch.toggle(true,true);
this.leftMenu.btnAbout.toggle(false);
var selectedText = this.api.asc_GetSelectedText();
if (this.isSearchPanelVisible()) {
selectedText && this.leftMenu.panelSearch.setFindText(selectedText);
this.leftMenu.panelSearch.focus(selectedText !== '' ? s : 'search');
this.leftMenu.fireEvent('search:aftershow', this.leftMenu, selectedText);
return false;
} else if (this.getApplication().getController('Viewport').isSearchBarVisible()) {
var viewport = this.getApplication().getController('Viewport');
if (s === 'replace') {
viewport.header.btnSearch.toggle(false);
this.onShowHideSearch(true, viewport.searchBar.inputSearch.val());
} else {
selectedText && viewport.searchBar.setText(selectedText);
viewport.searchBar.focus();
return false;
}
} else if (s === 'search') {
Common.NotificationCenter.trigger('search:show');
return false;
} else {
this.onShowHideSearch(true, selectedText);
}
this.leftMenu.btnSearchBar.toggle(true,true);
this.leftMenu.panelSearch.focus(selectedText !== '' ? s : 'search');
// this.leftMenu.menuFile.hide();
return false;
case 'save':
@ -861,6 +765,10 @@ define([
return false;
case 'escape':
// if (!this.leftMenu.isOpened()) return true;
var btnSearch = this.getApplication().getController('Viewport').header.btnSearch;
btnSearch.pressed && btnSearch.toggle(false);
this.leftMenu._state.isSearchOpen && (this.leftMenu._state.isSearchOpen = false);
if ( this.leftMenu.menuFile.isVisible() ) {
if (Common.UI.HintManager.needCloseFileMenu())
this.leftMenu.menuFile.hide();
@ -954,6 +862,29 @@ define([
}
},
onShowHideSearch: function (state, findText) {
if (state) {
Common.UI.Menu.Manager.hideAll();
this.leftMenu.showMenu('advancedsearch', undefined, true);
this.leftMenu.fireEvent('search:aftershow', this.leftMenu, findText);
} else {
this.leftMenu.btnSearchBar.toggle(false, true);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
},
onMenuSearchBar: function(obj, show) {
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? undefined : 'no-replace';
this.leftMenu.panelSearch.setSearchMode(mode);
}
this.leftMenu._state.isSearchOpen = show;
},
isSearchPanelVisible: function () {
return this.leftMenu._state.isSearchOpen;
},
isCommentsVisible: function() {
return this.leftMenu && this.leftMenu.panelComments && this.leftMenu.panelComments.isVisible();
},

View file

@ -1257,6 +1257,7 @@ define([
pluginsController = application.getController('Common.Controllers.Plugins'),
navigationController = application.getController('Navigation');
leftmenuController.getView('LeftMenu').getMenu('file').loadDocument({doc:me.document});
leftmenuController.setMode(me.appOptions).createDelayedElements().setApi(me.api);

View file

@ -0,0 +1,427 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* ViewTab.js
*
* Created by Julia Svinareva on 09.02.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
define([
'core',
'common/main/lib/view/SearchPanel'
], function () {
'use strict';
DE.Controllers.Search = Backbone.Controller.extend(_.extend({
sdkViewName : '#id_main',
views: [
'Common.Views.SearchPanel'
],
initialize: function () {
this.addListeners({
'SearchBar': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:input': _.bind(this.onInputSearchChange, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown'),
'show': _.bind(this.onSelectSearchingResults, this, true),
'hide': _.bind(this.onSelectSearchingResults, this, false)
},
'Common.Views.SearchPanel': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this),
'search:input': _.bind(this.onInputSearchChange, this),
'search:options': _.bind(this.onChangeSearchOption, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown'),
'show': _.bind(this.onShowPanel, this),
'hide': _.bind(this.onHidePanel, this),
},
'LeftMenu': {
'search:aftershow': _.bind(this.onShowAfterSearch, this)
}
});
},
onLaunch: function () {
this._state = {
searchText: '',
matchCase: false,
matchWord: false,
useRegExp: false,
isHighlightedResults: false
};
},
setMode: function (mode) {
this.view = this.createView('Common.Views.SearchPanel', { mode: mode });
},
setApi: function (api) {
if (api) {
this.api = api;
this.api.asc_registerCallback('asc_onSetSearchCurrent', _.bind(this.onUpdateSearchCurrent, this));
this.api.asc_registerCallback('asc_onStartTextAroundSearch', _.bind(this.onStartTextAroundSearch, this));
this.api.asc_registerCallback('asc_onEndTextAroundSearch', _.bind(this.onEndTextAroundSearch, this));
this.api.asc_registerCallback('asc_onGetTextAroundSearchPack', _.bind(this.onApiGetTextAroundSearch, this));
this.api.asc_registerCallback('asc_onRemoveTextAroundSearch', _.bind(this.onApiRemoveTextAroundSearch, this));
}
return this;
},
getView: function(name) {
return !name && this.view ?
this.view : Backbone.Controller.prototype.getView.call(this, name);
},
onChangeSearchOption: function (option, checked) {
switch (option) {
case 'case-sensitive':
this._state.matchCase = checked;
break;
case 'match-word':
this._state.matchWord = checked;
break;
case 'regexp':
this._state.useRegExp = checked;
break;
}
if (this._state.searchText !== '') {
this.hideResults();
if (this.onQuerySearch()) {
if (this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = undefined;
}
this.api.asc_StartTextAroundSearch();
}
}
},
onSearchNext: function (type, text, e) {
var isReturnKey = type === 'keydown' && e.keyCode === Common.UI.Keys.RETURN;
if (text && text.length > 0 && (isReturnKey || type !== 'keydown')) {
this._state.searchText = text;
if (this.onQuerySearch(type) && (this.searchTimer || isReturnKey)) {
this.hideResults();
if (this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = undefined;
}
if (this.view.$el.is(':visible')) {
this.api.asc_StartTextAroundSearch();
}
}
}
},
onInputSearchChange: function (text) {
var me = this;
if (this._state.searchText !== text) {
this._state.newSearchText = text;
this._lastInputChange = (new Date());
if (this.searchTimer === undefined) {
this.searchTimer = setInterval(function(){
if ((new Date()) - me._lastInputChange < 400) return;
me.hideResults();
me._state.searchText = me._state.newSearchText;
if (me._state.newSearchText !== '' && me.onQuerySearch()) {
if (me.view.$el.is(':visible')) {
me.api.asc_StartTextAroundSearch();
}
me.view.disableReplaceButtons(false);
} else if (me._state.newSearchText === '') {
me.view.updateResultsNumber('no-results');
me.view.disableReplaceButtons(true);
}
clearInterval(me.searchTimer);
me.searchTimer = undefined;
}, 10);
}
}
},
onQuerySearch: function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(this._state.searchText);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
if (!this.api.asc_findText(searchSettings, d != 'back')) {
this.resultItems = [];
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
return false;
}
return true;
},
onQueryReplace: function(textSearch, textReplace) {
if (textSearch !== '') {
var me = this;
var str = this.api.asc_GetErrorForReplaceString(textReplace);
if (str) {
Common.UI.warning({
title: this.notcriticalErrorTitle,
msg: Common.Utils.String.format(this.warnReplaceString, str),
buttons: ['ok'],
callback: function(){
me.view.focus('replace');
}
});
return;
}
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(textSearch);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
if (!this.api.asc_replaceText(searchSettings, textReplace, false)) {
this.allResultsWasRemoved();
}
}
},
onQueryReplaceAll: function(textSearch, textReplace) {
if (textSearch !== '') {
var me = this;
var str = this.api.asc_GetErrorForReplaceString(textReplace);
if (str) {
Common.UI.warning({
title: this.notcriticalErrorTitle,
msg: Common.Utils.String.format(this.warnReplaceString, str),
buttons: ['ok'],
callback: function(){
me.view.focus('replace');
}
});
return;
}
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(textSearch);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
this.api.asc_replaceText(searchSettings, textReplace, true);
this.allResultsWasRemoved();
}
},
allResultsWasRemoved: function () {
this.resultItems = [];
this.hideResults();
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
},
onUpdateSearchCurrent: function (current, all) {
if (current === -1) return;
this._state.currentResult = current;
this._state.resultsNumber = all;
if (this.view) {
this.view.updateResultsNumber(current, all);
this.view.disableNavButtons(current, all);
if (this.resultItems && this.resultItems.length > 0) {
this.resultItems.forEach(function (item) {
item.selected = false;
});
if (this.resultItems[current]) {
this.resultItems[current].selected = true;
$('#search-results').find('.item').removeClass('selected');
$(this.resultItems[current].el).addClass('selected');
this.scrollToSelectedResult(current);
}
}
}
Common.NotificationCenter.trigger('search:updateresults', current, all);
},
scrollToSelectedResult: function (ind) {
var index = ind !== undefined ? ind : _.findIndex(this.resultItems, {selected: true});
if (index !== -1) {
var item = this.resultItems[index].$el,
itemHeight = item.outerHeight(),
itemTop = item.position().top,
container = this.view.$resultsContainer,
containerHeight = container.outerHeight(),
containerTop = container.scrollTop();
if (itemTop < 0 || (containerTop === 0 && itemTop > containerHeight)) {
container.scroller.scrollTop(containerTop + itemTop - 12);
} else if (itemTop + itemHeight > containerHeight) {
container.scroller.scrollTop(containerTop + itemHeight);
}
}
},
onStartTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = true;
}
},
onEndTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = false;
this.view.$resultsContainer.scroller.update({alwaysVisibleY: true});
}
},
onApiGetTextAroundSearch: function (data) {
if (this.view && this._state.isStartedAddingResults) {
if (data.length > 300 || !data.length) return;
var me = this;
me.resultItems = [];
data.forEach(function (item, ind) {
var el = document.createElement("div"),
isSelected = ind === me._state.currentResult;
el.className = 'item';
el.innerHTML = item[1].trim();
me.view.$resultsContainer.append(el);
if (isSelected) {
$(el).addClass('selected');
}
var resultItem = {id: item[0], $el: $(el), el: el, selected: isSelected};
me.resultItems.push(resultItem);
$(el).on('click', _.bind(function (el) {
var id = item[0];
me.api.asc_SelectSearchElement(id);
}, me));
});
this.view.$resultsContainer.show();
}
},
onApiRemoveTextAroundSearch: function (arr) {
var me = this;
arr.forEach(function (id) {
var ind = _.findIndex(me.resultItems, {id: id});
if (ind !== -1) {
me.resultItems[ind].$el.remove();
me.resultItems.splice(ind, 1);
}
});
},
hideResults: function () {
if (this.view) {
this.view.$resultsContainer.hide();
this.view.$resultsContainer.empty();
}
},
onShowAfterSearch: function (findText) {
var viewport = this.getApplication().getController('Viewport');
if (viewport.isSearchBarVisible()) {
viewport.searchBar.hide();
}
var text = typeof findText === 'string' ? findText : (this.api.asc_GetSelectedText() || this._state.searchText);
if (this.resultItems && this.resultItems.length > 0 &&
(!this._state.matchCase && text.toLowerCase() === this.view.inputText.getValue().toLowerCase() ||
this._state.matchCase && text === this.view.inputText.getValue())) { // show old results
return;
}
if (text) {
this.view.setFindText(text);
} else if (text !== undefined) { // panel was opened from empty searchbar, clear to start new search
this.view.setFindText('');
this._state.searchText = undefined;
}
this.hideResults();
if (text !== '' && text === this._state.searchText) { // search was made
this.view.disableReplaceButtons(false);
this.api.asc_StartTextAroundSearch();
} else if (text !== '') { // search wasn't made
this.onInputSearchChange(text);
} else {
this.resultItems = [];
this.view.disableReplaceButtons(true);
this.view.clearResultsNumber();
}
this.view.disableNavButtons(this._state.currentResult, this._state.resultsNumber);
},
onShowPanel: function () {
this.onSelectSearchingResults(true);
if (this.resultItems && this.resultItems.length > 0 && !this._state.isStartedAddingResults) {
var me = this;
this.view.$resultsContainer.show();
this.resultItems.forEach(function (item) {
me.view.$resultsContainer.append(item.el);
if (item.selected) {
$(item.el).addClass('selected');
}
$(item.el).on('click', function (el) {
me.api.asc_SelectSearchElement(item.id);
$('#search-results').find('.item').removeClass('selected');
$(el.currentTarget).addClass('selected');
});
});
this.scrollToSelectedResult();
}
},
onHidePanel: function () {
this.hideResults();
this.onSelectSearchingResults(false);
},
onSelectSearchingResults: function (val) {
if (!val && this.getApplication().getController('LeftMenu').isSearchPanelVisible()) return;
if (this._state.isHighlightedResults !== val) {
this.api.asc_selectSearchingResults(val);
this._state.isHighlightedResults = val;
}
},
notcriticalErrorTitle: 'Warning',
warnReplaceString: '{0} is not a valid special character for the Replace With box.'
}, DE.Controllers.Search || {}));
});

View file

@ -44,6 +44,7 @@
define([
'core',
'common/main/lib/view/Header',
'common/main/lib/view/SearchBar',
'documenteditor/main/app/view/Viewport',
'documenteditor/main/app/view/LeftMenu'
], function (Viewport) {
@ -148,6 +149,7 @@ define([
Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this));
Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this));
Common.NotificationCenter.on('search:show', _.bind(this.onSearchShow, this));
},
onAppShowed: function (config) {
@ -267,6 +269,34 @@ define([
this.header && this.header.lockHeaderBtns( 'rename-user', disable);
},
onSearchShow: function () {
this.header.btnSearch && this.header.btnSearch.toggle(true);
},
onSearchToggle: function () {
var leftMenu = this.getApplication().getController('LeftMenu');
if (leftMenu.isSearchPanelVisible()) {
this.header.btnSearch.toggle(false, true);
leftMenu.getView('LeftMenu').panelSearch.focus();
return;
}
if (!this.searchBar) {
this.searchBar = new Common.UI.SearchBar({});
this.searchBar.on('hide', _.bind(function () {
this.header.btnSearch.toggle(false, true);
}, this));
}
if (this.header.btnSearch.pressed) {
this.searchBar.show(this.api.asc_GetSelectedText());
} else {
this.searchBar.hide();
}
},
isSearchBarVisible: function () {
return this.searchBar && this.searchBar.isVisible();
},
textFitPage: 'Fit to Page',
textFitWidth: 'Fit to Width',
txtDarkMode: 'Dark mode'

View file

@ -1,6 +1,6 @@
<div id="view-left-menu" class="tool-menu left">
<div class="tool-menu-btns">
<button id="left-btn-search" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target=""><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<button id="left-btn-searchbar" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-search"><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<!-- /** coauthoring begin **/ -->
<button id="left-btn-comments" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-comments"><i class="icon toolbar__icon btn-menu-comments">&nbsp;</i></button>
<button id="left-btn-chat" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-chat"><i class="icon toolbar__icon btn-menu-chat">&nbsp;</i></button>
@ -12,6 +12,7 @@
<button id="left-btn-about" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target=""><i class="icon toolbar__icon btn-menu-about">&nbsp;</i></button>
</div>
<div class="left-panel" style="">
<div id="left-panel-search" class="" style="display: none;"></div>
<!-- /** coauthoring begin **/ -->
<div id="left-panel-comments" class="" style="display: none;"></div>
<div id="left-panel-chat" class="" style="display: none;"></div>

View file

@ -76,6 +76,10 @@ define([
'click #left-btn-plugins': _.bind(this.onCoauthOptions, this),
'click #left-btn-navigation': _.bind(this.onCoauthOptions, this),
'click #left-btn-thumbnails': _.bind(this.onCoauthOptions, this),
'click #left-btn-searchbar': _.bind(function () {
this.onCoauthOptions();
this.fireEvent('search:aftershow', this.leftMenu);
}, this),
'click #left-btn-support': function() {
var config = this.mode.customization;
config && !!config.feedback && !!config.feedback.url ?
@ -93,12 +97,13 @@ define([
render: function () {
var $markup = $(this.template({}));
this.btnSearch = new Common.UI.Button({
action: 'search',
el: $markup.elementById('#left-btn-search'),
hint: this.tipSearch + Common.Utils.String.platformKey('Ctrl+F'),
this.btnSearchBar = new Common.UI.Button({
action: 'advancedsearch',
el: $markup.elementById('#left-btn-searchbar'),
hint: this.tipSearch,
disabled: true,
enableToggle: true
enableToggle: true,
toggleGroup: 'leftMenuGroup'
});
this.btnAbout = new Common.UI.Button({
@ -161,7 +166,7 @@ define([
});
this.btnNavigation.on('click', this.onBtnMenuClick.bind(this));
this.btnSearch.on('click', this.onBtnMenuClick.bind(this));
this.btnSearchBar.on('click', this.onBtnMenuClick.bind(this));
this.btnAbout.on('toggle', this.onBtnMenuToggle.bind(this));
this.menuFile = new DE.Views.FileMenu();
@ -188,9 +193,6 @@ define([
btn.panel['show']();
if (!this._state.pluginIsRunning)
this.$el.width(SCALE_MIN);
if (this.btnSearch.isActive())
this.btnSearch.toggle(false);
} else {
btn.panel['hide']();
}
@ -257,6 +259,14 @@ define([
this.panelThumbnails.hide();
}
}
if (this.panelSearch) {
if (this.btnSearchBar.pressed) {
this.panelSearch.show();
this.panelSearch.focus();
} else {
this.panelSearch.hide();
}
}
/** coauthoring end **/
// if (this.mode.canPlugins && this.panelPlugins) {
// if (this.btnPlugins.pressed) {
@ -284,6 +294,9 @@ define([
} else
if (name == 'thumbnails') {
this.panelThumbnails = panel.render('#left-panel-thumbnails');
} else
if (name == 'advancedsearch') {
this.panelSearch = panel.render('#left-panel-search');
}
},
@ -329,6 +342,10 @@ define([
this.panelNavigation['hide']();
this.btnNavigation.toggle(false, true);
}
if (this.panelSearch) {
this.panelSearch['hide']();
this.btnSearchBar.toggle(false, true);
}
if (this.panelThumbnails) {
this.panelThumbnails['hide']();
this.btnThumbnails.toggle(false, true);
@ -337,7 +354,7 @@ define([
},
isOpened: function() {
var isopened = this.btnSearch.pressed;
var isopened = this.btnSearchBar.pressed;
/** coauthoring begin **/
!isopened && (isopened = this.btnComments.pressed || this.btnChat.pressed);
/** coauthoring end **/
@ -345,7 +362,7 @@ define([
},
disableMenu: function(menu, disable) {
this.btnSearch.setDisabled(false);
this.btnSearchBar.setDisabled(false);
this.btnAbout.setDisabled(false);
this.btnSupport.setDisabled(false);
/** coauthoring begin **/
@ -357,7 +374,7 @@ define([
this.btnThumbnails.setDisabled(false);
},
showMenu: function(menu, opts) {
showMenu: function(menu, opts, suspendAfter) {
var re = /^(\w+):?(\w*)$/.exec(menu);
if ( re[1] == 'file' ) {
if ( !this.menuFile.isVisible() ) {
@ -389,6 +406,15 @@ define([
this.onBtnMenuClick(this.btnNavigation);
this.onCoauthOptions();
}
} else if (menu == 'advancedsearch') {
if (this.btnSearchBar.isVisible() &&
!this.btnSearchBar.isDisabled() && !this.btnSearchBar.pressed) {
this.btnSearchBar.toggle(true);
this.onBtnMenuClick(this.btnSearchBar);
this.onCoauthOptions();
this.panelSearch.focus();
!suspendAfter && this.fireEvent('search:aftershow', this);
}
}
/** coauthoring end **/
}

View file

@ -148,6 +148,7 @@ require([
'LeftMenu',
'Main',
'ViewTab',
'Search',
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
@ -181,6 +182,7 @@ require([
'documenteditor/main/app/controller/LeftMenu',
'documenteditor/main/app/controller/Main',
'documenteditor/main/app/controller/ViewTab',
'documenteditor/main/app/controller/Search',
'documenteditor/main/app/view/FileMenuPanels',
'documenteditor/main/app/view/ParagraphSettings',
'documenteditor/main/app/view/HeaderFooterSettings',

View file

@ -200,6 +200,11 @@
"Common.UI.Window.textInformation": "Information",
"Common.UI.Window.textWarning": "Warning",
"Common.UI.Window.yesButtonText": "Yes",
"Common.UI.SearchBar.textFind": "Find",
"Common.UI.SearchBar.tipPreviousResult": "Previous result",
"Common.UI.SearchBar.tipNextResult": "Next result",
"Common.UI.SearchBar.tipOpenAdvancedSettings": "Open advanced settings",
"Common.UI.SearchBar.tipCloseSearch": "Close search",
"Common.Utils.Metric.txtCm": "cm",
"Common.Utils.Metric.txtPt": "pt",
"Common.Views.About.txtAddress": "address: ",
@ -302,6 +307,7 @@
"Common.Views.Header.tipViewUsers": "View users and manage document access rights",
"Common.Views.Header.txtAccessRights": "Change access rights",
"Common.Views.Header.txtRename": "Rename",
"Common.Views.Header.tipSearch": "Search",
"Common.Views.History.textCloseHistory": "Close History",
"Common.Views.History.textHide": "Collapse",
"Common.Views.History.textHideAll": "Hide detailed changes",
@ -507,6 +513,21 @@
"Common.Views.UserNameDialog.textDontShow": "Don't ask me again",
"Common.Views.UserNameDialog.textLabel": "Label:",
"Common.Views.UserNameDialog.textLabelError": "Label must not be empty.",
"Common.Views.SearchPanel.textFind": "Find",
"Common.Views.SearchPanel.textFindAndReplace": "Find and replace",
"Common.Views.SearchPanel.textCloseSearch": "Close search",
"Common.Views.SearchPanel.textReplace": "Replace",
"Common.Views.SearchPanel.textReplaceAll": "Replace All",
"Common.Views.SearchPanel.textSearchResults": "Search results: {0}/{1}",
"Common.Views.SearchPanel.textReplaceWith": "Replace with",
"Common.Views.SearchPanel.textCaseSensitive": "Case sensitive",
"Common.Views.SearchPanel.textMatchUsingRegExp": "Match using regular expressions",
"Common.Views.SearchPanel.textWholeWords": "Whole words only",
"Common.Views.SearchPanel.textNoMatches": "No matches",
"Common.Views.SearchPanel.textNoSearchResults": "No search results",
"Common.Views.SearchPanel.textTooManyResults": "There are too many results to show here",
"Common.Views.SearchPanel.tipPreviousResult": "Previous result",
"Common.Views.SearchPanel.tipNextResult": "Next result",
"DE.Controllers.LeftMenu.leavePageText": "All unsaved changes in this document will be lost.<br> Click \"Cancel\" then \"Save\" to save them. Click \"OK\" to discard all the unsaved changes.",
"DE.Controllers.LeftMenu.newDocumentTitle": "Unnamed document",
"DE.Controllers.LeftMenu.notcriticalErrorTitle": "Warning",
@ -1250,6 +1271,8 @@
"DE.Controllers.Viewport.textFitPage": "Fit to Page",
"DE.Controllers.Viewport.textFitWidth": "Fit to Width",
"DE.Controllers.Viewport.txtDarkMode": "Dark mode",
"DE.Controllers.Search.notcriticalErrorTitle": "Warning",
"DE.Controllers.Search.warnReplaceString": "{0} is not a valid special character for the Replace With box.",
"DE.Views.AddNewCaptionLabelDialog.textLabel": "Label:",
"DE.Views.AddNewCaptionLabelDialog.textLabelError": "Label must not be empty.",
"DE.Views.BookmarksDialog.textAdd": "Add",

View file

@ -250,6 +250,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<!--<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>-->
<div class="item margin-right-small"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>
@ -305,6 +306,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -244,6 +244,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<!--<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>-->
<div class="item margin-right-small"><input id="page-number" class="form-control input-xs masked" type="text" value="0"><span class="text" id="pages" tabindex="-1">of 0</span></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>

View file

@ -72,6 +72,7 @@ PE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -292,6 +293,10 @@ PE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onMouseMoveStart', onDocMouseMoveStart);
api.asc_registerCallback('asc_onMouseMoveEnd', onDocMouseMoveEnd);
api.asc_registerCallback('asc_onMouseMove', onDocMouseMove);
@ -719,6 +724,8 @@ PE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,165 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
$searchBar.hide();
} else {
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(_state.searchText);
searchSettings.put_MatchCase(false);
searchSettings.put_WholeWords(false);
if (!api.asc_findText(searchSettings, d != 'back')) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();

View file

@ -4,6 +4,7 @@
"common.view.modals.txtHeight": "Height",
"common.view.modals.txtShare": "Share Link",
"common.view.modals.txtWidth": "Width",
"common.view.SearchBar.textFind": "Find",
"PE.ApplicationController.convertationErrorText": "Conversion failed.",
"PE.ApplicationController.convertationTimeoutText": "Conversion timeout exceeded.",
"PE.ApplicationController.criticalErrorTitle": "Error",

View file

@ -153,6 +153,7 @@ require([
'LeftMenu',
'Main',
'ViewTab',
'Search',
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
@ -182,6 +183,7 @@ require([
'presentationeditor/main/app/controller/LeftMenu',
'presentationeditor/main/app/controller/Main',
'presentationeditor/main/app/controller/ViewTab',
'presentationeditor/main/app/controller/Search',
'presentationeditor/main/app/view/FileMenuPanels',
'presentationeditor/main/app/view/ParagraphSettings',
'presentationeditor/main/app/view/ImageSettings',

View file

@ -81,8 +81,6 @@ define([
'comments:hide': _.bind(this.commentsShowHide, this, 'hide')
},
'FileMenu': {
'menu:hide': _.bind(this.menuFilesShowHide, this, 'hide'),
'menu:show': _.bind(this.menuFilesShowHide, this, 'show'),
'filemenu:hide': _.bind(this.menuFilesHide, this),
'item:click': _.bind(this.clickMenuFileItem, this),
'saveas:format': _.bind(this.clickSaveAsFormat, this),
@ -97,15 +95,11 @@ define([
'file:close': this.clickToolbarTab.bind(this, 'other'),
'save:disabled' : this.changeToolbarSaveState.bind(this)
},
'SearchDialog': {
'hide': _.bind(this.onSearchDlgHide, this),
'search:back': _.bind(this.onQuerySearch, this, 'back'),
'search:next': _.bind(this.onQuerySearch, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this)
},
'Common.Views.ReviewChanges': {
'collaboration:chat': _.bind(this.onShowHideChat, this)
},
'SearchBar': {
'search:show': _.bind(this.onShowHideSearch, this)
}
});
Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this));
@ -117,9 +111,9 @@ define([
onLaunch: function() {
this.leftMenu = this.createView('LeftMenu').render();
this.leftMenu.btnSearch.on('toggle', _.bind(this.onMenuSearch, this));
this.leftMenu.btnThumbs.on('toggle', _.bind(this.onShowTumbnails, this));
this.isThumbsShown = true;
this.leftMenu.btnSearchBar.on('toggle', _.bind(this.onMenuSearchBar, this));
Common.util.Shortcuts.delegateShortcuts({
shortcuts: {
@ -145,7 +139,6 @@ define([
this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiServerDisconnect, this));
Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiServerDisconnect, this));
this.api.asc_registerCallback('asc_onDownloadUrl', _.bind(this.onDownloadUrl, this));
this.api.asc_registerCallback('asc_onReplaceAll', _.bind(this.onApiTextReplaced, this));
/** coauthoring begin **/
if (this.mode.canCoAuthoring) {
if (this.mode.canChat)
@ -170,6 +163,8 @@ define([
if (this.mode.canUseHistory)
this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode);
this.leftMenu.btnThumbs.toggle(true);
this.getApplication().getController('Search').setApi(this.api).setMode(this.mode);
this.leftMenu.setOptionsPanel('advancedsearch', this.getApplication().getController('Search').getView('Common.Views.SearchPanel'));
return this;
},
@ -447,66 +442,6 @@ define([
},
/** coauthoring end **/
onQuerySearch: function(d, w, opts) {
if (opts.textsearch && opts.textsearch.length) {
var me = this;
this.api.asc_findText(opts.textsearch, d != 'back', opts.matchcase, function(resultCount) {
!resultCount && Common.UI.info({
msg: me.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
});
}
},
onQueryReplace: function(w, opts) {
if (!_.isEmpty(opts.textsearch)) {
if (!this.api.asc_replaceText(opts.textsearch, opts.textreplace, false, opts.matchcase)) {
var me = this;
Common.UI.info({
msg: this.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
}
}
},
onQueryReplaceAll: function(w, opts) {
if (!_.isEmpty(opts.textsearch)) {
this.api.asc_replaceText(opts.textsearch, opts.textreplace, true, opts.matchcase);
}
},
showSearchDlg: function(show,action) {
if ( !this.dlgSearch ) {
this.dlgSearch = (new Common.UI.SearchDialog({
matchcase: true
}));
var me = this;
Common.NotificationCenter.on('preview:start', function() {
me.dlgSearch.hide();
});
}
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? (action || undefined) : 'no-replace';
if (this.dlgSearch.isVisible()) {
this.dlgSearch.setMode(mode);
this.dlgSearch.focus();
} else {
this.dlgSearch.show(mode);
}
} else this.dlgSearch['hide']();
},
onMenuSearch: function(obj, show) {
this.showSearchDlg(show);
},
onShowTumbnails: function(obj, show) {
this.api.ShowThumbnails(show);
@ -520,29 +455,11 @@ define([
this.isThumbsShown = isShow;
},
onSearchDlgHide: function() {
this.leftMenu.btnSearch.toggle(false, true);
$(this.leftMenu.btnSearch.el).blur();
this.api.asc_enableKeyEvents(true);
// this.api.asc_selectSearchingResults(false);
},
onApiTextReplaced: function(found,replaced) {
var me = this;
if (found) {
!(found - replaced > 0) ?
Common.UI.info( {msg: Common.Utils.String.format(this.textReplaceSuccess, replaced)} ) :
Common.UI.warning( {msg: Common.Utils.String.format(this.textReplaceSkipped, found-replaced)} );
} else {
Common.UI.info({msg: this.textNoTextFound});
}
},
setPreviewMode: function(mode) {
if (this.viewmode === mode) return;
this.viewmode = mode;
this.dlgSearch && this.dlgSearch.setMode(this.viewmode ? 'no-replace' : 'search');
this.leftMenu.panelSearch && this.leftMenu.panelSearch.setSearchMode(this.viewmode ? 'no-replace' : 'search');
},
onApiServerDisconnect: function(enableDownload) {
@ -556,10 +473,6 @@ define([
this.leftMenu.btnPlugins.setDisabled(true);
this.leftMenu.getMenu('file').setMode({isDisconnected: true, enableDownload: !!enableDownload});
if ( this.dlgSearch ) {
this.leftMenu.btnSearch.toggle(false, true);
this.dlgSearch['hide']();
}
},
onApiCountPages: function(count) {
@ -631,15 +544,6 @@ define([
}
},
menuFilesShowHide: function(state) {
if ( this.dlgSearch ) {
if ( state == 'show' )
this.dlgSearch.suspendKeyEvents();
else
Common.Utils.asyncCall(this.dlgSearch.resumeKeyEvents, this.dlgSearch);
}
},
onShortcut: function(s, e) {
if (!this.mode) return;
@ -651,10 +555,33 @@ define([
if ((!previewPanel || !previewPanel.isVisible()) && !this._state.no_slides) {
Common.UI.Menu.Manager.hideAll();
var full_menu_pressed = this.leftMenu.btnAbout.pressed;
this.showSearchDlg(true,s);
this.leftMenu.btnSearch.toggle(true,true);
this.leftMenu.btnAbout.toggle(false);
full_menu_pressed && this.menuExpand(this.leftMenu.btnAbout, 'files', false);
var selectedText = this.api.asc_GetSelectedText();
if (this.isSearchPanelVisible()) {
selectedText && this.leftMenu.panelSearch.setFindText(selectedText);
this.leftMenu.panelSearch.focus(selectedText !== '' ? s : 'search');
this.leftMenu.fireEvent('search:aftershow', this.leftMenu, selectedText);
return false;
} else if (this.getApplication().getController('Viewport').isSearchBarVisible()) {
var viewport = this.getApplication().getController('Viewport');
if (s === 'replace') {
viewport.header.btnSearch.toggle(false);
this.onShowHideSearch(true, viewport.searchBar.inputSearch.val());
} else {
selectedText && viewport.searchBar.setText(selectedText);
viewport.searchBar.focus();
return false;
}
} else if (s === 'search') {
Common.NotificationCenter.trigger('search:show');
return false;
} else {
this.onShowHideSearch(true, selectedText);
}
this.leftMenu.btnSearchBar.toggle(true,true);
this.leftMenu.panelSearch.focus(s);
}
return false;
case 'save':
@ -685,6 +612,10 @@ define([
return false;
case 'escape':
// if (!this.leftMenu.isOpened()) return true;
var btnSearch = this.getApplication().getController('Viewport').header.btnSearch;
btnSearch.pressed && btnSearch.toggle(false);
this.leftMenu._state.isSearchOpen && (this.leftMenu._state.isSearchOpen = false);
// TODO:
if ( this.leftMenu.menuFile.isVisible() ) {
if (Common.UI.HintManager.needCloseFileMenu())
@ -758,6 +689,9 @@ define([
// focus to sdk
this.api.asc_enableKeyEvents(true);
} else if (this.leftMenu.btnSearchBar.isActive()) {
this.leftMenu.btnSearchBar.toggle(false);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
}
},
@ -774,6 +708,29 @@ define([
}
},
onShowHideSearch: function (state, findText) {
if (state) {
Common.UI.Menu.Manager.hideAll();
this.leftMenu.showMenu('advancedsearch', undefined, true);
this.leftMenu.fireEvent('search:aftershow', this.leftMenu, findText);
} else {
this.leftMenu.btnSearchBar.toggle(false, true);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
},
onMenuSearchBar: function(obj, show) {
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? undefined : 'no-replace';
this.leftMenu.panelSearch.setSearchMode(mode);
}
this.leftMenu._state.isSearchOpen = show;
},
isSearchPanelVisible: function () {
return this.leftMenu._state.isSearchOpen;
},
showHistory: function() {
if (!this.mode.wopi) {
var maincontroller = PE.getController('Main');

View file

@ -0,0 +1,380 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* ViewTab.js
*
* Created by Julia Svinareva on 25.02.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
define([
'core',
'common/main/lib/view/SearchPanel'
], function () {
'use strict';
PE.Controllers.Search = Backbone.Controller.extend(_.extend({
sdkViewName : '#id_main',
views: [
'Common.Views.SearchPanel'
],
initialize: function () {
this.addListeners({
'SearchBar': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:input': _.bind(this.onInputSearchChange, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown')
},
'Common.Views.SearchPanel': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this),
'search:input': _.bind(this.onInputSearchChange, this),
'search:options': _.bind(this.onChangeSearchOption, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown'),
'show': _.bind(this.onShowPanel, this),
'hide': _.bind(this.onHidePanel, this),
},
'LeftMenu': {
'search:aftershow': _.bind(this.onShowAfterSearch, this)
}
});
},
onLaunch: function () {
this._state = {
searchText: '',
matchCase: false,
matchWord: false,
useRegExp: false
};
},
setMode: function (mode) {
this.view = this.createView('Common.Views.SearchPanel', { mode: mode });
},
setApi: function (api) {
if (api) {
this.api = api;
this.api.asc_registerCallback('asc_onSetSearchCurrent', _.bind(this.onUpdateSearchCurrent, this));
this.api.asc_registerCallback('asc_onStartTextAroundSearch', _.bind(this.onStartTextAroundSearch, this));
this.api.asc_registerCallback('asc_onEndTextAroundSearch', _.bind(this.onEndTextAroundSearch, this));
this.api.asc_registerCallback('asc_onGetTextAroundSearchPack', _.bind(this.onApiGetTextAroundSearch, this));
this.api.asc_registerCallback('asc_onRemoveTextAroundSearch', _.bind(this.onApiRemoveTextAroundSearch, this));
}
return this;
},
getView: function(name) {
return !name && this.view ?
this.view : Backbone.Controller.prototype.getView.call(this, name);
},
onChangeSearchOption: function (option, checked) {
switch (option) {
case 'case-sensitive':
this._state.matchCase = checked;
break;
case 'match-word':
this._state.matchWord = checked;
break;
case 'regexp':
this._state.useRegExp = checked;
break;
}
if (this._state.searchText !== '') {
this.hideResults();
if (this.onQuerySearch()) {
if (this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = undefined;
}
this.api.asc_StartTextAroundSearch();
}
}
},
onSearchNext: function (type, text, e) {
var isReturnKey = type === 'keydown' && e.keyCode === Common.UI.Keys.RETURN;
if (text && text.length > 0 && (isReturnKey || type !== 'keydown')) {
this._state.searchText = text;
if (this.onQuerySearch(type) && (this.searchTimer || isReturnKey)) {
this.hideResults();
if (this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = undefined;
}
if (this.view.$el.is(':visible')) {
this.api.asc_StartTextAroundSearch();
}
}
}
},
onInputSearchChange: function (text) {
var me = this;
if (this._state.searchText !== text) {
this._state.newSearchText = text;
this._lastInputChange = (new Date());
if (this.searchTimer === undefined) {
this.searchTimer = setInterval(function(){
if ((new Date()) - me._lastInputChange < 400) return;
me.hideResults();
me._state.searchText = me._state.newSearchText;
if (me._state.newSearchText !== '' && me.onQuerySearch()) {
if (me.view.$el.is(':visible')) {
me.api.asc_StartTextAroundSearch();
}
me.view.disableReplaceButtons(false);
} else if (me._state.newSearchText === '') {
me.view.updateResultsNumber('no-results');
me.view.disableReplaceButtons(true);
}
clearInterval(me.searchTimer);
me.searchTimer = undefined;
}, 10);
}
}
},
onQuerySearch: function (d, w) {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(this._state.searchText);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
if (!this.api.asc_findText(searchSettings, d != 'back')) {
this.resultItems = [];
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
return false;
}
return true;
},
onQueryReplace: function(textSearch, textReplace) {
if (textSearch !== '') {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(textSearch);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
if (!this.api.asc_replaceText(searchSettings, textReplace, false)) {
this.allResultsWasRemoved();
}
}
},
onQueryReplaceAll: function(textSearch, textReplace) {
if (textSearch !== '') {
var searchSettings = new AscCommon.CSearchSettings();
searchSettings.put_Text(textSearch);
searchSettings.put_MatchCase(this._state.matchCase);
searchSettings.put_WholeWords(this._state.matchWord);
this.api.asc_replaceText(searchSettings, textReplace, true);
this.allResultsWasRemoved();
}
},
allResultsWasRemoved: function () {
this.resultItems = [];
this.hideResults();
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
},
onUpdateSearchCurrent: function (current, all) {
if (current === -1) return;
this._state.currentResult = current;
this._state.resultsNumber = all;
if (this.view) {
this.view.updateResultsNumber(current, all);
this.view.disableNavButtons(current, all);
if (this.resultItems && this.resultItems.length > 0) {
this.resultItems.forEach(function (item) {
item.selected = false;
});
if (this.resultItems[current]) {
this.resultItems[current].selected = true;
$('#search-results').find('.item').removeClass('selected');
$(this.resultItems[current].el).addClass('selected');
this.scrollToSelectedResult(current);
}
}
}
Common.NotificationCenter.trigger('search:updateresults', current, all);
},
scrollToSelectedResult: function (ind) {
var index = ind !== undefined ? ind : _.findIndex(this.resultItems, {selected: true});
if (index !== -1) {
var item = this.resultItems[index].$el,
itemHeight = item.outerHeight(),
itemTop = item.position().top,
container = this.view.$resultsContainer,
containerHeight = container.outerHeight(),
containerTop = container.scrollTop();
if (itemTop < 0 || (containerTop === 0 && itemTop > containerHeight)) {
container.scroller.scrollTop(containerTop + itemTop - 12);
} else if (itemTop + itemHeight > containerHeight) {
container.scroller.scrollTop(containerTop + itemHeight);
}
}
},
onStartTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = true;
}
},
onEndTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = false;
this.view.$resultsContainer.scroller.update({alwaysVisibleY: true});
}
},
onApiGetTextAroundSearch: function (data) {
if (this.view && this._state.isStartedAddingResults) {
if (data.length > 300 || !data.length) return;
var me = this;
me.resultItems = [];
data.forEach(function (item, ind) {
var el = document.createElement("div"),
isSelected = ind === me._state.currentResult;
el.className = 'item';
el.innerHTML = item[1].trim();
me.view.$resultsContainer.append(el);
if (isSelected) {
$(el).addClass('selected');
}
var resultItem = {id: item[0], $el: $(el), el: el, selected: isSelected};
me.resultItems.push(resultItem);
$(el).on('click', _.bind(function (el) {
var id = item[0];
me.api.asc_SelectSearchElement(id);
}, me));
});
this.view.$resultsContainer.show();
}
},
onApiRemoveTextAroundSearch: function (arr) {
var me = this;
arr.forEach(function (id) {
var ind = _.findIndex(me.resultItems, {id: id});
if (ind !== -1) {
me.resultItems[ind].$el.remove();
me.resultItems.splice(ind, 1);
}
});
},
hideResults: function () {
if (this.view) {
this.view.$resultsContainer.hide();
this.view.$resultsContainer.empty();
}
},
onShowAfterSearch: function (findText) {
var viewport = this.getApplication().getController('Viewport');
if (viewport.isSearchBarVisible()) {
viewport.searchBar.hide();
}
var text = typeof findText === 'string' ? findText : (this.api.asc_GetSelectedText() || this._state.searchText);
if (text) {
this.view.setFindText(text);
} else if (text !== undefined) { // panel was opened from empty searchbar, clear to start new search
this.view.setFindText('');
this._state.searchText = undefined;
}
this.hideResults();
if (text !== '' && text === this._state.searchText) { // search was made
this.view.disableReplaceButtons(false);
this.api.asc_StartTextAroundSearch();
} else if (text !== '') { // search wasn't made
this.onInputSearchChange(text);
} else {
this.resultItems = [];
this.view.disableReplaceButtons(true);
this.view.clearResultsNumber();
}
this.view.disableNavButtons(this._state.currentResult, this._state.resultsNumber);
},
onShowPanel: function () {
if (this.resultItems && this.resultItems.length > 0 && !this._state.isStartedAddingResults) {
var me = this;
this.view.$resultsContainer.show();
this.resultItems.forEach(function (item) {
me.view.$resultsContainer.append(item.el);
if (item.selected) {
$(item.el).addClass('selected');
}
$(item.el).on('click', function (el) {
me.api.asc_SelectSearchElement(item.id);
$('#search-results').find('.item').removeClass('selected');
$(el.currentTarget).addClass('selected');
});
});
this.scrollToSelectedResult();
}
},
onHidePanel: function () {
this.hideResults();
},
notcriticalErrorTitle: 'Warning',
warnReplaceString: '{0} is not a valid special character for the Replace With box.'
}, PE.Controllers.Search || {}));
});

View file

@ -43,6 +43,7 @@
define([
'core',
'common/main/lib/view/Header',
'common/main/lib/view/SearchBar',
'presentationeditor/main/app/view/DocumentPreview',
'presentationeditor/main/app/view/Viewport'
// 'documenteditor/main/app/view/LeftMenu'
@ -152,6 +153,7 @@ define([
Common.NotificationCenter.on('app:face', this.onAppShowed.bind(this));
Common.NotificationCenter.on('app:ready', this.onAppReady.bind(this));
Common.NotificationCenter.on('search:show', _.bind(this.onSearchShow, this));
},
onAppShowed: function (config) {
@ -324,6 +326,39 @@ define([
this.header && this.header.lockHeaderBtns( 'rename-user', disable);
},
onNotesShow: function(bIsShow) {
this.header && this.header.mnuitemHideNotes.setChecked(!bIsShow, true);
Common.localStorage.setBool('pe-hidden-notes', !bIsShow);
},
onSearchShow: function () {
this.header.btnSearch && this.header.btnSearch.toggle(true);
},
onSearchToggle: function () {
var leftMenu = this.getApplication().getController('LeftMenu');
if (leftMenu.isSearchPanelVisible()) {
this.header.btnSearch.toggle(false, true);
leftMenu.getView('LeftMenu').panelSearch.focus();
return;
}
if (!this.searchBar) {
this.searchBar = new Common.UI.SearchBar({});
this.searchBar.on('hide', _.bind(function () {
this.header.btnSearch.toggle(false, true);
}, this));
}
if (this.header.btnSearch.pressed) {
this.searchBar.show(this.api.asc_GetSelectedText());
} else {
this.searchBar.hide();
}
},
isSearchBarVisible: function () {
return this.searchBar && this.searchBar.isVisible();
},
textFitPage: 'Fit to Page',
textFitWidth: 'Fit to Width'
}, PE.Controllers.Viewport));

View file

@ -1,6 +1,6 @@
<div id="view-left-menu" class="tool-menu left">
<div class="tool-menu-btns">
<button id="left-btn-search" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target=""><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<button id="left-btn-searchbar" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-search"><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<button id="left-btn-thumbs" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target=""><i class="icon toolbar__icon btn-menu-thumbs">&nbsp;</i></button>
<!-- /** coauthoring begin **/ -->
<button id="left-btn-comments" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-comments"><i class="icon toolbar__icon btn-menu-comments">&nbsp;</i></button>
@ -11,6 +11,7 @@
<button id="left-btn-about" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target=""><i class="icon toolbar__icon btn-menu-about">&nbsp;</i></button>
</div>
<div class="left-panel" style="">
<div id="left-panel-search" class="" style="display: none;"></div>
<!-- /** coauthoring begin **/ -->
<div id="left-panel-comments" class="" style="display: none;"></div>
<div id="left-panel-chat" class="" style="display: none;"></div>

View file

@ -72,6 +72,10 @@ define([
'click #left-btn-chat': _.bind(this.onCoauthOptions, this),
'click #left-btn-plugins': _.bind(this.onCoauthOptions, this),
/** coauthoring end **/
'click #left-btn-searchbar': _.bind(function () {
this.onCoauthOptions();
this.fireEvent('search:aftershow', this.leftMenu);
}, this),
'click #left-btn-support': function() {
var config = this.mode.customization;
config && !!config.feedback && !!config.feedback.url ?
@ -89,12 +93,13 @@ define([
render: function () {
var $markup = $(this.template({}));
this.btnSearch = new Common.UI.Button({
action: 'search',
el: $markup.elementById('#left-btn-search'),
hint: this.tipSearch + Common.Utils.String.platformKey('Ctrl+F'),
this.btnSearchBar = new Common.UI.Button({
action: 'advancedsearch',
el: $markup.elementById('#left-btn-searchbar'),
hint: this.tipSearch,
disabled: true,
enableToggle: true
enableToggle: true,
toggleGroup: 'leftMenuGroup'
});
this.btnThumbs = new Common.UI.Button({
@ -155,8 +160,7 @@ define([
});
this.btnPlugins.hide();
this.btnPlugins.on('click', _.bind(this.onBtnMenuClick, this));
this.btnSearch.on('click', _.bind(this.onBtnMenuClick, this));
this.btnSearchBar.on('click', _.bind(this.onBtnMenuClick, this));
this.btnThumbs.on('click', _.bind(this.onBtnMenuClick, this));
this.btnAbout.on('toggle', _.bind(this.onBtnMenuToggle, this));
this.btnAbout.on('click', _.bind(this.onFullMenuClick, this));
@ -173,9 +177,6 @@ define([
btn.panel['show']();
if (!this._state.pluginIsRunning)
this.$el.width(SCALE_MIN);
if (this.btnSearch.isActive())
this.btnSearch.toggle(false);
} else {
btn.panel['hide']();
}
@ -241,6 +242,14 @@ define([
}
}
/** coauthoring end **/
if (this.panelSearch) {
if (this.btnSearchBar.pressed) {
this.panelSearch.show();
this.panelSearch.focus()
} else {
this.panelSearch.hide();
}
}
// if (this.mode.canPlugins && this.panelPlugins) {
// if (this.btnPlugins.pressed) {
// this.panelPlugins.show();
@ -260,6 +269,9 @@ define([
this.panelPlugins = panel.render('#left-panel-plugins');
} else if (name == 'history') {
this.panelHistory = panel.render('#left-panel-history');
} else
if (name == 'advancedsearch') {
this.panelSearch = panel.render('#left-panel-search');
}
},
@ -299,11 +311,15 @@ define([
this.panelPlugins['hide']();
this.btnPlugins.toggle(false, true);
}
if (this.panelSearch) {
this.panelSearch['hide']();
this.btnSearchBar.toggle(false, true);
}
this.fireEvent('panel:show', [this, '', false]);
},
isOpened: function() {
var isopened = this.btnSearch.pressed;
var isopened = this.btnSearchBar.pressed;
/** coauthoring begin **/
!isopened && (isopened = this.btnComments.pressed || this.btnChat.pressed);
/** coauthoring end **/
@ -311,6 +327,7 @@ define([
},
disableMenu: function(menu, disable) {
this.btnSearchBar.setDisabled(disable);
this.btnThumbs.setDisabled(disable);
this.btnAbout.setDisabled(disable);
this.btnSupport.setDisabled(disable);
@ -320,7 +337,7 @@ define([
this.btnPlugins.setDisabled(disable);
},
showMenu: function(menu, opts) {
showMenu: function(menu, opts, suspendAfter) {
var re = /^(\w+):?(\w*)$/.exec(menu);
if ( re[1] == 'file' ) {
this.menuFile.show(re[2].length ? re[2] : undefined, opts);
@ -342,6 +359,14 @@ define([
this.onBtnMenuClick(this.btnComments);
this.onCoauthOptions();
}
} else if (menu == 'advancedsearch') {
if (this.btnSearchBar.isVisible() &&
!this.btnSearchBar.isDisabled() && !this.btnSearchBar.pressed) {
this.btnSearchBar.toggle(true);
this.onBtnMenuClick(this.btnSearchBar);
this.onCoauthOptions();
!suspendAfter && this.fireEvent('search:aftershow', this);
}
}
/** coauthoring end **/
}

View file

@ -144,6 +144,7 @@ require([
'LeftMenu',
'Main',
'ViewTab',
'Search',
'Common.Controllers.Fonts',
'Common.Controllers.History'
/** coauthoring begin **/
@ -173,6 +174,7 @@ require([
'presentationeditor/main/app/controller/LeftMenu',
'presentationeditor/main/app/controller/Main',
'presentationeditor/main/app/controller/ViewTab',
'presentationeditor/main/app/controller/Search',
'presentationeditor/main/app/view/FileMenuPanels',
'presentationeditor/main/app/view/ParagraphSettings',
'presentationeditor/main/app/view/ImageSettings',

View file

@ -287,6 +287,11 @@
"Common.UI.Window.textInformation": "Information",
"Common.UI.Window.textWarning": "Warning",
"Common.UI.Window.yesButtonText": "Yes",
"Common.UI.SearchBar.textFind": "Find",
"Common.UI.SearchBar.tipPreviousResult": "Previous result",
"Common.UI.SearchBar.tipNextResult": "Next result",
"Common.UI.SearchBar.tipOpenAdvancedSettings": "Open advanced settings",
"Common.UI.SearchBar.tipCloseSearch": "Close search",
"Common.Utils.Metric.txtCm": "cm",
"Common.Utils.Metric.txtPt": "pt",
"Common.Views.About.txtAddress": "address: ",
@ -392,6 +397,7 @@
"Common.Views.Header.tipViewUsers": "View users and manage document access rights",
"Common.Views.Header.txtAccessRights": "Change access rights",
"Common.Views.Header.txtRename": "Rename",
"Common.Views.Header.tipSearch": "Search",
"Common.Views.History.textCloseHistory": "Close History",
"Common.Views.History.textHide": "Collapse",
"Common.Views.History.textHideAll": "Hide detailed changes",
@ -580,6 +586,21 @@
"Common.Views.UserNameDialog.textDontShow": "Don't ask me again",
"Common.Views.UserNameDialog.textLabel": "Label:",
"Common.Views.UserNameDialog.textLabelError": "Label must not be empty.",
"Common.Views.SearchPanel.textFind": "Find",
"Common.Views.SearchPanel.textFindAndReplace": "Find and replace",
"Common.Views.SearchPanel.textCloseSearch": "Close search",
"Common.Views.SearchPanel.textReplace": "Replace",
"Common.Views.SearchPanel.textReplaceAll": "Replace All",
"Common.Views.SearchPanel.textSearchResults": "Search results: {0}/{1}",
"Common.Views.SearchPanel.textReplaceWith": "Replace with",
"Common.Views.SearchPanel.textCaseSensitive": "Case sensitive",
"Common.Views.SearchPanel.textMatchUsingRegExp": "Match using regular expressions",
"Common.Views.SearchPanel.textWholeWords": "Whole words only",
"Common.Views.SearchPanel.textNoMatches": "No matches",
"Common.Views.SearchPanel.textNoSearchResults": "No search results",
"Common.Views.SearchPanel.textTooManyResults": "There are too many results to show here",
"Common.Views.SearchPanel.tipPreviousResult": "Previous result",
"Common.Views.SearchPanel.tipNextResult": "Next result",
"del_PE.Views.FileMenuPanels.Settings.strAutoRecover": "Turn on autorecover",
"PE.Controllers.LeftMenu.leavePageText": "All unsaved changes in this document will be lost.<br> Click \"Cancel\" then \"Save\" to save them. Click \"OK\" to discard all the unsaved changes.",
"PE.Controllers.LeftMenu.newDocumentTitle": "Unnamed presentation",
@ -1299,6 +1320,8 @@
"PE.Controllers.Toolbar.txtSymbol_zeta": "Zeta",
"PE.Controllers.Viewport.textFitPage": "Fit to Slide",
"PE.Controllers.Viewport.textFitWidth": "Fit to Width",
"PE.Controllers.Search.notcriticalErrorTitle": "Warning",
"PE.Controllers.Search.warnReplaceString": "{0} is not a valid special character for the Replace With box.",
"PE.Views.Animation.str0_5": "0.5 s (Very Fast)",
"PE.Views.Animation.str1": "1 s (Fast)",
"PE.Views.Animation.str2": "2 s (Medium)",

View file

@ -224,6 +224,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>
</div>
@ -282,6 +283,8 @@
<script type="text/javascript" src="../../common/embed/lib/view/LoadMask.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/controller/modals.js"></script>
<script type="text/javascript" src="../../common/embed/lib/view/SearchBar.js"></script>
<script type="text/javascript" src="js/SearchBar.js"></script>
<script type="text/javascript" src="js/ApplicationView.js"></script>
<script type="text/javascript" src="js/ApplicationController.js"></script>
<script type="text/javascript" src="js/application.js"></script>

View file

@ -216,6 +216,7 @@
<span id="title-doc-name"></span>
</div>
<div class="group right">
<div id="id-search" style="display: inline-block;"><button class="control-btn svg-icon search"></button></div>
<div id="box-tools" class="dropdown">
<button class="control-btn svg-icon more-vertical"></button>
</div>

View file

@ -74,6 +74,7 @@ SSE.ApplicationController = new(function(){
embedConfig = $.extend(embedConfig, data.config.embedded);
common.controller.modals.init(embedConfig);
common.controller.SearchBar.init(embedConfig);
// Docked toolbar
if (embedConfig.toolbarDocked === 'bottom') {
@ -238,6 +239,10 @@ SSE.ApplicationController = new(function(){
embed: '#idt-embed'
});
common.controller.SearchBar.attach({
search: '#id-search'
});
api.asc_registerCallback('asc_onMouseMove', onApiMouseMove);
api.asc_registerCallback('asc_onHyperlinkClick', common.utils.openLink);
api.asc_registerCallback('asc_onDownloadUrl', onDownloadUrl);
@ -672,6 +677,8 @@ SSE.ApplicationController = new(function(){
Common.Gateway.on('opendocument', loadDocument);
Common.Gateway.on('showmessage', onExternalMessage);
Common.Gateway.appReady();
common.controller.SearchBar.setApi(api);
}
return me;

View file

@ -0,0 +1,179 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* SearchBar.js
*
* Created by Julia Svinareva on 27.04.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
+function () {
!window.common && (window.common = {});
!common.controller && (common.controller = {});
common.controller.SearchBar = new(function() {
var $searchBar,
$searchBtn,
$searchInput,
appConfig,
api,
_state = {
searchText: ''
},
_lastInputChange,
_searchTimer;
var setApi = function (appApi) {
api = appApi;
if (api) {
api.asc_registerCallback('asc_onSetSearchCurrent', onApiUpdateSearchCurrent);
}
};
var create = function () {
$searchBar = common.view.SearchBar.create();
if (appConfig.toolbarDocked === 'bottom') {
$searchBar.css({'right': '45px', 'bottom': '31px'});
} else {
$searchBar.css({'right': '45px', 'top': '31px'});
}
$searchInput = $searchBar.find('#search-bar-text');
$searchInput.on('input', function(e){
common.view.SearchBar.disableNavButtons();
onInputSearchChange($searchInput.val());
}).on('keydown', function (e) {
onSearchNext('keydown', $searchInput.val(), e);
});
$searchBar.find('#search-bar-back').on('click', function(e){
onSearchNext('back', $searchInput.val());
});
$searchBar.find('#search-bar-next').on('click', function(e){
onSearchNext('next', $searchInput.val());
});
$searchBar.find('#search-bar-close').on('click', function(e){
highlightResults(false);
$searchBar.hide();
$searchBtn.find('button').button('toggle');
});
common.view.SearchBar.disableNavButtons();
};
var attachToView = function(config) {
if ( !$searchBar ) {
create();
}
$searchBtn = $(config.search);
$searchBtn.on('click', function(e){
if ($searchBar.is(':visible')) {
highlightResults(false);
$searchBar.hide();
} else {
highlightResults(true);
var text = (api && api.asc_GetSelectedText()) || _state.searchText;
$searchInput.val(text);
(text.length > 0) && onInputSearchChange(text);
$searchBar.show();
$searchInput.focus();
$searchInput.select();
}
$searchBtn.find('button').button('toggle');
});
};
var onInputSearchChange = function (text) {
if (_state.searchText !== text) {
_state.newSearchText = text;
_lastInputChange = (new Date());
if (_searchTimer === undefined) {
_searchTimer = setInterval(function() {
if ((new Date()) - _lastInputChange < 400) return;
_state.searchText = _state.newSearchText;
(_state.newSearchText !== '') && onQuerySearch();
clearInterval(_searchTimer);
_searchTimer = undefined;
}, 10);
}
}
};
var onQuerySearch = function (d, w) {
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(_state.searchText);
options.asc_setScanForward(d != 'back');
options.asc_setIsMatchCase(false);
options.asc_setIsWholeCell(false);
options.asc_setScanOnOnlySheet(Asc.c_oAscSearchBy.Sheet);
options.asc_setScanByRows(true);
options.asc_setLookIn(Asc.c_oAscFindLookIn.Formulas);
if (!api.asc_findText(options)) {
common.view.SearchBar.disableNavButtons();
return false;
}
return true;
};
var onSearchNext = function (type, text, e) {
if (text && text.length > 0 && (type === 'keydown' && e.keyCode === 13 || type !== 'keydown')) {
_state.searchText = text;
if (onQuerySearch(type) && _searchTimer) {
clearInterval(_searchTimer);
_searchTimer = undefined;
}
}
};
var onApiUpdateSearchCurrent = function (current, all) {
common.view.SearchBar.disableNavButtons(current, all);
};
var highlightResults = function (val) {
if (_state.isHighlightedResults !== val) {
api.asc_selectSearchingResults(val);
_state.isHighlightedResults = val;
}
};
return {
init: function(config) { appConfig = config; },
attach: attachToView,
setApi: setApi
};
});
}();

View file

@ -4,6 +4,7 @@
"common.view.modals.txtHeight": "Height",
"common.view.modals.txtShare": "Share Link",
"common.view.modals.txtWidth": "Width",
"common.view.SearchBar.textFind": "Find",
"SSE.ApplicationController.convertationErrorText": "Conversion failed.",
"SSE.ApplicationController.convertationTimeoutText": "Conversion timeout exceeded.",
"SSE.ApplicationController.criticalErrorTitle": "Error",

View file

@ -159,6 +159,7 @@ require([
'PivotTable',
'DataTab',
'ViewTab',
'Search',
'WBProtection',
'Common.Controllers.Fonts',
'Common.Controllers.History',
@ -189,6 +190,7 @@ require([
'spreadsheeteditor/main/app/controller/PivotTable',
'spreadsheeteditor/main/app/controller/DataTab',
'spreadsheeteditor/main/app/controller/ViewTab',
'spreadsheeteditor/main/app/controller/Search',
'spreadsheeteditor/main/app/controller/WBProtection',
'spreadsheeteditor/main/app/view/FileMenuPanels',
'spreadsheeteditor/main/app/view/ParagraphSettings',

View file

@ -88,16 +88,11 @@ define([
'file:close': this.clickToolbarTab.bind(this, 'other'),
'save:disabled' : this.changeToolbarSaveState.bind(this)
},
'SearchDialog': {
'hide': _.bind(this.onSearchDlgHide, this),
'search:back': _.bind(this.onQuerySearch, this, 'back'),
'search:next': _.bind(this.onQuerySearch, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this),
'search:highlight': _.bind(this.onSearchHighlight, this)
},
'Common.Views.ReviewChanges': {
'collaboration:chat': _.bind(this.onShowHideChat, this)
},
'SearchBar': {
'search:show': _.bind(this.onShowHideSearch, this)
}
});
Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this));
@ -111,7 +106,7 @@ define([
onLaunch: function() {
this.leftMenu = this.createView('LeftMenu').render();
this.leftMenu.btnSearch.on('toggle', _.bind(this.onMenuSearch, this));
this.leftMenu.btnSearchBar.on('toggle', _.bind(this.onMenuSearchBar, this));
Common.util.Shortcuts.delegateShortcuts({
shortcuts: {
@ -149,7 +144,6 @@ define([
setApi: function(api) {
this.api = api;
this.api.asc_registerCallback('asc_onRenameCellTextEnd', _.bind(this.onRenameText, this));
this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiServerDisconnect, this));
Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiServerDisconnect, this));
this.api.asc_registerCallback('asc_onDownloadUrl', _.bind(this.onDownloadUrl, this));
@ -181,6 +175,8 @@ define([
this.leftMenu.getMenu('file').setApi(api);
if (this.mode.canUseHistory)
this.getApplication().getController('Common.Controllers.History').setApi(this.api).setMode(this.mode);
this.getApplication().getController('Search').setApi(this.api).setMode(this.mode);
this.leftMenu.setOptionsPanel('advancedsearch', this.getApplication().getController('Search').getView('Common.Views.SearchPanel'));
return this;
},
@ -558,201 +554,11 @@ define([
},
/** coauthoring end **/
onQuerySearch: function(d, w, opts) {
// if (opts.textsearch && opts.textsearch.length) {
var options = this.dlgSearch.findOptions;
options.asc_setFindWhat(opts.textsearch);
options.asc_setScanForward(d != 'back');
options.asc_setIsMatchCase(opts.matchcase);
options.asc_setIsWholeCell(opts.matchword);
options.asc_setScanOnOnlySheet(this.dlgSearch.menuWithin.menu.items[0].checked);
options.asc_setScanByRows(this.dlgSearch.menuSearch.menu.items[0].checked);
options.asc_setLookIn(this.dlgSearch.menuLookin.menu.items[0].checked?Asc.c_oAscFindLookIn.Formulas:Asc.c_oAscFindLookIn.Value);
var me = this;
this.api.asc_findText(options, function(resultCount) {
!resultCount && Common.UI.info({
msg: me.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
});
// }
},
onQueryReplace: function(w, opts) {
// if (!_.isEmpty(opts.textsearch)) {
this.api.isReplaceAll = false;
var options = this.dlgSearch.findOptions;
options.asc_setFindWhat(opts.textsearch);
options.asc_setReplaceWith(opts.textreplace);
options.asc_setIsMatchCase(opts.matchcase);
options.asc_setIsWholeCell(opts.matchword);
options.asc_setScanOnOnlySheet(this.dlgSearch.menuWithin.menu.items[0].checked);
options.asc_setScanByRows(this.dlgSearch.menuSearch.menu.items[0].checked);
options.asc_setLookIn(this.dlgSearch.menuLookin.menu.items[0].checked?Asc.c_oAscFindLookIn.Formulas:Asc.c_oAscFindLookIn.Value);
options.asc_setIsReplaceAll(false);
this.api.asc_replaceText(options);
// }
},
onQueryReplaceAll: function(w, opts) {
// if (!_.isEmpty(opts.textsearch)) {
this.api.isReplaceAll = true;
var options = this.dlgSearch.findOptions;
options.asc_setFindWhat(opts.textsearch);
options.asc_setReplaceWith(opts.textreplace);
options.asc_setIsMatchCase(opts.matchcase);
options.asc_setIsWholeCell(opts.matchword);
options.asc_setScanOnOnlySheet(this.dlgSearch.menuWithin.menu.items[0].checked);
options.asc_setScanByRows(this.dlgSearch.menuSearch.menu.items[0].checked);
options.asc_setLookIn(this.dlgSearch.menuLookin.menu.items[0].checked?Asc.c_oAscFindLookIn.Formulas:Asc.c_oAscFindLookIn.Value);
options.asc_setIsReplaceAll(true);
this.api.asc_replaceText(options);
// }
},
onSearchHighlight: function(w, highlight) {
this.api.asc_selectSearchingResults(highlight);
},
showSearchDlg: function(show,action) {
if ( !this.dlgSearch ) {
var menuWithin = new Common.UI.MenuItem({
caption : this.textWithin,
menu : new Common.UI.Menu({
menuAlign : 'tl-tr',
items : [{
caption : this.textSheet,
toggleGroup : 'searchWithih',
checkable : true,
checked : true
},{
caption : this.textWorkbook,
toggleGroup : 'searchWithih',
checkable : true,
checked : false
}]
})
});
var menuSearch = new Common.UI.MenuItem({
caption : this.textSearch,
menu : new Common.UI.Menu({
menuAlign : 'tl-tr',
items : [{
caption : this.textByRows,
toggleGroup : 'searchByrows',
checkable : true,
checked : true
},{
caption : this.textByColumns,
toggleGroup : 'searchByrows',
checkable : true,
checked : false
}]
})
});
var menuLookin = new Common.UI.MenuItem({
caption : this.textLookin,
menu : new Common.UI.Menu({
menuAlign : 'tl-tr',
items : [{
caption : this.textFormulas,
toggleGroup : 'searchLookin',
checkable : true,
checked : true
},{
caption : this.textValues,
toggleGroup : 'searchLookin',
checkable : true,
checked : false
}]
})
});
this.dlgSearch = (new Common.UI.SearchDialog({
matchcase: true,
matchword: true,
matchwordstr: this.textItemEntireCell,
markresult: {applied: true},
extraoptions : [menuWithin,menuSearch,menuLookin]
}));
this.dlgSearch.menuWithin = menuWithin;
this.dlgSearch.menuSearch = menuSearch;
this.dlgSearch.menuLookin = menuLookin;
this.dlgSearch.findOptions = new Asc.asc_CFindOptions();
}
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? (action || undefined) : 'no-replace';
if (this.dlgSearch.isVisible()) {
this.dlgSearch.setMode(mode);
this.dlgSearch.focus();
} else {
this.dlgSearch.show(mode);
}
this.api.asc_closeCellEditor();
} else this.dlgSearch['hide']();
},
onMenuSearch: function(obj, show) {
this.showSearchDlg(show);
},
onSearchDlgHide: function() {
this.leftMenu.btnSearch.toggle(false, true);
this.api.asc_selectSearchingResults(false);
$(this.leftMenu.btnSearch.el).blur();
this.api.asc_enableKeyEvents(true);
},
onRenameText: function(found, replaced) {
var me = this;
if (this.api.isReplaceAll) {
Common.UI.info({
msg: (found) ? ((!found-replaced) ? Common.Utils.String.format(this.textReplaceSuccess,replaced) : Common.Utils.String.format(this.textReplaceSkipped,found-replaced)) : this.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
} else {
var sett = this.dlgSearch.getSettings();
var options = this.dlgSearch.findOptions;
options.asc_setFindWhat(sett.textsearch);
options.asc_setScanForward(true);
options.asc_setIsMatchCase(sett.matchcase);
options.asc_setIsWholeCell(sett.matchword);
options.asc_setScanOnOnlySheet(this.dlgSearch.menuWithin.menu.items[0].checked);
options.asc_setScanByRows(this.dlgSearch.menuSearch.menu.items[0].checked);
options.asc_setLookIn(this.dlgSearch.menuLookin.menu.items[0].checked?Asc.c_oAscFindLookIn.Formulas:Asc.c_oAscFindLookIn.Value);
if (!me.api.asc_findText(options)) {
Common.UI.info({
msg: this.textNoTextFound,
callback: function() {
me.dlgSearch.focus();
}
});
}
}
},
setPreviewMode: function(mode) {
if (this.viewmode === mode) return;
this.viewmode = mode;
this.dlgSearch && this.dlgSearch.setMode(this.viewmode ? 'no-replace' : 'search');
this.leftMenu.panelSearch && this.leftMenu.panelSearch.setSearchMode(this.viewmode ? 'no-replace' : 'search');
},
onApiServerDisconnect: function(enableDownload) {
@ -767,10 +573,6 @@ define([
this.leftMenu.btnSpellcheck.setDisabled(true);
this.leftMenu.getMenu('file').setMode({isDisconnected: true, enableDownload: !!enableDownload});
if ( this.dlgSearch ) {
this.leftMenu.btnSearch.toggle(false, true);
this.dlgSearch['hide']();
}
},
/** coauthoring begin **/
@ -876,14 +678,36 @@ define([
switch (s) {
case 'replace':
case 'search':
if (!this.leftMenu.btnSearch.isDisabled()) {
if (!this.leftMenu.btnSearchBar.isDisabled()) {
Common.UI.Menu.Manager.hideAll();
this.showSearchDlg(true,s);
this.leftMenu.btnSearch.toggle(true,true);
this.leftMenu.btnAbout.toggle(false);
if ( this.leftMenu.menuFile.isVisible() )
this.leftMenu.menuFile.hide();
var selectedText = this.api.asc_GetSelectedText();
if (this.isSearchPanelVisible()) {
selectedText && this.leftMenu.panelSearch.setFindText(selectedText);
this.leftMenu.panelSearch.focus(selectedText !== '' ? s : 'search');
this.leftMenu.fireEvent('search:aftershow', [selectedText]);
return false;
} else if (this.getApplication().getController('Viewport').isSearchBarVisible()) {
var viewport = this.getApplication().getController('Viewport');
if (s === 'replace') {
viewport.header.btnSearch.toggle(false);
this.onShowHideSearch(true, viewport.searchBar.inputSearch.val());
} else {
selectedText && viewport.searchBar.setText(selectedText);
viewport.searchBar.focus();
return false;
}
} else if (s === 'search') {
Common.NotificationCenter.trigger('search:show');
return false;
} else {
this.onShowHideSearch(true, selectedText);
}
this.leftMenu.btnSearchBar.toggle(true,true);
this.leftMenu.panelSearch.focus(selectedText !== '' ? s : 'search');
}
return false;
case 'save':
@ -910,6 +734,10 @@ define([
return false;
case 'escape':
var btnSearch = this.getApplication().getController('Viewport').header.btnSearch;
btnSearch.pressed && btnSearch.toggle(false);
this.leftMenu._state.isSearchOpen && (this.leftMenu._state.isSearchOpen = false);
if ( this.leftMenu.menuFile.isVisible() ) {
if (Common.UI.HintManager.needCloseFileMenu())
this.leftMenu.menuFile.hide();
@ -967,7 +795,7 @@ define([
var isRangeSelection = (status != Asc.c_oAscSelectionDialogType.None);
this.leftMenu.btnAbout.setDisabled(isRangeSelection);
this.leftMenu.btnSearch.setDisabled(isRangeSelection);
this.leftMenu.btnSearchBar.setDisabled(isRangeSelection);
this.leftMenu.btnSpellcheck.setDisabled(isRangeSelection);
if (this.mode.canPlugins && this.leftMenu.panelPlugins) {
this.leftMenu.panelPlugins.setLocked(isRangeSelection);
@ -979,7 +807,7 @@ define([
var isEditFormula = (state == Asc.c_oAscCellEditorState.editFormula);
this.leftMenu.btnAbout.setDisabled(isEditFormula);
this.leftMenu.btnSearch.setDisabled(isEditFormula);
this.leftMenu.btnSearchBar.setDisabled(isEditFormula);
this.leftMenu.btnSpellcheck.setDisabled(isEditFormula);
if (this.mode.canPlugins && this.leftMenu.panelPlugins) {
this.leftMenu.panelPlugins.setLocked(isEditFormula);
@ -1013,6 +841,29 @@ define([
}
},
onShowHideSearch: function (state, findText) {
if (state) {
Common.UI.Menu.Manager.hideAll();
this.leftMenu.showMenu('advancedsearch');
this.leftMenu.fireEvent('search:aftershow', [findText]);
} else {
this.leftMenu.btnSearchBar.toggle(false, true);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
},
onMenuSearchBar: function(obj, show) {
if (show) {
var mode = this.mode.isEdit && !this.viewmode ? undefined : 'no-replace';
this.leftMenu.panelSearch.setSearchMode(mode);
}
this.leftMenu._state.isSearchOpen = show;
},
isSearchPanelVisible: function () {
return this.leftMenu._state.isSearchOpen;
},
onMenuChange: function (value) {
if ('hide' === value) {
if (this.leftMenu.btnComments.isActive() && this.api) {
@ -1021,6 +872,9 @@ define([
// focus to sdk
this.api.asc_enableKeyEvents(true);
} else if (this.leftMenu.btnSearchBar.isActive() && this.api) {
this.leftMenu.btnSearchBar.toggle(false);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnSearchBar);
}
}
},
@ -1044,8 +898,6 @@ define([
newDocumentTitle : 'Unnamed document',
textItemEntireCell : 'Entire cell contents',
requestEditRightsText : 'Requesting editing rights...',
textReplaceSuccess : 'Search has been done. {0} occurrences have been replaced',
textReplaceSkipped : 'The replacement has been made. {0} occurrences were skipped.',
warnDownloadAs : 'If you continue saving in this format all features except the text will be lost.<br>Are you sure you want to continue?' ,
textWarning: 'Warning',
textSheet: 'Sheet',

View file

@ -0,0 +1,552 @@
/*
*
* (c) Copyright Ascensio System SIA 2010-2020
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
/**
* ViewTab.js
*
* Created by Julia Svinareva on 22.02.2022
* Copyright (c) 2022 Ascensio System SIA. All rights reserved.
*
*/
define([
'core',
'common/main/lib/view/SearchPanel'
], function () {
'use strict';
SSE.Controllers.Search = Backbone.Controller.extend(_.extend({
sdkViewName : '#id_main',
views: [
'Common.Views.SearchPanel'
],
initialize: function () {
this.addListeners({
'SearchBar': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:input': _.bind(this.onInputSearchChange, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown'),
'show': _.bind(this.onSelectSearchingResults, this, true),
'hide': _.bind(this.onSelectSearchingResults, this, false)
},
'Common.Views.SearchPanel': {
'search:back': _.bind(this.onSearchNext, this, 'back'),
'search:next': _.bind(this.onSearchNext, this, 'next'),
'search:replace': _.bind(this.onQueryReplace, this),
'search:replaceall': _.bind(this.onQueryReplaceAll, this),
'search:input': _.bind(this.onInputSearchChange, this),
'search:options': _.bind(this.onChangeSearchOption, this),
'search:keydown': _.bind(this.onSearchNext, this, 'keydown'),
'show': _.bind(this.onShowPanel, this),
'hide': _.bind(this.onHidePanel, this)
},
'LeftMenu': { // TO DO
'search:aftershow': _.bind(this.onShowAfterSearch, this)
}
});
},
onLaunch: function () {
this._state = {
searchText: '',
matchCase: false,
matchWord: false,
useRegExp: false,
withinSheet: Asc.c_oAscSearchBy.Sheet,
searchByRows: true,
lookInFormulas: true,
isValidSelectedRange: true
};
},
setMode: function (mode) {
this.view = this.createView('Common.Views.SearchPanel', { mode: mode });
this.view.on('render:after', _.bind(this.onAfterRender, this));
},
setApi: function (api) {
if (api) {
this.api = api;
this.api.asc_registerCallback('asc_onRenameCellTextEnd', _.bind(this.onRenameText, this));
this.api.asc_registerCallback('asc_onSetSearchCurrent', _.bind(this.onUpdateSearchCurrent, this));
this.api.asc_registerCallback('asc_onStartTextAroundSearch', _.bind(this.onStartTextAroundSearch, this));
this.api.asc_registerCallback('asc_onEndTextAroundSearch', _.bind(this.onEndTextAroundSearch, this));
this.api.asc_registerCallback('asc_onGetTextAroundSearchPack', _.bind(this.onApiGetTextAroundSearch, this));
this.api.asc_registerCallback('asc_onRemoveTextAroundSearch', _.bind(this.onApiRemoveTextAroundSearch, this));
}
return this;
},
getView: function(name) {
return !name && this.view ?
this.view : Backbone.Controller.prototype.getView.call(this, name);
},
onAfterRender: function () {
var me = this;
this.view.inputSelectRange.validation = function(value) {
if (_.isEmpty(value)) {
return true;
}
var isvalid = me.api.asc_checkDataRange(undefined, value);
me._state.isValidSelectedRange = isvalid !== Asc.c_oAscError.ID.DataRangeError;
return (isvalid === Asc.c_oAscError.ID.DataRangeError) ? me.textInvalidRange : true;
};
this.view.inputSelectRange.on('button:click', _.bind(this.onRangeSelect, this));
},
onChangeSearchOption: function (option, value, noSearch) {
var runSearch = true;
switch (option) {
case 'case-sensitive':
this._state.matchCase = value;
break;
case 'match-word':
this._state.matchWord = value;
break;
case 'regexp':
this._state.useRegExp = value;
break;
case 'within':
this._state.withinSheet = value === 0 ? Asc.c_oAscSearchBy.Sheet : (value === 1 ? Asc.c_oAscSearchBy.Workbook : Asc.c_oAscSearchBy.Range);
this.view.inputSelectRange.setDisabled(value !== Asc.c_oAscSearchBy.Range);
if (value === Asc.c_oAscSearchBy.Range) {
runSearch = false;
}
break;
case 'range':
this._state.selectedRange = value;
runSearch = !noSearch;
break;
case 'search':
this._state.searchByRows = value;
break;
case 'lookIn':
this._state.lookInFormulas = value;
break;
}
if (runSearch && this._state.searchText !== '') {
this.hideResults();
if (this.onQuerySearch()) {
this.searchTimer && clearInterval(this.searchTimer);
this.searchTimer = undefined;
this.api.asc_StartTextAroundSearch();
}
}
},
onRangeSelect: function () {
var me = this;
var handlerDlg = function(dlg, result) {
if (result == 'ok') {
var valid = dlg.getSettings();
me.view.inputSelectRange.setValue(valid);
me.view.inputSelectRange.checkValidate();
me.onChangeSearchOption('range', valid);
}
};
var win = new SSE.Views.CellRangeDialog({
handler: handlerDlg
}).on('close', function() {
_.delay(function(){
me.view.inputSelectRange.focus();
},1);
});
win.show();
win.setSettings({
api: me.api,
range: (!_.isEmpty(me.view.inputSelectRange.getValue()) && (me.view.inputSelectRange.checkValidate()==true)) ? me.view.inputSelectRange.getValue() : me._state.selectedRange,
type: Asc.c_oAscSelectionDialogType.PrintTitles
});
},
onSearchNext: function (type, text, e) {
var isReturnKey = type === 'keydown' && e.keyCode === Common.UI.Keys.RETURN;
if (text && text.length > 0 && (isReturnKey || type !== 'keydown')) {
this._state.searchText = text;
if (this.onQuerySearch(type) && (this.searchTimer || isReturnKey)) {
this.hideResults();
if (this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = undefined;
}
if (this.view.$el.is(':visible')) {
this.api.asc_StartTextAroundSearch();
}
}
}
},
onInputSearchChange: function (text) {
var me = this;
if (this._state.searchText !== text) {
this._state.newSearchText = text;
this._lastInputChange = (new Date());
if (this.searchTimer === undefined) {
this.searchTimer = setInterval(function(){
if ((new Date()) - me._lastInputChange < 400) return;
me.hideResults();
me._state.searchText = me._state.newSearchText;
if (me._state.newSearchText !== '' && me.onQuerySearch()) {
if (me.view.$el.is(':visible')) {
me.api.asc_StartTextAroundSearch();
}
me.view.disableReplaceButtons(false);
} else if (me._state.newSearchText === '') {
me.view.updateResultsNumber('no-results');
me.view.disableReplaceButtons(true);
}
clearInterval(me.searchTimer);
me.searchTimer = undefined;
}, 10);
}
}
},
onQuerySearch: function (d, w, opts, fromPanel) {
var me = this;
if (this._state.withinSheet === Asc.c_oAscSearchBy.Range && !this._state.isValidSelectedRange) {
Common.UI.warning({
title: this.notcriticalErrorTitle,
msg: this.textInvalidRange,
buttons: ['ok'],
callback: function () {
me.view.focus('range');
}
});
return;
}
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(this._state.searchText);
options.asc_setScanForward(d != 'back');
options.asc_setIsMatchCase(this._state.matchCase);
options.asc_setIsWholeCell(this._state.matchWord);
options.asc_setScanOnOnlySheet(this._state.withinSheet);
if (this._state.withinSheet === Asc.c_oAscSearchBy.Range) {
options.asc_setSpecificRange(this._state.selectedRange);
}
options.asc_setScanByRows(this._state.searchByRows);
options.asc_setLookIn(this._state.lookInFormulas ? Asc.c_oAscFindLookIn.Formulas : Asc.c_oAscFindLookIn.Value);
if (!this.api.asc_findText(options)) {
this.resultItems = [];
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
return false;
}
return true;
},
onQueryReplace: function(textSearch, textReplace) {
if (textSearch !== '') {
this.api.isReplaceAll = false;
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(textSearch);
options.asc_setReplaceWith(textReplace);
options.asc_setIsMatchCase(this._state.matchCase);
options.asc_setIsWholeCell(this._state.matchWord);
options.asc_setScanOnOnlySheet(this._state.withinSheet);
if (this._state.withinSheet === Asc.c_oAscSearchBy.Range) {
options.asc_setSpecificRange(this._state.selectedRange);
}
options.asc_setScanByRows(this._state.searchByRows);
options.asc_setLookIn(this._state.lookIn ? Asc.c_oAscFindLookIn.Formulas : Asc.c_oAscFindLookIn.Value);
options.asc_setIsReplaceAll(false);
this.api.asc_replaceText(options);
}
},
onQueryReplaceAll: function(textSearch, textReplace) {
this.api.isReplaceAll = true;
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(textSearch);
options.asc_setReplaceWith(textReplace);
options.asc_setIsMatchCase(this._state.matchCase);
options.asc_setIsWholeCell(this._state.matchWord);
options.asc_setScanOnOnlySheet(this._state.withinSheet);
if (this._state.withinSheet === Asc.c_oAscSearchBy.Range) {
options.asc_setSpecificRange(this._state.selectedRange);
}
options.asc_setScanByRows(this._state.searchByRows);
options.asc_setLookIn(this._state.lookIn ? Asc.c_oAscFindLookIn.Formulas : Asc.c_oAscFindLookIn.Value);
options.asc_setIsReplaceAll(true);
this.api.asc_replaceText(options);
},
onRenameText: function (found, replaced) {
var me = this;
if (this.api.isReplaceAll) {
if (!found) {
this.allResultsWasRemoved();
} else {
!(found-replaced) && this.allResultsWasRemoved();
Common.UI.info({
msg: !(found-replaced) ? Common.Utils.String.format(this.textReplaceSuccess,replaced) : Common.Utils.String.format(this.textReplaceSkipped,found-replaced),
callback: function() {
me.view.focus();
}
});
}
} else {
var options = new Asc.asc_CFindOptions();
options.asc_setFindWhat(this._state.searchText);
options.asc_setScanForward(true);
options.asc_setIsMatchCase(this._state.matchCase);
options.asc_setIsWholeCell(this._state.matchWord);
options.asc_setScanOnOnlySheet(this._state.withinSheet);
if (this._state.withinSheet === Asc.c_oAscSearchBy.Range) {
options.asc_setSpecificRange(this._state.selectedRange);
}
options.asc_setScanByRows(this._state.searchByRows);
options.asc_setLookIn(this._state.lookInFormulas ? Asc.c_oAscFindLookIn.Formulas : Asc.c_oAscFindLookIn.Value);
if (!this.api.asc_findText(options)) {
this.allResultsWasRemoved();
}
}
},
allResultsWasRemoved: function () {
this.resultItems = [];
this.hideResults();
this.view.updateResultsNumber(undefined, 0);
this.view.disableReplaceButtons(true);
this._state.currentResult = 0;
this._state.resultsNumber = 0;
this.view.disableNavButtons();
},
onApiRemoveTextAroundSearch: function (arr) {
var me = this;
arr.forEach(function (id) {
var ind = _.findIndex(me.resultItems, {id: id});
if (ind !== -1) {
me.resultItems[ind].$el.remove();
me.resultItems.splice(ind, 1);
}
});
},
onUpdateSearchCurrent: function (current, all) {
if (current === -1) return;
this._state.currentResult = current;
this._state.resultsNumber = all;
if (this.view) {
this.view.updateResultsNumber(current, all);
this.view.disableNavButtons(current, all);
if (this.resultItems && this.resultItems.length > 0) {
this.resultItems.forEach(function (item) {
item.selected = false;
});
if (this.resultItems[current]) {
this.resultItems[current].selected = true;
$('#search-results').find('.item').removeClass('selected');
this.resultItems[current].$el.addClass('selected');
this.scrollToSelectedResult(current);
}
}
}
Common.NotificationCenter.trigger('search:updateresults', current, all);
},
scrollToSelectedResult: function (ind) {
var index = ind !== undefined ? ind : _.findIndex(this.resultItems, {selected: true});
if (index !== -1) {
var item = this.resultItems[index].$el,
itemHeight = item.outerHeight(),
itemTop = item.position().top,
container = this.view.$resultsContainer.find('.search-items'),
containerHeight = container.outerHeight(),
containerTop = container.scrollTop();
if (itemTop < 0 || (containerTop === 0 && itemTop > containerHeight)) {
this.view.$resultsContainer.scroller.scrollTop(containerTop + itemTop - 12);
} else if (itemTop + itemHeight > containerHeight) {
this.view.$resultsContainer.scroller.scrollTop(containerTop + itemHeight);
}
}
},
onStartTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = true;
}
},
onEndTextAroundSearch: function () {
if (this.view) {
this._state.isStartedAddingResults = false;
this.view.$resultsContainer.scroller.update({alwaysVisibleY: true});
}
},
onApiGetTextAroundSearch: function (data) { // [id, sheet, name, cell, value, formula]
if (this.view && this._state.isStartedAddingResults) {
if (data.length > 300 || !data.length) return;
var me = this,
$innerResults = me.view.$resultsContainer.find('.search-items');
me.resultItems = [];
data.forEach(function (item, ind) {
var isSelected = ind === me._state.currentResult;
var tr = '<div class="item" style="width: 100%;">' +
'<div class="sheet">' + (item[1] ? item[1] : '') + '</div>' +
'<div class="name">' + (item[2] ? item[2] : '') + '</div>' +
'<div class="cell">' + (item[3] ? item[3] : '') + '</div>' +
'<div class="value">' + (item[4] ? item[4] : '') + '</div>' +
'<div class="formula">' + (item[5] ? item[5] : '') + '</div>' +
'</div>';
var $item = $(tr).appendTo($innerResults);
if (isSelected) {
$item.addClass('selected');
}
var resultItem = {id: item[0], $el: $item, el: tr, selected: isSelected, data: data};
me.resultItems.push(resultItem);
$item.on('click', _.bind(function (el) {
var id = item[0];
me.api.asc_SelectSearchElement(id);
}, me));
me.addTooltips($item, item);
});
this.view.$resultsContainer.show();
}
},
addTooltips: function (item, data) {
var cells = [item.find('.sheet'), item.find('.name'), item.find('.cell'), item.find('.value'), item.find('.formula')],
tips = [data[1], data[2], data[3], data[4], data[5]];
cells.forEach(function (el, ind) {
var tip = tips[ind];
if (tip) {
el.one('mouseenter', function () {
el.attr('data-toggle', 'tooltip');
el.tooltip({
title: tip,
placement: 'cursor',
zIndex: 1000
});
el.mouseenter();
});
}
});
},
hideResults: function () {
if (this.view) {
this.view.$resultsContainer.hide();
this.view.$resultsContainer.find('.search-items').empty();
}
},
onShowAfterSearch: function (findText) {
var viewport = this.getApplication().getController('Viewport');
if (viewport.isSearchBarVisible()) {
viewport.searchBar.hide();
}
var text = typeof findText === 'string' ? findText : (this.api.asc_GetSelectedText() || this._state.searchText);
if (this.resultItems && this.resultItems.length > 0 &&
(!this._state.matchCase && text.toLowerCase() === this.view.inputText.getValue().toLowerCase() ||
this._state.matchCase && text === this.view.inputText.getValue())) { // show old results
return;
}
if (text) {
this.view.setFindText(text);
} else if (text !== undefined) { // panel was opened from empty searchbar, clear to start new search
this.view.setFindText('');
this._state.searchText = undefined;
}
this.hideResults();
if (text !== '' && text === this._state.searchText) { // search was made
this.view.disableReplaceButtons(false);
this.api.asc_StartTextAroundSearch();
} else if (text !== '') { // search wasn't made
this.onInputSearchChange(text);
} else {
this.resultItems = [];
this.view.disableReplaceButtons(true);
this.view.clearResultsNumber();
}
this.view.disableNavButtons(this._state.currentResult, this._state.resultsNumber);
},
onShowPanel: function () {
this.onSelectSearchingResults(true);
if (this.resultItems && this.resultItems.length > 0 && !this._state.isStartedAddingResults) {
var me = this,
$tableBody = this.view.$resultsContainer.find('.search-items');
this.view.$resultsContainer.show();
this.resultItems.forEach(function (item) {
var $item = $(item.el).appendTo($tableBody);
if (item.selected) {
$item.addClass('selected');
}
$item.on('click', function (el) {
me.api.asc_SelectSearchElement(item.id);
$('#search-results').find('.item').removeClass('selected');
$(el.currentTarget).addClass('selected');
});
me.addTooltips($item, item.data);
});
this.scrollToSelectedResult();
}
},
onHidePanel: function () {
this.hideResults();
this.onSelectSearchingResults(false);
},
onSelectSearchingResults: function (val) {
if (!val && this.getApplication().getController('LeftMenu').isSearchPanelVisible()) return;
if (this._state.isHighlightedResults !== val) {
this.api.asc_selectSearchingResults(val);
this._state.isHighlightedResults = val;
}
},
textNoTextFound: 'The data you have been searching for could not be found. Please adjust your search options.',
textReplaceSuccess: 'Search has been done. {0} occurrences have been replaced',
textReplaceSkipped: 'The replacement has been made. {0} occurrences were skipped.',
textInvalidRange: 'ERROR! Invalid cells range'
}, SSE.Controllers.Search || {}));
});

View file

@ -43,6 +43,7 @@
define([
'core',
'common/main/lib/view/Header',
'common/main/lib/view/SearchBar',
'spreadsheeteditor/main/app/view/Viewport'
// ,'spreadsheeteditor/main/app/view/LeftMenu'
], function (Viewport) {
@ -217,6 +218,8 @@ define([
this.boxFormula = $('#cell-editing-box');
this.boxSdk.css('border-left', 'none');
this.boxFormula.css('border-left', 'none');
Common.NotificationCenter.on('search:show', _.bind(this.onSearchShow, this));
},
onLayoutChanged: function(area) {
@ -294,6 +297,34 @@ define([
SetDisabled: function (disabled) {
},
onSearchShow: function () {
this.header.btnSearch && this.header.btnSearch.toggle(true);
},
onSearchToggle: function () {
var leftMenu = this.getApplication().getController('LeftMenu');
if (leftMenu.isSearchPanelVisible()) {
this.header.btnSearch.toggle(false, true);
leftMenu.getView('LeftMenu').panelSearch.focus();
return;
}
if (!this.searchBar) {
this.searchBar = new Common.UI.SearchBar({});
this.searchBar.on('hide', _.bind(function () {
this.header.btnSearch.toggle(false, true);
}, this));
}
if (this.header.btnSearch.pressed) {
this.searchBar.show(this.api.asc_GetSelectedText());
} else {
this.searchBar.hide();
}
},
isSearchBarVisible: function () {
return this.searchBar && this.searchBar.isVisible();
},
textHideFBar: 'Hide Formula Bar',
textHideHeadings: 'Hide Headings',
textHideGridlines: 'Hide Gridlines',

View file

@ -1,6 +1,6 @@
<div id="view-left-menu" class="tool-menu left">
<div class="tool-menu-btns">
<button id="left-btn-search" class="btn btn-category" content-target="" data-hint="0" data-hint-direction="right" data-hint-offset="big"><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<button id="left-btn-searchbar" class="btn btn-category" data-hint="0" data-hint-direction="right" data-hint-offset="big" content-target="left-panel-search"><i class="icon toolbar__icon btn-menu-search">&nbsp;</i></button>
<!-- /** coauthoring begin **/ -->
<button id="left-btn-comments" class="btn btn-category" content-target="left-panel-comments" data-hint="0" data-hint-direction="right" data-hint-offset="big"><i class="icon toolbar__icon btn-menu-comments">&nbsp;</i></button>
<button id="left-btn-chat" class="btn btn-category" content-target="left-panel-chat" data-hint="0" data-hint-direction="right" data-hint-offset="big"><i class="icon toolbar__icon btn-menu-chat">&nbsp;</i></button>
@ -11,6 +11,7 @@
<button id="left-btn-about" class="btn btn-category" content-target="" data-hint="0" data-hint-direction="right" data-hint-offset="big"><i class="icon toolbar__icon btn-menu-about">&nbsp;</i></button>
</div>
<div class="left-panel" style="">
<div id="left-panel-search" class="" style="display: none;"></div>
<!-- /** coauthoring begin **/ -->
<div id="left-panel-comments" class="" style="display: none;"></div>
<div id="left-panel-chat" class="" style="display: none;"></div>

View file

@ -65,6 +65,7 @@ define([
/** coauthoring end **/
'click #left-btn-plugins': _.bind(this.onCoauthOptions, this),
'click #left-btn-spellcheck': _.bind(this.onCoauthOptions, this),
'click #left-btn-searchbar': _.bind(this.onCoauthOptions, this),
'click #left-btn-support': function() {
var config = this.mode.customization;
config && !!config.feedback && !!config.feedback.url ?
@ -82,12 +83,13 @@ define([
render: function () {
var $markup = $(this.template({}));
this.btnSearch = new Common.UI.Button({
action: 'search',
el: $markup.elementById('#left-btn-search'),
hint: this.tipSearch + Common.Utils.String.platformKey('Ctrl+F'),
this.btnSearchBar = new Common.UI.Button({
action: 'advancedsearch',
el: $markup.elementById('#left-btn-searchbar'),
hint: this.tipSearch,
disabled: true,
enableToggle: true
enableToggle: true,
toggleGroup: 'leftMenuGroup'
});
this.btnAbout = new Common.UI.Button({
@ -151,7 +153,7 @@ define([
this.btnSpellcheck.hide();
this.btnSpellcheck.on('click', _.bind(this.onBtnMenuClick, this));
this.btnSearch.on('click', _.bind(this.onBtnMenuClick, this));
this.btnSearchBar.on('click', _.bind(this.onBtnMenuClick, this));
this.btnAbout.on('toggle', _.bind(this.onBtnMenuToggle, this));
this.menuFile = new SSE.Views.FileMenu({});
@ -166,9 +168,6 @@ define([
btn.panel['show']();
if (!this._state.pluginIsRunning)
this.$el.width(SCALE_MIN);
if (this.btnSearch.isActive())
this.btnSearch.toggle(false);
} else {
btn.panel['hide']();
}
@ -226,6 +225,14 @@ define([
} else
this.panelSpellcheck['hide']();
}
if (this.panelSearch) {
if (this.btnSearchBar.pressed) {
this.panelSearch.show();
this.fireEvent('search:aftershow', this);
} else {
this.panelSearch.hide();
}
}
// if (this.mode.canPlugins && this.panelPlugins) {
// if (this.btnPlugins.pressed) {
// this.panelPlugins.show();
@ -247,6 +254,9 @@ define([
this.panelSpellcheck = panel.render('#left-panel-spellcheck');
} else if (name == 'history') {
this.panelHistory = panel.render('#left-panel-history');
} else
if (name == 'advancedsearch') {
this.panelSearch = panel.render('#left-panel-search');
}
},
@ -288,10 +298,14 @@ define([
this.panelSpellcheck['hide']();
this.btnSpellcheck.toggle(false, true);
}
if (this.panelSearch) {
this.panelSearch['hide']();
this.btnSearchBar.toggle(false, true);
}
},
isOpened: function() {
var isopened = this.btnSearch.pressed;
var isopened = this.btnSearchBar.pressed;
/** coauthoring begin **/
!isopened && (isopened = this.btnComments.pressed || this.btnChat.pressed);
/** coauthoring end **/
@ -301,7 +315,7 @@ define([
disableMenu: function(menu, disable) {
this.btnAbout.setDisabled(false);
this.btnSupport.setDisabled(false);
this.btnSearch.setDisabled(false);
this.btnSearchBar.setDisabled(false);
/** coauthoring begin **/
this.btnComments.setDisabled(false);
this.btnChat.setDisabled(false);
@ -333,6 +347,13 @@ define([
this.onCoauthOptions();
this.btnComments.$el.focus();
}
} else if (menu == 'advancedsearch') {
if (this.btnSearchBar.isVisible() &&
!this.btnSearchBar.isDisabled() && !this.btnSearchBar.pressed) {
this.btnSearchBar.toggle(true);
this.onBtnMenuClick(this.btnSearchBar);
this.onCoauthOptions();
}
}
/** coauthoring end **/
}

View file

@ -149,6 +149,7 @@ require([
'PivotTable',
'DataTab',
'ViewTab',
'Search',
'WBProtection',
'Common.Controllers.Fonts',
'Common.Controllers.History',
@ -179,6 +180,7 @@ require([
'spreadsheeteditor/main/app/controller/PivotTable',
'spreadsheeteditor/main/app/controller/DataTab',
'spreadsheeteditor/main/app/controller/ViewTab',
'spreadsheeteditor/main/app/controller/Search',
'spreadsheeteditor/main/app/controller/WBProtection',
'spreadsheeteditor/main/app/view/FileMenuPanels',
'spreadsheeteditor/main/app/view/ParagraphSettings',

View file

@ -145,6 +145,11 @@
"Common.UI.Window.textInformation": "Information",
"Common.UI.Window.textWarning": "Warning",
"Common.UI.Window.yesButtonText": "Yes",
"Common.UI.SearchBar.textFind": "Find",
"Common.UI.SearchBar.tipPreviousResult": "Previous result",
"Common.UI.SearchBar.tipNextResult": "Next result",
"Common.UI.SearchBar.tipOpenAdvancedSettings": "Open advanced settings",
"Common.UI.SearchBar.tipCloseSearch": "Close search",
"Common.Utils.Metric.txtCm": "cm",
"Common.Utils.Metric.txtPt": "pt",
"Common.Views.About.txtAddress": "address: ",
@ -242,6 +247,7 @@
"Common.Views.Header.tipViewUsers": "View users and manage document access rights",
"Common.Views.Header.txtAccessRights": "Change access rights",
"Common.Views.Header.txtRename": "Rename",
"Common.Views.Header.tipSearch": "Search",
"Common.Views.History.textCloseHistory": "Close History",
"Common.Views.History.textHide": "Collapse",
"Common.Views.History.textHideAll": "Hide detailed changes",
@ -435,6 +441,38 @@
"Common.Views.UserNameDialog.textDontShow": "Don't ask me again",
"Common.Views.UserNameDialog.textLabel": "Label:",
"Common.Views.UserNameDialog.textLabelError": "Label must not be empty.",
"Common.Views.SearchPanel.textFind": "Find",
"Common.Views.SearchPanel.textFindAndReplace": "Find and replace",
"Common.Views.SearchPanel.textCloseSearch": "Close search",
"Common.Views.SearchPanel.textReplace": "Replace",
"Common.Views.SearchPanel.textReplaceAll": "Replace All",
"Common.Views.SearchPanel.textSearchResults": "Search results: {0}/{1}",
"Common.Views.SearchPanel.textReplaceWith": "Replace with",
"Common.Views.SearchPanel.textCaseSensitive": "Case sensitive",
"Common.Views.SearchPanel.textMatchUsingRegExp": "Match using regular expressions",
"Common.Views.SearchPanel.textWholeWords": "Whole words only",
"Common.Views.SearchPanel.textWithin": "Within",
"Common.Views.SearchPanel.textSelectDataRange": "Select Data range",
"Common.Views.SearchPanel.textSearch": "Search",
"Common.Views.SearchPanel.textLookIn": "Look in",
"Common.Views.SearchPanel.textSheet": "Sheet",
"Common.Views.SearchPanel.textWorkbook": "Workbook",
"Common.Views.SearchPanel.textSpecificRange": "Specific range",
"Common.Views.SearchPanel.textByRows": "By rows",
"Common.Views.SearchPanel.textByColumns": "By columns",
"Common.Views.SearchPanel.textFormulas": "Formulas",
"Common.Views.SearchPanel.textValues": "Values",
"Common.Views.SearchPanel.textSearchOptions": "Search options",
"Common.Views.SearchPanel.textNoMatches": "No matches",
"Common.Views.SearchPanel.textNoSearchResults": "No search results",
"Common.Views.SearchPanel.textItemEntireCell": "Entire cell contents",
"Common.Views.SearchPanel.textTooManyResults": "There are too many results to show here",
"Common.Views.SearchPanel.tipPreviousResult": "Previous result",
"Common.Views.SearchPanel.tipNextResult": "Next result",
"Common.Views.SearchPanel.textName": "Name",
"Common.Views.SearchPanel.textCell": "Cell",
"Common.Views.SearchPanel.textValue": "Value",
"Common.Views.SearchPanel.textFormula": "Formula",
"SSE.Controllers.DataTab.textColumns": "Columns",
"SSE.Controllers.DataTab.textEmptyUrl": "You need to specify URL.",
"SSE.Controllers.DataTab.textRows": "Rows",
@ -1445,6 +1483,10 @@
"SSE.Controllers.Viewport.textHideFBar": "Hide Formula Bar",
"SSE.Controllers.Viewport.textHideGridlines": "Hide Gridlines",
"SSE.Controllers.Viewport.textHideHeadings": "Hide Headings",
"SSE.Controllers.Search.textNoTextFound": "The data you have been searching for could not be found. Please adjust your search options.",
"SSE.Controllers.Search.textReplaceSuccess": "Search has been done. {0} occurrences have been replaced",
"SSE.Controllers.Search.textReplaceSkipped": "The replacement has been made. {0} occurrences were skipped.",
"SSE.Controllers.Search.textInvalidRange": "ERROR! Invalid cells range",
"SSE.Views.AdvancedSeparatorDialog.strDecimalSeparator": "Decimal separator",
"SSE.Views.AdvancedSeparatorDialog.strThousandsSeparator": "Thousands separator",
"SSE.Views.AdvancedSeparatorDialog.textLabel": "Settings used to recognize numeric data",

View file

@ -745,3 +745,57 @@
height: 16px;
width: 16px;
}
.search-panel {
#search-options {
label {
width: 100%;
}
}
#search-results {
padding-top: 6px;
.search-table {
width:100%;
height: 100%;
position: relative;
}
.header-item {
width:16%;
display: inline-block;
height: 18px;
text-align: start;
font-weight: normal;
padding-left: 4px;
&:not(:first-child) {
border-left: @scaled-one-px-value-ie solid @border-divider-ie;
border-left: @scaled-one-px-value solid @border-divider;
}
&:last-child {
width:36%;
}
}
.search-items {
height: calc(100% - 24px);
position: absolute;
top: 23px;
width: 100%;
overflow: hidden;
.item {
padding: 0;
display: flex;
div {
width: 16%;
padding-left: 4px;
height: 28px;
line-height: 28px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:last-child {
width: 36%;
}
}
}
}
}
}

View file

@ -334,6 +334,8 @@
"../apps/common/embed/lib/view/LoadMask.js",
"../apps/common/embed/lib/view/modals.js",
"../apps/common/embed/lib/controller/modals.js",
"../apps/common/embed/lib/view/SearchBar.js",
"../apps/documenteditor/embed/js/SearchBar.js",
"../apps/documenteditor/embed/js/ApplicationView.js",
"../apps/documenteditor/embed/js/ApplicationController.js",
"../apps/documenteditor/embed/js/application.js"

View file

@ -338,6 +338,8 @@
"../apps/common/embed/lib/view/LoadMask.js",
"../apps/common/embed/lib/view/modals.js",
"../apps/common/embed/lib/controller/modals.js",
"../apps/common/embed/lib/view/SearchBar.js",
"../apps/presentationeditor/embed/js/SearchBar.js",
"../apps/presentationeditor/embed/js/ApplicationView.js",
"../apps/presentationeditor/embed/js/ApplicationController.js",
"../apps/presentationeditor/embed/js/application.js"

View file

@ -352,6 +352,8 @@
"../apps/common/embed/lib/view/LoadMask.js",
"../apps/common/embed/lib/view/modals.js",
"../apps/common/embed/lib/controller/modals.js",
"../apps/common/embed/lib/view/SearchBar.js",
"../apps/spreadsheeteditor/embed/js/SearchBar.js",
"../apps/spreadsheeteditor/embed/js/ApplicationView.js",
"../apps/spreadsheeteditor/embed/js/ApplicationController.js",
"../apps/spreadsheeteditor/embed/js/application.js"