diff --git a/apps/presentationeditor/main/app/controller/LeftMenu.js b/apps/presentationeditor/main/app/controller/LeftMenu.js index 0e191aa88..fad0ff918 100644 --- a/apps/presentationeditor/main/app/controller/LeftMenu.js +++ b/apps/presentationeditor/main/app/controller/LeftMenu.js @@ -98,7 +98,9 @@ define([ 'SearchDialog': { 'hide': _.bind(this.onSearchDlgHide, this), 'search:back': _.bind(this.onQuerySearch, this, 'back'), - 'search:next': _.bind(this.onQuerySearch, this, 'next') + '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) @@ -117,6 +119,7 @@ define([ shortcuts: { 'command+shift+s,ctrl+shift+s': _.bind(this.onShortcut, this, 'save'), 'command+f,ctrl+f': _.bind(this.onShortcut, this, 'search'), + 'ctrl+h': _.bind(this.onShortcut, this, 'replace'), 'alt+f': _.bind(this.onShortcut, this, 'file'), 'esc': _.bind(this.onShortcut, this, 'escape'), /** coauthoring begin **/ @@ -136,6 +139,7 @@ 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) @@ -375,7 +379,7 @@ define([ onQuerySearch: function(d, w, opts) { if (opts.textsearch && opts.textsearch.length) { - if (!this.api.findText(opts.textsearch, d != 'back')) { + if (!this.api.findText(opts.textsearch, d != 'back', opts.matchcase)) { var me = this; Common.UI.info({ msg: this.textNoTextFound, @@ -387,14 +391,41 @@ define([ } }, - showSearchDlg: function(show) { + 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({})); + this.dlgSearch = (new Common.UI.SearchDialog({ + matchcase: true + })); } if (show) { - this.dlgSearch.isVisible() ? this.dlgSearch.focus() : - this.dlgSearch.show('no-replace'); + var mode = this.mode.isEdit ? (action || undefined) : 'no-replace'; + if (this.dlgSearch.isVisible()) { + this.dlgSearch.setMode(mode); + this.dlgSearch.focus(); + } else { + this.dlgSearch.show(mode); + } } else this.dlgSearch['hide'](); }, @@ -422,6 +453,17 @@ define([ // 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}); + } + }, + onApiServerDisconnect: function(enableDownload) { this.mode.isEdit = false; this.leftMenu.close(); @@ -515,11 +557,12 @@ define([ var previewPanel = PE.getController('Viewport').getView('DocumentPreview'); switch (s) { + case 'replace': case 'search': if ((!previewPanel || !previewPanel.isVisible()) && !this._state.no_slides) { Common.UI.Menu.Manager.hideAll(); var full_menu_pressed = this.leftMenu.btnAbout.pressed; - this.showSearchDlg(true); + 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); @@ -639,6 +682,8 @@ define([ newDocumentTitle : 'Unnamed document', requestEditRightsText : 'Requesting editing rights...', notcriticalErrorTitle: 'Warning', - txtUntitled: 'Untitled' + txtUntitled: 'Untitled', + textReplaceSuccess : 'Search has been done. {0} occurrences have been replaced', + textReplaceSkipped : 'The replacement has been made. {0} occurrences were skipped.' }, PE.Controllers.LeftMenu || {})); }); \ No newline at end of file diff --git a/apps/presentationeditor/main/locale/cs.json b/apps/presentationeditor/main/locale/cs.json index 2d1073623..fce1a0062 100644 --- a/apps/presentationeditor/main/locale/cs.json +++ b/apps/presentationeditor/main/locale/cs.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Rozlišovat malá a velká písmena", "Common.UI.SearchDialog.textReplaceDef": "Zadejte nahrazující text", "Common.UI.SearchDialog.textSearchStart": "Zde pište text", - "Common.UI.SearchDialog.textTitle": "Hledání", - "Common.UI.SearchDialog.textTitle2": "Hledání", + "Common.UI.SearchDialog.textTitle": "Najít a nahradit", + "Common.UI.SearchDialog.textTitle2": "Najít", "Common.UI.SearchDialog.textWholeWords": "Pouze celá slova", "Common.UI.SearchDialog.txtBtnHideReplace": "Skrýt náhradu", "Common.UI.SearchDialog.txtBtnReplace": "Nahradit", diff --git a/apps/presentationeditor/main/locale/de.json b/apps/presentationeditor/main/locale/de.json index 38e610a4c..18d5ed354 100644 --- a/apps/presentationeditor/main/locale/de.json +++ b/apps/presentationeditor/main/locale/de.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Groß-/Kleinschreibung beachten", "Common.UI.SearchDialog.textReplaceDef": "Geben Sie den Ersetzungstext ein", "Common.UI.SearchDialog.textSearchStart": "Geben Sie den Text hier ein", - "Common.UI.SearchDialog.textTitle": "Suche", - "Common.UI.SearchDialog.textTitle2": "Suche", + "Common.UI.SearchDialog.textTitle": "Suchen und ersetzen", + "Common.UI.SearchDialog.textTitle2": "Suchen", "Common.UI.SearchDialog.textWholeWords": "Nur ganze Wörter", "Common.UI.SearchDialog.txtBtnHideReplace": "Ersetzen verbergen", "Common.UI.SearchDialog.txtBtnReplace": "Ersetzen", diff --git a/apps/presentationeditor/main/locale/en.json b/apps/presentationeditor/main/locale/en.json index 5d9210bc1..dcb168231 100644 --- a/apps/presentationeditor/main/locale/en.json +++ b/apps/presentationeditor/main/locale/en.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Case sensitive", "Common.UI.SearchDialog.textReplaceDef": "Enter the replacement text", "Common.UI.SearchDialog.textSearchStart": "Enter your text here", - "Common.UI.SearchDialog.textTitle": "Search", - "Common.UI.SearchDialog.textTitle2": "Search", + "Common.UI.SearchDialog.textTitle": "Find and Replace", + "Common.UI.SearchDialog.textTitle2": "Find", "Common.UI.SearchDialog.textWholeWords": "Whole words only", "Common.UI.SearchDialog.txtBtnHideReplace": "Hide Replace", "Common.UI.SearchDialog.txtBtnReplace": "Replace", @@ -238,6 +238,8 @@ "PE.Controllers.LeftMenu.requestEditRightsText": "Requesting editing rights...", "PE.Controllers.LeftMenu.textNoTextFound": "The data you have been searching for could not be found. Please adjust your search options.", "PE.Controllers.LeftMenu.txtUntitled": "Untitled", + "PE.Controllers.LeftMenu.textReplaceSkipped": "The replacement has been made. {0} occurrences were skipped.", + "PE.Controllers.LeftMenu.textReplaceSuccess": "The search has been done. Occurrences replaced: {0}", "PE.Controllers.Main.applyChangesTextText": "Loading data...", "PE.Controllers.Main.applyChangesTitleText": "Loading Data", "PE.Controllers.Main.convertationTimeoutText": "Conversion timeout exceeded.", diff --git a/apps/presentationeditor/main/locale/es.json b/apps/presentationeditor/main/locale/es.json index 1782784b0..959516f90 100644 --- a/apps/presentationeditor/main/locale/es.json +++ b/apps/presentationeditor/main/locale/es.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Sensible a mayúsculas y minúsculas", "Common.UI.SearchDialog.textReplaceDef": "Introduzca el texto de sustitución", "Common.UI.SearchDialog.textSearchStart": "Introduzca su texto aquí", - "Common.UI.SearchDialog.textTitle": "Buscar", - "Common.UI.SearchDialog.textTitle2": "Buscar", + "Common.UI.SearchDialog.textTitle": "Encontrar y reemplazar", + "Common.UI.SearchDialog.textTitle2": "Encontrar", "Common.UI.SearchDialog.textWholeWords": "Sólo palabras completas", "Common.UI.SearchDialog.txtBtnHideReplace": "Esconder Sustitución", "Common.UI.SearchDialog.txtBtnReplace": "Reemplazar", diff --git a/apps/presentationeditor/main/locale/fr.json b/apps/presentationeditor/main/locale/fr.json index 0f5fe2b23..3e02770ec 100644 --- a/apps/presentationeditor/main/locale/fr.json +++ b/apps/presentationeditor/main/locale/fr.json @@ -20,7 +20,7 @@ "Common.UI.SearchDialog.textMatchCase": "Сas sensible", "Common.UI.SearchDialog.textReplaceDef": "Saisissez le texte de remplacement", "Common.UI.SearchDialog.textSearchStart": "Entrez votre texte ici", - "Common.UI.SearchDialog.textTitle": "Recherche", + "Common.UI.SearchDialog.textTitle": "Rechercher et remplacer", "Common.UI.SearchDialog.textTitle2": "Rechercher", "Common.UI.SearchDialog.textWholeWords": "Seulement les mots entiers", "Common.UI.SearchDialog.txtBtnHideReplace": "Masquer le champ de remplacement", diff --git a/apps/presentationeditor/main/locale/it.json b/apps/presentationeditor/main/locale/it.json index 820f1499a..b5f55cee2 100644 --- a/apps/presentationeditor/main/locale/it.json +++ b/apps/presentationeditor/main/locale/it.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Sensibile al maiuscolo/minuscolo", "Common.UI.SearchDialog.textReplaceDef": "Inserisci testo sostitutivo", "Common.UI.SearchDialog.textSearchStart": "Inserisci il tuo testo qui", - "Common.UI.SearchDialog.textTitle": "Ricerca", - "Common.UI.SearchDialog.textTitle2": "Ricerca", + "Common.UI.SearchDialog.textTitle": "Trova e sostituisci", + "Common.UI.SearchDialog.textTitle2": "Trova", "Common.UI.SearchDialog.textWholeWords": "Solo parole intere", "Common.UI.SearchDialog.txtBtnHideReplace": "Nascondi Sostituzione", "Common.UI.SearchDialog.txtBtnReplace": "Sostituisci", diff --git a/apps/presentationeditor/main/locale/ja.json b/apps/presentationeditor/main/locale/ja.json index c8c0e7e2a..e4f2bc921 100644 --- a/apps/presentationeditor/main/locale/ja.json +++ b/apps/presentationeditor/main/locale/ja.json @@ -20,7 +20,7 @@ "Common.UI.SearchDialog.textMatchCase": "大文字と小文字の区別", "Common.UI.SearchDialog.textReplaceDef": "代替テキストの挿入", "Common.UI.SearchDialog.textSearchStart": "ここでテキストを挿入してください。", - "Common.UI.SearchDialog.textTitle": "検索", + "Common.UI.SearchDialog.textTitle": "検索と置換", "Common.UI.SearchDialog.textTitle2": "検索", "Common.UI.SearchDialog.textWholeWords": "単語全体", "Common.UI.SearchDialog.txtBtnHideReplace": "変更を表示しない", diff --git a/apps/presentationeditor/main/locale/ko.json b/apps/presentationeditor/main/locale/ko.json index 9f5fe02bd..3ae82df9b 100644 --- a/apps/presentationeditor/main/locale/ko.json +++ b/apps/presentationeditor/main/locale/ko.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "대소 문자를 구분합니다", "Common.UI.SearchDialog.textReplaceDef": "대체 텍스트 입력", "Common.UI.SearchDialog.textSearchStart": "여기에 텍스트를 입력하십시오", - "Common.UI.SearchDialog.textTitle": "검색", - "Common.UI.SearchDialog.textTitle2": "검색", + "Common.UI.SearchDialog.textTitle": "찾기 및 바꾸기", + "Common.UI.SearchDialog.textTitle2": "찾기", "Common.UI.SearchDialog.textWholeWords": "전체 단어 만", "Common.UI.SearchDialog.txtBtnHideReplace": "바꾸기 숨기기", "Common.UI.SearchDialog.txtBtnReplace": "Replace", diff --git a/apps/presentationeditor/main/locale/lv.json b/apps/presentationeditor/main/locale/lv.json index 4aae36a83..6ccf9d94f 100644 --- a/apps/presentationeditor/main/locale/lv.json +++ b/apps/presentationeditor/main/locale/lv.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Case sensitive", "Common.UI.SearchDialog.textReplaceDef": "Enter the replacement text", "Common.UI.SearchDialog.textSearchStart": "Enter your text here", - "Common.UI.SearchDialog.textTitle": "Search", - "Common.UI.SearchDialog.textTitle2": "Search", + "Common.UI.SearchDialog.textTitle": "Find and Replace", + "Common.UI.SearchDialog.textTitle2": "Find", "Common.UI.SearchDialog.textWholeWords": "Whole words only", "Common.UI.SearchDialog.txtBtnHideReplace": "Nerādīt aizvietošanas lauku", "Common.UI.SearchDialog.txtBtnReplace": "Replace", diff --git a/apps/presentationeditor/main/locale/nl.json b/apps/presentationeditor/main/locale/nl.json index b4d3504ff..fb1804d0a 100644 --- a/apps/presentationeditor/main/locale/nl.json +++ b/apps/presentationeditor/main/locale/nl.json @@ -20,7 +20,7 @@ "Common.UI.SearchDialog.textMatchCase": "Hoofdlettergevoelig", "Common.UI.SearchDialog.textReplaceDef": "Voer de vervangende tekst in", "Common.UI.SearchDialog.textSearchStart": "Voer hier uw tekst in", - "Common.UI.SearchDialog.textTitle": "Zoeken", + "Common.UI.SearchDialog.textTitle": "Zoeken en vervangen", "Common.UI.SearchDialog.textTitle2": "Zoeken", "Common.UI.SearchDialog.textWholeWords": "Alleen hele woorden", "Common.UI.SearchDialog.txtBtnHideReplace": "Vervanging verbergen", diff --git a/apps/presentationeditor/main/locale/pl.json b/apps/presentationeditor/main/locale/pl.json index 9db5e81f2..d20794544 100644 --- a/apps/presentationeditor/main/locale/pl.json +++ b/apps/presentationeditor/main/locale/pl.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Rozróżniana wielkość liter", "Common.UI.SearchDialog.textReplaceDef": "Wprowadź tekst zastępczy", "Common.UI.SearchDialog.textSearchStart": "Wprowadź tekst tutaj", - "Common.UI.SearchDialog.textTitle": "Wyszukiwanie", - "Common.UI.SearchDialog.textTitle2": "Wyszukiwanie", + "Common.UI.SearchDialog.textTitle": "Znajdź i zamień", + "Common.UI.SearchDialog.textTitle2": "Znajdź", "Common.UI.SearchDialog.textWholeWords": "Tylko całe słowa", "Common.UI.SearchDialog.txtBtnHideReplace": "Ukryj Zamień", "Common.UI.SearchDialog.txtBtnReplace": "Zamienić", diff --git a/apps/presentationeditor/main/locale/pt.json b/apps/presentationeditor/main/locale/pt.json index cf365dbe5..c151ef2a2 100644 --- a/apps/presentationeditor/main/locale/pt.json +++ b/apps/presentationeditor/main/locale/pt.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Diferenciar maiúsculas de minúsculas", "Common.UI.SearchDialog.textReplaceDef": "Inserir o texto de substituição", "Common.UI.SearchDialog.textSearchStart": "Inserir seu texto aqui", - "Common.UI.SearchDialog.textTitle": "Pesquisar", - "Common.UI.SearchDialog.textTitle2": "Pesquisar", + "Common.UI.SearchDialog.textTitle": "Localizar e substituir", + "Common.UI.SearchDialog.textTitle2": "Localizar", "Common.UI.SearchDialog.textWholeWords": "Palavras inteiras apenas", "Common.UI.SearchDialog.txtBtnHideReplace": "Ocultar Substituição", "Common.UI.SearchDialog.txtBtnReplace": "Substituir", diff --git a/apps/presentationeditor/main/locale/ru.json b/apps/presentationeditor/main/locale/ru.json index de8f9ed0a..a118c1431 100644 --- a/apps/presentationeditor/main/locale/ru.json +++ b/apps/presentationeditor/main/locale/ru.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "С учетом регистра", "Common.UI.SearchDialog.textReplaceDef": "Введите текст для замены", "Common.UI.SearchDialog.textSearchStart": "Введите здесь текст", - "Common.UI.SearchDialog.textTitle": "Поиск", - "Common.UI.SearchDialog.textTitle2": "Поиск", + "Common.UI.SearchDialog.textTitle": "Поиск и замена", + "Common.UI.SearchDialog.textTitle2": "Найти", "Common.UI.SearchDialog.textWholeWords": "Только слово целиком", "Common.UI.SearchDialog.txtBtnHideReplace": "Скрыть поле замены", "Common.UI.SearchDialog.txtBtnReplace": "Заменить", diff --git a/apps/presentationeditor/main/locale/sk.json b/apps/presentationeditor/main/locale/sk.json index 909ac2f7e..070e77234 100644 --- a/apps/presentationeditor/main/locale/sk.json +++ b/apps/presentationeditor/main/locale/sk.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Rozlišovať veľkosť písmen", "Common.UI.SearchDialog.textReplaceDef": "Zadať náhradný text", "Common.UI.SearchDialog.textSearchStart": "Zadať svoj text tu", - "Common.UI.SearchDialog.textTitle": "Hľadať", - "Common.UI.SearchDialog.textTitle2": "Hľadať", + "Common.UI.SearchDialog.textTitle": "Nájsť a nahradiť", + "Common.UI.SearchDialog.textTitle2": "Nájsť", "Common.UI.SearchDialog.textWholeWords": "Len celé slová", "Common.UI.SearchDialog.txtBtnHideReplace": "Skryť náhradu", "Common.UI.SearchDialog.txtBtnReplace": "Nahradiť", diff --git a/apps/presentationeditor/main/locale/sl.json b/apps/presentationeditor/main/locale/sl.json index 6d0936570..0a82297f3 100644 --- a/apps/presentationeditor/main/locale/sl.json +++ b/apps/presentationeditor/main/locale/sl.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Občutljiv na velike in male črke", "Common.UI.SearchDialog.textReplaceDef": "Vnesi nadomestno besedilo", "Common.UI.SearchDialog.textSearchStart": "Svoje besedilo vnesite tu", - "Common.UI.SearchDialog.textTitle": "Iskanje", - "Common.UI.SearchDialog.textTitle2": "Iskanje", + "Common.UI.SearchDialog.textTitle": "Najdi in zamenjaj", + "Common.UI.SearchDialog.textTitle2": "Najdi", "Common.UI.SearchDialog.textWholeWords": "Le cele besede", "Common.UI.SearchDialog.txtBtnReplace": "Zamenjaj", "Common.UI.SearchDialog.txtBtnReplaceAll": "Zamenjaj vse", diff --git a/apps/presentationeditor/main/locale/tr.json b/apps/presentationeditor/main/locale/tr.json index 1a06d3c31..b954ad4c8 100644 --- a/apps/presentationeditor/main/locale/tr.json +++ b/apps/presentationeditor/main/locale/tr.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Büyük küçük harfe duyarlı", "Common.UI.SearchDialog.textReplaceDef": "Yerine geçecek metini giriniz", "Common.UI.SearchDialog.textSearchStart": "Metninizi buraya giriniz", - "Common.UI.SearchDialog.textTitle": "Ara", - "Common.UI.SearchDialog.textTitle2": "Ara", + "Common.UI.SearchDialog.textTitle": "Bul ve Değiştir", + "Common.UI.SearchDialog.textTitle2": "Bul", "Common.UI.SearchDialog.textWholeWords": "Sadece tam kelimeler", "Common.UI.SearchDialog.txtBtnHideReplace": "Değiştirmeyi Gizle", "Common.UI.SearchDialog.txtBtnReplace": "Değiştir", diff --git a/apps/presentationeditor/main/locale/uk.json b/apps/presentationeditor/main/locale/uk.json index cb26cefb2..62c2a2e16 100644 --- a/apps/presentationeditor/main/locale/uk.json +++ b/apps/presentationeditor/main/locale/uk.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "Чутливість до регістору символів", "Common.UI.SearchDialog.textReplaceDef": "Введіть текст заміни", "Common.UI.SearchDialog.textSearchStart": "Введіть свій текст тут", - "Common.UI.SearchDialog.textTitle": "Пошук", - "Common.UI.SearchDialog.textTitle2": "Пошук", + "Common.UI.SearchDialog.textTitle": "Знайти та перемістити", + "Common.UI.SearchDialog.textTitle2": "Знайти", "Common.UI.SearchDialog.textWholeWords": "Тільки цілі слова", "Common.UI.SearchDialog.txtBtnHideReplace": "Сховати заміни", "Common.UI.SearchDialog.txtBtnReplace": "Замінити", diff --git a/apps/presentationeditor/main/locale/vi.json b/apps/presentationeditor/main/locale/vi.json index ff26f1f63..88b92520a 100644 --- a/apps/presentationeditor/main/locale/vi.json +++ b/apps/presentationeditor/main/locale/vi.json @@ -20,7 +20,7 @@ "Common.UI.SearchDialog.textMatchCase": "Phân biệt chữ hoa chữ thường", "Common.UI.SearchDialog.textReplaceDef": "Nhập văn bản thay thế", "Common.UI.SearchDialog.textSearchStart": "Nhập từ khóa của bạn ở đây", - "Common.UI.SearchDialog.textTitle": "Tìm kiếm", + "Common.UI.SearchDialog.textTitle": "Tìm và Thay thế", "Common.UI.SearchDialog.textTitle2": "Tìm kiếm", "Common.UI.SearchDialog.textWholeWords": "Chỉ toàn bộ từ", "Common.UI.SearchDialog.txtBtnHideReplace": "Ẩn Thay thế", diff --git a/apps/presentationeditor/main/locale/zh.json b/apps/presentationeditor/main/locale/zh.json index 2a7109e0c..a4815fc03 100644 --- a/apps/presentationeditor/main/locale/zh.json +++ b/apps/presentationeditor/main/locale/zh.json @@ -20,8 +20,8 @@ "Common.UI.SearchDialog.textMatchCase": "区分大小写", "Common.UI.SearchDialog.textReplaceDef": "输入替换文字", "Common.UI.SearchDialog.textSearchStart": "在这里输入你的文字", - "Common.UI.SearchDialog.textTitle": "搜索", - "Common.UI.SearchDialog.textTitle2": "搜索", + "Common.UI.SearchDialog.textTitle": "查找和替换", + "Common.UI.SearchDialog.textTitle2": "发现", "Common.UI.SearchDialog.textWholeWords": "只有整个字", "Common.UI.SearchDialog.txtBtnHideReplace": "隐藏替换", "Common.UI.SearchDialog.txtBtnReplace": "替换", diff --git a/apps/presentationeditor/mobile/app/controller/Search.js b/apps/presentationeditor/mobile/app/controller/Search.js index 81ce45a43..ea53666bc 100644 --- a/apps/presentationeditor/mobile/app/controller/Search.js +++ b/apps/presentationeditor/mobile/app/controller/Search.js @@ -81,7 +81,8 @@ define([ 'Search': { 'searchbar:show' : this.onSearchbarShow, 'searchbar:hide' : this.onSearchbarHide, - 'searchbar:render' : this.onSearchbarRender + 'searchbar:render' : this.onSearchbarRender, + 'searchbar:showsettings': this.onSearchbarSettings } }); }, @@ -130,7 +131,8 @@ define([ onSearchbarRender: function(bar) { var me = this, - searchString = Common.SharedSettings.get('search-search') || ''; + searchString = Common.SharedSettings.get('search-search') || '', + replaceString = Common.SharedSettings.get('search-replace')|| ''; me.searchBar = uiApp.searchbar('.searchbar.document .searchbar.search', { customSearch: true, @@ -139,13 +141,46 @@ define([ onClear : _.bind(me.onSearchClear, me) }); + me.replaceBar = uiApp.searchbar('.searchbar.document .searchbar.replace', { + customSearch: true, + onSearch : _.bind(me.onReplaceChange, me), + onEnable : _.bind(me.onReplaceEnable, me), + onClear : _.bind(me.onReplaceClear, me) + }); + me.searchPrev = $('.searchbar.document .prev'); me.searchNext = $('.searchbar.document .next'); + me.replaceBtn = $('.searchbar.document .link.replace'); me.searchPrev.single('click', _.bind(me.onSearchPrev, me)); me.searchNext.single('click', _.bind(me.onSearchNext, me)); + me.replaceBtn.single('click', _.bind(me.onReplace, me)); + + $$('.searchbar.document .link.replace').on('taphold', _.bind(me.onReplaceAll, me)); me.searchBar.search(searchString); + me.replaceBar.search(replaceString); + }, + + onSearchbarSettings: function (view) { + var strictBool = function (settingName) { + var value = Common.SharedSettings.get(settingName); + return !_.isUndefined(value) && (value === true); + }; + + var me = this, + isReplace = strictBool('search-is-replace'), + isCaseSensitive = strictBool('search-case-sensitive'), + $pageSettings = $('.page[data-page=search-settings]'), + $inputType = $pageSettings.find('input[name=search-type]'), + $inputCase = $pageSettings.find('#search-case-sensitive input:checkbox'); + + $inputType.val([isReplace ? 'replace' : 'search']); + $inputCase.prop('checked', isCaseSensitive); + + // init events + $inputType.single('change', _.bind(me.onTypeChange, me)); + $inputCase.single('change', _.bind(me.onCaseClick, me)); }, onSearchbarShow: function(bar) { @@ -153,7 +188,7 @@ define([ }, onSearchEnable: function (bar) { - // + this.replaceBar.container.removeClass('searchbar-active'); }, onSearchbarHide: function(bar) { @@ -166,7 +201,7 @@ define([ Common.SharedSettings.set('search-search', search.query); - _.each([me.searchPrev, me.searchNext], function(btn) { + _.each([me.searchPrev, me.searchNext, me.replaceBtn], function(btn) { btn.toggleClass('disabled', isEmpty); }); }, @@ -177,6 +212,21 @@ define([ // document.activeElement.blur(); }, + onReplaceChange: function(replace) { + var me = this, + isEmpty = (replace.query.trim().length < 1); + + Common.SharedSettings.set('search-replace', replace.query); + }, + + onReplaceEnable: function (bar) { + this.searchBar.container.removeClass('searchbar-active'); + }, + + onReplaceClear: function(replace) { + Common.SharedSettings.set('search-replace', ''); + }, + onSearchPrev: function(btn) { this.onQuerySearch(this.searchBar.query, 'back'); }, @@ -185,9 +235,37 @@ define([ this.onQuerySearch(this.searchBar.query, 'next'); }, + onReplace: function (btn) { + this.onQueryReplace(this.searchBar.query, this.replaceBar.query); + }, + + onReplaceAll: function (e) { + var me = this, + popover = [ + '
', + '
', + '', + '
', + '
' + ].join(''); + + popover = uiApp.popover(popover, $$(e.currentTarget)); + + $('#replace-all').single('click', _.bind(function () { + me.onQueryReplaceAll(this.searchBar.query, this.replaceBar.query); + uiApp.closeModal(popover); + }, me)) + }, + onQuerySearch: function(query, direction) { + var matchcase = Common.SharedSettings.get('search-case-sensitive') || false; + if (query && query.length) { - if (!this.api.findText(query, direction != 'back')) { + if (!this.api.findText(query, direction != 'back', matchcase)) { var me = this; uiApp.alert( '', @@ -200,9 +278,48 @@ define([ } }, + onQueryReplace: function(search, replace) { + var matchcase = Common.SharedSettings.get('search-case-sensitive') || false; + + if (search && search.length) { + if (!this.api.asc_replaceText(search, replace, false, matchcase)) { + var me = this; + uiApp.alert( + '', + me.textNoTextFound, + function () { + me.searchBar.input.focus(); + } + ); + } + } + }, + + onQueryReplaceAll: function(search, replace) { + var matchcase = Common.SharedSettings.get('search-case-sensitive') || false; + + if (search && search.length) { + this.api.asc_replaceText(search, replace, true, matchcase); + } + }, + + onTypeChange: function (e) { + var me = this, + $target = $(e.currentTarget), + isReplace = ($target.val() === 'replace'); + + Common.SharedSettings.set('search-is-replace', isReplace); + $('.searchbar.document').toggleClass('replace', isReplace); + }, + + onCaseClick: function (e) { + Common.SharedSettings.set('search-case-sensitive', $(e.currentTarget).is(':checked')); + }, + // API handlers - textNoTextFound : 'Text not found' + textNoTextFound : 'Text not found', + textReplaceAll: 'Replace All' } })(), PE.Controllers.Search || {})) }); \ No newline at end of file diff --git a/apps/presentationeditor/mobile/app/template/Search.template b/apps/presentationeditor/mobile/app/template/Search.template index c19a04bb2..2b4076cd7 100644 --- a/apps/presentationeditor/mobile/app/template/Search.template +++ b/apps/presentationeditor/mobile/app/template/Search.template @@ -2,19 +2,92 @@
+
+ + +
+ +
+
+ <% if (isEdit) { %> +
+
    +
  • + +
  • +
  • + +
  • +
+
+ <% } %> +
+
    +
  • +
    +
    +
    <%= scope.textCase %>
    +
    + +
    +
    +
    +
  • +
diff --git a/apps/presentationeditor/mobile/app/view/Search.js b/apps/presentationeditor/mobile/app/view/Search.js index 73e9a3c02..37f18643c 100644 --- a/apps/presentationeditor/mobile/app/view/Search.js +++ b/apps/presentationeditor/mobile/app/view/Search.js @@ -68,7 +68,7 @@ define([ }, initEvents: function() { - // + $('#search-settings').single('click', _.bind(this.showSettings, this)); }, // Render layout @@ -88,6 +88,57 @@ define([ this.render(); }, + showSettings: function (e) { + var me = this; + + uiApp.closeModal(); + + if (Common.SharedSettings.get('phone')) { + me.picker = $$(uiApp.popup([ + ''].join('') + )) + } else { + me.picker = uiApp.popover([ + '
', + '
', + '
', + '
', + '', + '
', + '
', + '
'].join(''), + $$('#search-settings') + ); + + // Prevent hide overlay. Conflict popover and modals. + var $overlay = $('.modal-overlay'); + + $$(me.picker).on('opened', function () { + $overlay.on('removeClass', function () { + if (!$overlay.hasClass('modal-overlay-visible')) { + $overlay.addClass('modal-overlay-visible') + } + }); + }).on('close', function () { + $overlay.off('removeClass'); + $overlay.removeClass('modal-overlay-visible') + }); + } + + if (Common.SharedSettings.get('android')) { + $$('.view.search-settings-view.navbar-through').removeClass('navbar-through').addClass('navbar-fixed'); + $$('.view.search-settings-view .navbar').prependTo('.view.search-settings-view > .pages > .page'); + } + + me.fireEvent('searchbar:showsettings', me); + }, + showSearch: function () { var me = this, searchBar = $$('.searchbar.document'); @@ -95,6 +146,10 @@ define([ if (searchBar.length < 1) { $(me.el).find('.pages .page').first().prepend(_layout.find('#search-panel-view').html()); + // Show replace mode if needed + var isReplace = Common.SharedSettings.get('search-is-replace'); + $('.searchbar.document').toggleClass('replace', !_.isUndefined(isReplace) && (isReplace === true)); + me.fireEvent('searchbar:render', me); me.fireEvent('searchbar:show', me); @@ -133,7 +188,13 @@ define([ } }, - textSearch: 'Search' + textFind: 'Find', + textFindAndReplace: 'Find and Replace', + textDone: 'Done', + textSearch: 'Search', + textReplace: 'Replace', + textCase: 'Case sensitive', + textHighlight: 'Highlight results' } })(), PE.Views.Search || {})) }); \ No newline at end of file diff --git a/apps/presentationeditor/mobile/app/view/Settings.js b/apps/presentationeditor/mobile/app/view/Settings.js index 40084d3a0..ed1a83fd4 100644 --- a/apps/presentationeditor/mobile/app/view/Settings.js +++ b/apps/presentationeditor/mobile/app/view/Settings.js @@ -221,7 +221,8 @@ define([ textSlideSize: 'Slide Size', mniSlideStandard: 'Standard (4:3)', mniSlideWide: 'Widescreen (16:9)', - textPoweredBy: 'Powered by' + textPoweredBy: 'Powered by', + textFindAndReplace: 'Find and Replace' } })(), PE.Views.Settings || {})) }); \ No newline at end of file diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index b7e512bed..c7d3eb8db 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -213,6 +213,7 @@ "PE.Controllers.Main.warnNoLicenseUsers": "This version of ONLYOFFICE Editors has certain limitations for concurrent users.
If you need more please consider purchasing a commercial license.", "PE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.", "PE.Controllers.Search.textNoTextFound": "Text not Found", + "PE.Controllers.Search.textReplaceAll": "Replace All", "PE.Controllers.Settings.notcriticalErrorTitle": "Warning", "PE.Controllers.Settings.txtLoading": "Loading...", "PE.Controllers.Toolbar.dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to await the autosave of the document. Click 'Leave this Page' to discard all the unsaved changes.", @@ -423,6 +424,11 @@ "PE.Views.EditText.textSmallCaps": "Small Caps", "PE.Views.EditText.textStrikethrough": "Strikethrough", "PE.Views.EditText.textSubscript": "Subscript", + "PE.Views.Search.textCase": "Case sensitive", + "PE.Views.Search.textDone": "Done", + "PE.Views.Search.textFind": "Find", + "PE.Views.Search.textFindAndReplace": "Find and Replace", + "PE.Views.Search.textReplace": "Replace", "PE.Views.Search.textSearch": "Search", "PE.Views.Settings.mniSlideStandard": "Standard (4:3)", "PE.Views.Settings.mniSlideWide": "Widescreen (16:9)", @@ -437,6 +443,7 @@ "PE.Views.Settings.textEditPresent": "Edit Presentation", "PE.Views.Settings.textEmail": "email", "PE.Views.Settings.textFind": "Find", + "PE.Views.Settings.textFindAndReplace": "Find and Replace", "PE.Views.Settings.textHelp": "Help", "PE.Views.Settings.textLoading": "Loading...", "PE.Views.Settings.textPoweredBy": "Powered by", diff --git a/apps/presentationeditor/mobile/resources/css/app-ios.css b/apps/presentationeditor/mobile/resources/css/app-ios.css index bce01f9a0..fd0900f8a 100644 --- a/apps/presentationeditor/mobile/resources/css/app-ios.css +++ b/apps/presentationeditor/mobile/resources/css/app-ios.css @@ -6239,6 +6239,16 @@ html.pixel-ratio-3 .document-menu .list-block li:last-child li .item-inner:after background: url('../../../../common/mobile/resources/img/about/onlyoffice.svg') no-repeat center; margin-top: 20px; } +.tablet .searchbar.document.replace .center .searchbar:first-child { + margin-right: 10px; +} +.tablet .searchbar.document.replace .center .replace { + display: flex; +} +.tablet .searchbar.document.replace .right .replace { + display: flex; + margin: 0 10px; +} .tablet .searchbar.document .center { width: 100%; } @@ -6246,9 +6256,30 @@ html.pixel-ratio-3 .document-menu .list-block li:last-child li .item-inner:after background: inherit; padding: 0; } +.tablet .searchbar.document .center .replace { + display: none; +} .tablet .searchbar.document .right .prev { margin-left: 0; } +.tablet .searchbar.document .right .replace { + display: none; +} +.phone .searchbar.document.replace { + height: 88px; +} +.phone .searchbar.document.replace .left { + margin-top: -44px; +} +.phone .searchbar.document.replace .center .searchbar-input { + margin: 8px 0; +} +.phone .searchbar.document.replace .center .replace { + display: block; +} +.phone .searchbar.document.replace .right > .replace { + display: flex; +} .phone .searchbar.document .left, .phone .searchbar.document .center, .phone .searchbar.document .right { @@ -6264,9 +6295,15 @@ html.pixel-ratio-3 .document-menu .list-block li:last-child li .item-inner:after .phone .searchbar.document .center .searchbar:after { content: none; } +.phone .searchbar.document .center .replace { + display: none; +} .phone .searchbar.document .right > p { margin: 0; } +.phone .searchbar.document .right > .replace { + display: none; +} .searchbar.document { background: #e4e4e6; } diff --git a/apps/presentationeditor/mobile/resources/css/app-material.css b/apps/presentationeditor/mobile/resources/css/app-material.css index 068a5713a..281461beb 100644 --- a/apps/presentationeditor/mobile/resources/css/app-material.css +++ b/apps/presentationeditor/mobile/resources/css/app-material.css @@ -5838,8 +5838,14 @@ html.phone .document-menu .list-block .item-link { .about .logo { background: url('../../../../common/mobile/resources/img/about/onlyoffice.svg') no-repeat center; } -.tablet .searchbar.document .left { - min-width: 15px; +.tablet .searchbar.document.replace .center > .replace { + display: flex; +} +.tablet .searchbar.document.replace .right .replace { + display: flex; +} +.tablet .searchbar.document.replace .link.replace { + font-size: 16px; } .tablet .searchbar.document .center { width: 100%; @@ -5853,14 +5859,32 @@ html.phone .document-menu .list-block .item-link { .tablet .searchbar.document .center .searchbar.search { padding: 0; } +.tablet .searchbar.document .center > .replace { + display: none; +} +.tablet .searchbar.document .right .replace { + display: none; +} +.phone .searchbar.document.replace { + height: 96px; +} +.phone .searchbar.document.replace .link.replace { + font-size: 16px; +} +.phone .searchbar.document.replace .left { + margin-top: -48px; +} +.phone .searchbar.document.replace .center .replace { + display: block; +} +.phone .searchbar.document.replace .right > .replace { + display: flex; +} .phone .searchbar.document .left, .phone .searchbar.document .center, .phone .searchbar.document .right { flex-direction: column; } -.phone .searchbar.document .left { - min-width: 15px; -} .phone .searchbar.document .center { width: 100%; margin: 0; @@ -5869,12 +5893,18 @@ html.phone .document-menu .list-block .item-link { .phone .searchbar.document .center .searchbar { padding: 0; } +.phone .searchbar.document .center .replace { + display: none; +} .phone .searchbar.document .right > p { margin: 0; } .phone .searchbar.document .right > p a.link { height: 48px; } +.phone .searchbar.document .right > .replace { + display: none; +} i.icon.icon-expand-up { width: 17px; height: 17px; diff --git a/apps/presentationeditor/mobile/resources/less/ios/_search.less b/apps/presentationeditor/mobile/resources/less/ios/_search.less index 3d1a59f69..389fd54c2 100644 --- a/apps/presentationeditor/mobile/resources/less/ios/_search.less +++ b/apps/presentationeditor/mobile/resources/less/ios/_search.less @@ -1,6 +1,27 @@ // Search .tablet { + // Replace mode + .searchbar.document.replace { + .center { + .searchbar:first-child { + margin-right: 10px; + } + + .replace { + display: flex; + } + } + + .right { + .replace { + display: flex; + margin: 0 10px; + } + } + } + + // Search mode .searchbar.document { .center { width: 100%; @@ -9,17 +30,51 @@ background: inherit; padding: 0; } + + .replace { + display: none; + } } .right { .prev { margin-left: 0; } + + .replace { + display: none; + } } } } .phone { + // Replace mode + .searchbar.document.replace { + height: 88px; + + .left { + margin-top: -44px; + } + + .center { + .searchbar-input { + margin: 8px 0; + } + + .replace { + display: block; + } + } + + .right { + > .replace { + display: flex; + } + } + } + + // Search mode .searchbar.document { .left, .center, @@ -38,12 +93,20 @@ content: none; } } + + .replace { + display: none; + } } .right { > p { margin: 0; } + + > .replace { + display: none; + } } } } diff --git a/apps/presentationeditor/mobile/resources/less/material/_search.less b/apps/presentationeditor/mobile/resources/less/material/_search.less index b2b0bc97e..42e5d041f 100644 --- a/apps/presentationeditor/mobile/resources/less/material/_search.less +++ b/apps/presentationeditor/mobile/resources/less/material/_search.less @@ -1,11 +1,27 @@ // Search .tablet { - .searchbar.document { - .left { - min-width: 15px; + // Replace mode + .searchbar.document.replace { + .center { + > .replace { + display: flex; + } } + .right { + .replace { + display: flex; + } + } + + .link.replace { + font-size: 16px; + } + } + + // Search mode + .searchbar.document { .center { width: 100%; display: flex; @@ -19,6 +35,16 @@ padding: 0; } } + + > .replace { + display: none; + } + } + + .right { + .replace { + display: none; + } } } } @@ -26,6 +52,32 @@ @phoneSearchHeight: 48px; .phone { + // Replace mode + .searchbar.document.replace { + height: @phoneSearchHeight * 2; + + .link.replace { + font-size: 16px; + } + + .left { + margin-top: -@phoneSearchHeight; + } + + .center { + .replace { + display: block; + } + } + + .right { + > .replace { + display: flex; + } + } + } + + // Search mode .searchbar.document { .left, .center, @@ -34,7 +86,7 @@ } .left { - min-width: 15px; + //min-width: 15px; } .center { @@ -45,6 +97,10 @@ .searchbar { padding: 0; } + + .replace { + display: none; + } } .right { @@ -55,6 +111,10 @@ height: @phoneSearchHeight; } } + + > .replace { + display: none; + } } } } \ No newline at end of file