Parcourir la source

fix: 内容编辑及注释模块调整修复

liutian il y a 7 mois
Parent
commit
d92d8e27a8

+ 4 - 4
packages/core/src/editor/content_edit_history_manager.js

@@ -16,7 +16,8 @@ export class ContentEditHistoryManager {
       return false
     }
 
-    return await this.messageHandler.sendWithPromise('CanRedo', this.editPagePtr)
+    const res = await this.messageHandler.sendWithPromise('CanRedo', this.editPagePtr)
+    return !!res
   }
 
   async canUndo() {
@@ -25,7 +26,8 @@ export class ContentEditHistoryManager {
       return false
     }
 
-    return await this.messageHandler.sendWithPromise('CanUndo', this.editPagePtr)
+    const res = await this.messageHandler.sendWithPromise('CanUndo', this.editPagePtr)
+    return !!res
   }
 
   async redo() {
@@ -42,7 +44,6 @@ export class ContentEditHistoryManager {
     const res = await this.messageHandler.sendWithPromise('Redo', this.editPagePtr)
     this.undoList.push(lastRedo)
     this.updateView(res)
-    return res
   }
 
   async undo() {
@@ -60,7 +61,6 @@ export class ContentEditHistoryManager {
     const canRedo = await this.canRedo()
     canRedo && this.redoList.push(lastUndo)
     this.updateView(res)
-    return res
   }
 
   async updateView(res) {

+ 12 - 1
packages/core/src/editor/image_editor.js

@@ -52,6 +52,7 @@ export class ImageEditor {
     this.imageUrl = null
     this.cropped = false
     this.removed = false
+    this.listener = null
 
     this.start = null
     this.end = null
@@ -434,6 +435,10 @@ export class ImageEditor {
       this.contentContainer.selectedFrameIndex = this.editAreaIndex
       this.container.append(this.outerLineContainer)
       this.eventBus.dispatch('changeRightPanelBtnDisabled', false)
+      this.eventBus.dispatch('contentBoxSelected', {
+        type: 'image',
+        pageNumber: this.pageViewer.pageIndex + 1,
+      })
     }
 
     if (this.mouseMoved) {
@@ -486,7 +491,8 @@ export class ImageEditor {
     const redo = document.getElementById('redo')
     redo && elements.push(redo)
 
-    onClickOutsideUp(elements, this.handleOutside.bind(this))
+    this.listener && document.removeEventListener(isMobileDevice ? 'touchend' : 'mouseup', this.listener)
+    this.listener = onClickOutsideUp(elements, this.handleOutside.bind(this))
   }
 
   async handleMouseMove (e) {
@@ -715,6 +721,11 @@ export class ImageEditor {
       if (!hasItem) {
         this.eventBus.dispatch('contentPropertyChange', { type: 'image', isOpen: false })
         this.eventBus.dispatch('changeRightPanelBtnDisabled', true)
+
+        this.eventBus.dispatch('contentBoxDeselected', {
+          type: 'image',
+          pageNumber: this.pageViewer.pageIndex + 1,
+        })
       }
     }, 1)
   }

+ 9 - 0
packages/core/src/editor/text_editor.js

@@ -513,6 +513,10 @@ export class TextEditor {
 
       this.contentContainer.selectedFrameIndex = this.editAreaIndex
       this.eventBus.dispatch('changeRightPanelBtnDisabled', false)
+      this.eventBus.dispatch('contentBoxSelected', {
+        type: 'text',
+        pageNumber: this.pageViewer.pageIndex + 1,
+      })
     }
 
     if (this.state === 1) {
@@ -863,6 +867,11 @@ export class TextEditor {
         if (!hasItem) {
           this.eventBus.dispatch('contentPropertyChange', { type: 'text', isOpen: false })
           this.eventBus.dispatch('changeRightPanelBtnDisabled', true)
+
+          this.eventBus.dispatch('contentBoxDeselected', {
+            type: 'text',
+            pageNumber: this.pageViewer.pageIndex + 1,
+          })
         }
       }, 1)
     }

+ 2 - 0
packages/core/src/ui_utils.js

@@ -1706,6 +1706,8 @@ const onClickOutsideUp = (el, cb) => {
   }
 
   document.addEventListener(isMobileDevice ? 'touchend' : 'mouseup', listener);
+
+  return listener
 }
 
 const pdfDateStringRegex = new RegExp(

+ 1 - 1
packages/webview/src/apis/disableElements.js

@@ -4,7 +4,7 @@ export default (store) => (dataElements) => {
     ...store.getActiveHeaderItems,
     ...store.getTools,
     ...store.getActiveRightHeaderItems,
-    ...store.getToolItems.annotation[0].tools,
+    ...store.getToolItems.annotation,
     ...store.getToolItems.form,
     ...store.getPopupItems('textPopup')
   ];

+ 1 - 1
packages/webview/src/apis/enableElements.js

@@ -4,7 +4,7 @@ export default (store) => (dataElements) => {
     ...store.getActiveHeaderItems,
     ...store.getTools,
     ...store.getActiveRightHeaderItems,
-    ...store.getToolItems.annotation[0].tools,
+    ...store.getToolItems.annotation,
     ...store.getToolItems.form,
     ...store.getPopupItems('textPopup')
   ];

+ 2 - 0
packages/webview/src/apis/index.js

@@ -8,6 +8,7 @@ import disableElements from './disableElements';
 import enableElements from './enableElements';
 import setHeaderItems from './setHeaderItems';
 import setActiveToolMode from './setActiveToolMode';
+import setActiveTool from './setActiveTool';
 import setLanguage from './setLanguage';
 import getPassword from './getPassword';
 import textPopup from './textPopup';
@@ -41,6 +42,7 @@ export default () => {
     setHeaderItems: setHeaderItems(useViewer),
     setActiveToolMode: setActiveToolMode(useViewer),
     setActiceToolMode: setActiveToolMode(useViewer),
+    setActiveTool: setActiveTool(useViewer, useDocument),
     setLanguage: setLanguage(useViewer),
     getPassword: getPassword(documentStore),
     textPopup: textPopup(viewerStore),

+ 29 - 0
packages/webview/src/apis/setActiveTool.js

@@ -0,0 +1,29 @@
+
+/**
+ * Sets the current active toolbar group.
+ * @method UI.setActiveTool
+ * @param {string} dataElement The dataElement. Default values are: note, ink, highlight
+ * @example
+WebViewer(...)
+  .then(function(instance) {
+    // Change the toolbar group to the `Forms` group
+    instance.UI.setActiveTool('note');
+ */
+
+export default (useViewer, useDocument) => (dataElement) => {
+  const toolMode = useViewer.getToolMode
+  if (toolMode) {
+    const tools = useViewer.getToolItems[toolMode]
+    const tool = tools.find(tool => tool.dataElement === dataElement)
+    if (!tool) {
+      console.warn('DataElement not match toolMode.');
+      return
+    }
+    if (tool.hidden) {
+      tool.hidden = false;
+    }
+    useDocument.setToolState(tool.element);
+  } else {
+    console.warn('DataElement not found.');
+  }
+}

+ 2 - 2
packages/webview/src/components/Annotate/Annotate.vue

@@ -1,5 +1,5 @@
 <template>
-  <template v-for="(tool, index) in item" :key="`${tool.type}-${tool.dataElement || index}`">
+  <template v-for="(tool, index) in items" :key="`${tool.type}-${tool.dataElement || index}`">
     <StickyNoteButton v-if="tool.type === 'note' && !tool.hidden" :data-element="tool.dataElement" />
     <div v-else-if="['highlight', 'underline', 'strikeout', 'squiggly'].includes(tool.type)" class="markup-container">
       <Button v-if="tool.type === 'highlight' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: markupActive && markupTool === 'highlight' }" @click.stop="changeMarkupTool('highlight')" :title="$t('header.highlight')"><Highlight /></Button>
@@ -65,7 +65,7 @@
   import core from '@/core'
   const { switchTool, switchAnnotationEditorMode } = core
 
-  const { item } = defineProps(['item'])
+  defineProps(['items'])
 
   const useDocument = useDocumentStore()
   const useViewer = useViewerStore()

+ 17 - 13
packages/webview/src/components/ContentEditorToolBar/ContentEditorToolBar.vue

@@ -1,18 +1,20 @@
 <template>
   <div class="edit-tool">
-    <Button class="operate" :class="{ active: activeTool === 'addText' }" @click="changeActiveTool('addText')" title="Add Text">
-      <AddText />{{ $t('header.addText') }}
-    </Button>
-    <Button class="operate" :class="{ active: activeTool === 'addImage' }" @click="changeActiveTool('addImage')" title="Add Image">
-      <AddImage />{{ $t('header.addImage') }}<input v-if="isMobileDevice" type="file" id="editorImageInput" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFile">
-    </Button>
-    <div class="divider pc"></div>
-    <Button class="history" id="undo" :class="{ disabled: !undoListLength }" :title="$t('header.undo')" @click="reset('undo')">
-      <EditBack />
-    </Button>
-    <Button class="history" id="redo" :class="{ disabled: !redoListLength }" :title="$t('header.redo')" @click="reset('redo')">
-      <EditGo />
-    </Button>
+    <template v-for="(item, index) in items" :key="index">
+      <Button v-if="item.type === 'addText'" :data-element="item.dataElement" class="operate" :class="{ active: activeTool === 'addText' }" @click="changeActiveTool('addText')" :title="$t(item.title)">
+        <AddText />{{ $t(item.title) }}
+      </Button>
+      <Button v-else-if="item.type === 'addImage'" :data-element="item.dataElement" class="operate" :class="{ active: activeTool === 'addImage' }" @click="changeActiveTool('addImage')" title="Add Image">
+        <AddImage />{{ $t(item.title) }}<input v-if="isMobileDevice" type="file" id="editorImageInput" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFile">
+      </Button>
+      <div v-else-if="item.type === 'divider'" :data-element="item.dataElement" class="divider pc"></div>
+      <Button v-else-if="item.type === 'undo'" :data-element="item.dataElement" class="history" id="undo" :class="{ disabled: !undoListLength }" :title="$t(item.title)" @click="reset('undo')">
+        <EditBack />
+      </Button>
+      <Button v-else-if="item.type === 'redo'" :data-element="item.dataElement" class="history" id="redo" :class="{ disabled: !redoListLength }" :title="$t(item.title)" @click="reset('redo')">
+        <EditGo />
+      </Button>
+    </template>
   </div>
 </template>
 
@@ -26,6 +28,8 @@ import { isMobileDevice } from '@/helpers/device'
 import core from '@/core'
 const { switchTool, switchAnnotationEditorMode, resetOperate } = core
 
+defineProps(['items'])
+
 const useDocument = useDocumentStore()
 const useViewer = useViewerStore()
 

+ 7 - 5
packages/webview/src/components/DocumentContainer/DocumentContainer.vue

@@ -160,11 +160,6 @@ async function handlePdf (pdf, filename = null) {
     useDocument.setPassword(pwd)
     useDocument.setCurrentPdfData(pdf, options)
     useDocument.setOutline(core.getOutlines())
-    const toolModeChanged = (mode) => {
-      if (mode === toolMode.value) return
-      useViewer.setActiveToolMode(mode)
-    }
-    core.addEvent('toolModeChanged', toolModeChanged)
   } catch (error) {
     console.log(error)
     if (error === 'invalid_file_error' || error === 'no_password_given' || error === 'incorrect_password') {
@@ -188,6 +183,12 @@ window.instance.initOptions = async (options) => {
   const webviewerMode = !!(options && options.webviewerServer) ? options.webviewerServer : 'Standalone'
   useViewer.setWebviewerMode(webviewerMode)
   if (!res) return
+
+  const toolModeChanged = (mode) => {
+    if (mode === toolMode.value) return
+    useViewer.setActiveToolMode(mode)
+  }
+  core.addEvent('toolModeChanged', toolModeChanged)
   useViewer.setVierified(res)
   useViewer.setLicense(getDocumentViewer()._license)
   const thumbnailView = document.querySelector('.thumbnail-view')
@@ -208,6 +209,7 @@ window.instance.initOptions = async (options) => {
   initialDoc = Array.isArray(initialDoc) ? initialDoc : [initialDoc]
   const activeTab = useViewer.activeTab || 0
   initialDoc = initialDoc[activeTab]
+
   if (initialDoc) {
     useViewer.setUpload(true)
     useViewer.setUploadLoading(true)

+ 6 - 7
packages/webview/src/components/Toolbar/Toolbar.vue

@@ -1,11 +1,12 @@
 <template>
   <div class="toolbar" :class="{ hidden: ['view', 'document'].includes(toolMode) || (toolMode === 'compare' && compareStatus !== 'finished'), security: toolMode === 'security', editor: toolMode === 'editor', disabled: isDisabledHeader}">
-    <template v-for="(item, index) in tools[toolMode]" :key="`${item.type}-${item.dataElement || index}`">
-      <!-- Annotation -->
-      <Annotate v-if="item.type === 'annotation'" :item="item.tools" />
-
+    <!-- Annotation -->
+    <Annotate v-if="toolMode === 'annotation'" :items="tools[toolMode]" />
+    <!-- Content Editor -->
+    <ContentEditorToolBar v-else-if="toolMode === 'editor'" :items="tools[toolMode]"/>
+    <template v-else v-for="(item, index) in tools[toolMode]" :key="`${item.type}-${item.dataElement || index}`">
       <!-- Form -->
-      <TextFieldButton v-else-if="item.type === 'textFieldButton' && !item.hidden" :item="item" :data-element="item.dataElement" />
+      <TextFieldButton v-if="item.type === 'textFieldButton' && !item.hidden" :item="item" :data-element="item.dataElement" />
       <CheckBoxButton v-else-if="item.type === 'checkBoxButton' && !item.hidden" :item="item" :data-element="item.dataElement" />
       <RadioButton v-else-if="item.type === 'radioButton' && !item.hidden" :item="item" :data-element="item.dataElement" />
       <ListBox v-else-if="item.type === 'listBox' && !item.hidden" :item="item" :data-element="item.dataElement" />
@@ -18,8 +19,6 @@
 
       <!-- Compare -->
       <ComparedToolbar v-else-if="item.type === 'comparedToolbar'" />
-      <!-- Content Editor -->
-      <ContentEditorToolBar v-else-if="item.type === 'contentEditorToolbar'" />
       <!-- Signature -->
       <SignatureToolBar v-else-if="item.type === 'signatureToolBar'" />
     </template>

+ 80 - 60
packages/webview/src/stores/modules/viewer.js

@@ -238,65 +238,61 @@ export const useViewerStore = defineStore({
     toolItems: {
       annotation: [
         {
-          type: 'annotation',
-          tools: [
-            {
-              type: 'note'
-            },
-            {
-              type: 'ink',
-              dataElement: 'ink'
-            },
-            {
-              type: 'highlight',
-              dataElement: 'highlight'
-            },
-            {
-              type: 'underline',
-              dataElement: 'underline'
-            },
-            {
-              type: 'strikeout',
-              dataElement: 'strikeout'
-            },
-            {
-              type: 'squiggly',
-              dataElement: 'squiggly'
-            },
-            {
-              type: 'circle',
-              dataElement: 'circle'
-            },
-            {
-              type: 'square',
-              dataElement: 'square'
-            },
-            {
-              type: 'arrow',
-              dataElement: 'arrow'
-            },
-            {
-              type: 'line',
-              dataElement: 'line'
-            },
-            {
-              type: 'freetext',
-              dataElement: 'freetext'
-            },
-            {
-              type: 'stamp',
-              dataElement: 'stamp'
-            },
-            {
-              type: 'image',
-              dataElement: 'image'
-            },
-            {
-              type: 'link',
-              dataElement: 'link'
-            },
-          ]
-        }
+          type: 'note',
+          dataElement: 'note'
+        },
+        {
+          type: 'ink',
+          dataElement: 'ink'
+        },
+        {
+          type: 'highlight',
+          dataElement: 'highlight'
+        },
+        {
+          type: 'underline',
+          dataElement: 'underline'
+        },
+        {
+          type: 'strikeout',
+          dataElement: 'strikeout'
+        },
+        {
+          type: 'squiggly',
+          dataElement: 'squiggly'
+        },
+        {
+          type: 'circle',
+          dataElement: 'circle'
+        },
+        {
+          type: 'square',
+          dataElement: 'square'
+        },
+        {
+          type: 'arrow',
+          dataElement: 'arrow'
+        },
+        {
+          type: 'line',
+          dataElement: 'line'
+        },
+        {
+          type: 'freetext',
+          dataElement: 'freetext'
+        },
+        {
+          type: 'stamp',
+          dataElement: 'stamp'
+        },
+        {
+          type: 'image',
+          dataElement: 'image'
+        },
+        {
+          type: 'link',
+          dataElement: 'link'
+        },
       ],
       form: [
         {
@@ -357,7 +353,31 @@ export const useViewerStore = defineStore({
       ],
       editor: [
         {
-          type: 'contentEditorToolbar'
+          type: 'addText',
+          dataElement: 'addText',
+          element: 'addText',
+          title: 'header.addText'
+        },
+        {
+          type: 'addImage',
+          dataElement: 'addImage',
+          element: 'addImage',
+          title: 'header.addImage'
+        },
+        {
+          type: 'divider',
+        },
+        {
+          type: 'undo',
+          dataElement: 'undo',
+          element: 'undo',
+          title: 'header.undo'
+        },
+        {
+          type: 'redo',
+          dataElement: 'redo',
+          element: 'redo',
+          title: 'header.redo'
         }
       ],
       sign: [