diff --git a/apps/common/main/lib/component/InputField.js b/apps/common/main/lib/component/InputField.js
index fecc5c2922..c474c2dd2b 100644
--- a/apps/common/main/lib/component/InputField.js
+++ b/apps/common/main/lib/component/InputField.js
@@ -394,6 +394,7 @@ define([
title : errors.join('\n'),
placement : 'cursor'
});
+ errorBadge.tooltip('show');
if (modalParents.length > 0) {
errorBadge.data('bs.tooltip').tip().css('z-index', parseInt(modalParents.css('z-index')) + 10);
diff --git a/apps/common/main/lib/component/Window.js b/apps/common/main/lib/component/Window.js
index eaff31f1f7..0c403fd040 100644
--- a/apps/common/main/lib/component/Window.js
+++ b/apps/common/main/lib/component/Window.js
@@ -646,7 +646,7 @@ define([
var arrBtns = {ok: this.okButtonText, cancel: this.cancelButtonText,
yes: this.yesButtonText, no: this.noButtonText,
- close: this.closeButtonText};
+ close: this.closeButtonText, apply: this.applyButtonText, doNotApply: this.doNotApplyButtonText};
if (options.buttons && _.isArray(options.buttons)) {
if (options.primary==undefined)
diff --git a/apps/common/main/lib/view/TextInputDialog.js b/apps/common/main/lib/view/TextInputDialog.js
index 2698e41809..c818c0cd9d 100644
--- a/apps/common/main/lib/view/TextInputDialog.js
+++ b/apps/common/main/lib/view/TextInputDialog.js
@@ -138,6 +138,7 @@ define([], function () { 'use strict';
if (state == 'ok') {
if (this.inputLabel.checkValidate() !== true) {
this.inputLabel.cmpEl.find('input').focus();
+ this.inputLabel.showError(this.inputLabel.checkValidate())
return;
}
}
diff --git a/apps/pdfeditor/main/app/controller/RedactTab.js b/apps/pdfeditor/main/app/controller/RedactTab.js
index 51fb4a692d..7778d2fd77 100644
--- a/apps/pdfeditor/main/app/controller/RedactTab.js
+++ b/apps/pdfeditor/main/app/controller/RedactTab.js
@@ -93,22 +93,119 @@ define([
'redact:start' : this.onStartRedact.bind(this),
'redact:apply' : this.onApplyRedact.bind(this),
'redact:page' : this.onRedactCurrentPage.bind(this),
- // 'smartart:mouseenter': this.mouseenterSmartArt,
- // 'smartart:mouseleave': this.mouseleaveSmartArt,
+ 'redact:pages' : this.onRedactPages.bind(this),
+ },
+ 'Toolbar': {
+ 'tab:active': this.onActiveTab
}
});
},
onApplyRedact: function() {
- this.api.ApplyRedact();
+ Common.UI.warning({
+ width: 500,
+ msg: this.textApplyRedact,
+ buttons: ['yes', 'no'],
+ primary: 'yes',
+ callback: _.bind(function(btn) {
+ if (btn == 'yes') {
+ this.api.ApplyRedact();
+ }
+ }, this)
+ });
},
onStartRedact: function(isMarkMode) {
- this.api.SetRedactTool(isMarkMode)
+ this.api.SetRedactTool(isMarkMode);
},
onRedactCurrentPage: function() {
- this.api.RedactPages([0]);
+ this.api.RedactPages([this.api.getCurrentPage()]);
+ },
+
+ onRedactPages: function() {
+ const self = this;
+ const countPages = this.api.getCountPages();
+
+ (new Common.Views.TextInputDialog({
+ title: this.textRedactPages,
+ label: this.textEnterPageRange,
+ value: `1-${countPages}`,
+ description: this.textEnterRangeDescription,
+ inputFixedConfig: {fixedWidth: 40},
+ inputConfig: {
+ maxLength: 20,
+ allowBlank: false,
+ validation: function(value) {
+ const singlePage = /^\d+$/;
+ const range = /^(\d+)-(\d+)$/;
+
+ if (singlePage.test(value)) {
+ const page = parseInt(value, 10);
+ if (page < 1 || page > countPages) return `Page must be between 1 and ${countPages}`;
+ return true;
+ }
+
+ const match = value.match(range);
+ if (match) {
+ const start = parseInt(match[1], 10);
+ const end = parseInt(match[2], 10);
+ if (start < 1 || end < 1 || start > countPages || end > countPages) {
+ return `Pages must be between 1 and ${countPages}`;
+ }
+ if (start > end) return 'Start page must be less than or equal to end page';
+ return true;
+ }
+
+ return 'Invalid format. Use single number or range with dash, e.g., 2 or 2-6';
+ }
+ },
+ handler: function(result, value) {
+ if (result === 'ok') {
+ let pages = [];
+
+ if (value.includes('-')) {
+ const [start, end] = value.split('-').map(p => parseInt(p, 10));
+ for (let i = start; i <= end; i++) {
+ pages.push(i - 1);
+ }
+ } else {
+ pages.push(parseInt(value, 10));
+ }
+
+ self.api.RedactPages(pages);
+ }
+ }
+ })).show();
+ },
+
+ onActiveTab: function(tab) {
+ Common.UI.TooltipManager.showTip('mark-for-redaction');
+ const isMarked = this.api.HasRedact();
+ if (isMarked) {
+ Common.UI.warning({
+ width: 500,
+ msg: this.textUnappliedRedactions,
+ buttons: ['apply', 'doNotApply', 'cancel'],
+ primary: 'apply',
+ callback: _.bind(function(btn) {
+ if (btn == 'apply') {
+ this.api.ApplyRedact();
+ this.api.SetRedactTool(false);
+ this.view.btnMarkForRedact.toggle(false);
+ } else if (btn == 'doNotApply') {
+ this.api.RemoveAllRedact();
+ this.api.SetRedactTool(false);
+ this.view.btnMarkForRedact.toggle(false);
+ } else if (btn == 'cancel') {
+ // Common.NotificationCenter.trigger('tab:set-active', 'red');
+ this.toolbar.toolbar.setTab('red')
+ }}, this)
+ });
+ } else {
+ this.view.btnMarkForRedact.toggle(false);
+ this.api.SetRedactTool(false);
+ }
},
SetDisabled: function(state) {
@@ -138,6 +235,12 @@ define([
me.view.setEvents();
});
}
+ Common.UI.TooltipManager.addTips({
+ 'mark-for-redaction' : {name: 'help-tip-mark-for-redaction', placement: 'bottom-right', offset: {x: 10, y: 0}, text: this.tipMarkForRedaction, header: this.tipMarkForRedactionHeader, target: '#slot-btn-markredact',
+ automove: true, next: 'apply-redaction', maxwidth: 270, closable: false, isNewFeature: true},
+ 'apply-redaction' : {name: 'help-tip-apply-redaction', placement: 'bottom-left', offset: {x: 10, y: 0}, text: this.tipApplyRedaction, header: this.tipApplyRedactionHeader, target: '#slot-btn-apply-redactions',
+ automove: true, maxwidth: 270, closable: false, isNewFeature: true},
+ });
},
onDocumentReady: function() {
@@ -146,7 +249,6 @@ define([
// this.getApplication().getController('Common.Controllers.ExternalDiagramEditor').setApi(this.api).loadConfig({config:this.mode, customization: this.mode.customization});
// this.getApplication().getController('Common.Controllers.ExternalOleEditor').setApi(this.api).loadConfig({config:this.mode, customization: this.mode.customization});
-
Common.Utils.lockControls(Common.enumLock.disableOnStart, false, {array: this.view.lockedControls});
}
},
@@ -155,51 +257,6 @@ define([
},
onApiFocusObject: function(selectedObjects) {
- var pr, i = -1, type,
- paragraph_locked = false,
- no_paragraph = true,
- in_chart = false,
- page_deleted = false;
-
- while (++i < selectedObjects.length) {
- type = selectedObjects[i].get_ObjectType();
- pr = selectedObjects[i].get_ObjectValue();
-
- if (type === Asc.c_oAscTypeSelectElement.Paragraph) {
- paragraph_locked = pr.get_Locked();
- no_paragraph = false;
- } else if (type == Asc.c_oAscTypeSelectElement.Image || type == Asc.c_oAscTypeSelectElement.Shape || type == Asc.c_oAscTypeSelectElement.Chart || type == Asc.c_oAscTypeSelectElement.Table) {
- if (type == Asc.c_oAscTypeSelectElement.Table ||
- type == Asc.c_oAscTypeSelectElement.Shape && !pr.get_FromImage() && !pr.get_FromChart()) {
- no_paragraph = false;
- }
- if (type == Asc.c_oAscTypeSelectElement.Chart) {
- in_chart = true;
- }
- } else if (type == Asc.c_oAscTypeSelectElement.PdfPage) {
- page_deleted = pr.asc_getDeleteLock();
- }
- }
-
- // if (in_chart !== this._state.in_chart) {
- // this.view.btnInsertChart.updateHint(in_chart ? this.view.tipChangeChart : this.view.tipInsertChart);
- // this._state.in_chart = in_chart;
- // }
-
- if (this._state.prcontrolsdisable !== paragraph_locked) {
- if (this._state.activated) this._state.prcontrolsdisable = paragraph_locked;
- Common.Utils.lockControls(Common.enumLock.paragraphLock, paragraph_locked===true, {array: this.view.lockedControls});
- }
-
- if (this._state.no_paragraph !== no_paragraph) {
- if (this._state.activated) this._state.no_paragraph = no_paragraph;
- Common.Utils.lockControls(Common.enumLock.noParagraphSelected, no_paragraph, {array: this.view.lockedControls});
- }
-
- if (page_deleted !== undefined && this._state.pagecontrolsdisable !== page_deleted) {
- if (this._state.activated) this._state.pagecontrolsdisable = page_deleted;
- Common.Utils.lockControls(Common.enumLock.pageDeleted, page_deleted, {array: this.view.lockedControls});
- }
},
}, PDFE.Controllers.RedactTab || {}));
diff --git a/apps/pdfeditor/main/app/controller/Toolbar.js b/apps/pdfeditor/main/app/controller/Toolbar.js
index 381ade43a2..77d606fe40 100644
--- a/apps/pdfeditor/main/app/controller/Toolbar.js
+++ b/apps/pdfeditor/main/app/controller/Toolbar.js
@@ -1509,20 +1509,19 @@ define([
me.api.UpdateInterfaceState();
}, 50);
- // var tab = {caption: toolbar.textTabInsert, action: 'ins', extcls: this.mode.isEdit ? 'canedit' : '', layoutname: 'toolbar-insert', dataHintTitle: 'I'};
- // var instab = this.getApplication().getController('InsTab');
- // instab.setApi(this.api).setConfig({toolbar: this, mode: this.mode});
- // toolbar.addTab(tab, instab.createToolbarPanel(), 1);
- // instab.onAppReady(this.mode);
- // setTimeout(function(){
- // instab.onDocumentReady();
- // }, 50);
+ var tab = {caption: toolbar.textTabInsert, action: 'ins', extcls: this.mode.isEdit ? 'canedit' : '', layoutname: 'toolbar-insert', dataHintTitle: 'I'};
+ var instab = this.getApplication().getController('InsTab');
+ instab.setApi(this.api).setConfig({toolbar: this, mode: this.mode});
+ toolbar.addTab(tab, instab.createToolbarPanel(), 1);
+ instab.onAppReady(this.mode);
+ setTimeout(function(){
+ instab.onDocumentReady();
+ }, 50);
var tab = {caption: 'Redact', action: 'red', extcls: this.mode.isEdit ? 'canedit' : '', layoutname: 'toolbar-redact', dataHintTitle: 'X'};
var redacttab = this.getApplication().getController('RedactTab');
- console.log(redacttab)
redacttab.setApi(this.api).setConfig({toolbar: this, mode: this.mode});
- toolbar.addTab(tab, redacttab.createToolbarPanel(), 1);
+ toolbar.addTab(tab, redacttab.createToolbarPanel(), 2);
redacttab.onAppReady(this.mode);
setTimeout(function(){
redacttab.onDocumentReady();
@@ -1543,6 +1542,7 @@ define([
if (this.mode.isPDFEdit || toolbar.isTabActive('ins') || toolbar.isTabActive('forms'))
toolbar.setTab('home');
toolbar.setVisible('ins', this.mode.isPDFEdit);
+ toolbar.setVisible('red', this.mode.isPDFEdit);
toolbar.setVisible('forms', this.mode.isPDFEdit && this.mode.canFeatureForms);
$host.find('.annotate').toggleClass('hidden', this.mode.isPDFEdit);
$host.find('.pdfedit').toggleClass('hidden', !this.mode.isPDFEdit);
diff --git a/apps/pdfeditor/main/app/view/RedactTab.js b/apps/pdfeditor/main/app/view/RedactTab.js
index 6f7f0285b6..6e2051c054 100644
--- a/apps/pdfeditor/main/app/view/RedactTab.js
+++ b/apps/pdfeditor/main/app/view/RedactTab.js
@@ -152,7 +152,9 @@ define([
]
}).on('item:click', function (menu, item, e) {
if (item.value === 'current') {
- me.fireEvent('redact:page', [item.value]);
+ me.fireEvent('redact:page');
+ } else {
+ me.fireEvent('redact:pages')
}
})
);
diff --git a/apps/pdfeditor/main/locale/en.json b/apps/pdfeditor/main/locale/en.json
index 2cbe7cf48d..3297f1cc23 100644
--- a/apps/pdfeditor/main/locale/en.json
+++ b/apps/pdfeditor/main/locale/en.json
@@ -94,6 +94,8 @@
"Common.UI.Themes.txtThemeModernLight": "Modern Light",
"Common.UI.Themes.txtThemeSystem": "Same as system",
"Common.UI.Window.cancelButtonText": "Cancel",
+ "Common.UI.Window.applyButtonText": "Apply",
+ "Common.UI.Window.doNotApplyButtonText": "Dont't apply",
"Common.UI.Window.closeButtonText": "Close",
"Common.UI.Window.noButtonText": "No",
"Common.UI.Window.okButtonText": "OK",
@@ -865,6 +867,15 @@
"PDFE.Controllers.InsTab.txtSymbol_vdots": "Vertical ellipsis",
"PDFE.Controllers.InsTab.txtSymbol_xsi": "Xi",
"PDFE.Controllers.InsTab.txtSymbol_zeta": "Zeta",
+ "PDFE.Controllers.RedactTab.textApplyRedact": "Redacted information will be permanently removed from this document. Once you save it, information couldn't be retrieved anymore",
+ "PDFE.Controllers.RedactTab.textRedactPages": "Redact pages",
+ "PDFE.Controllers.RedactTab.textEnterPageRange": "Enter page range for redaction",
+ "PDFE.Controllers.RedactTab.textEnterRangeDescription": "e.g. 1, 2, 8-11",
+ "PDFE.Controllers.RedactTab.textUnappliedRedactions": "This document contains redaction marks that yet not have been applied.
Until you select “Apply Redactions” these marks can be removed and information can be retrieved",
+ "PDFE.Controllers.RedactTab.tipMarkForRedaction": "Use these tools to mark, search, and redact sensitive content in your PDF",
+ "PDFE.Controllers.RedactTab.tipApplyRedaction": "Apply and save all redactions. Unsaved redactions can still be undone.",
+ "PDFE.Controllers.RedactTab.tipApplyRedactionHeader": "Apply redactions",
+ "PDFE.Controllers.RedactTab.tipMarkForRedactionHeader": "Mark for redactions",
"PDFE.Controllers.LeftMenu.leavePageText": "All unsaved changes in this document will be lost.
Click \"Cancel\" then \"Save\" to save them. Click \"OK\" to discard all the unsaved changes.",
"PDFE.Controllers.LeftMenu.newDocumentTitle": "Unnamed document",
"PDFE.Controllers.LeftMenu.notcriticalErrorTitle": "Warning",