use pdf viewer instead of instance & extract some methods

This commit is contained in:
Dan Percic 2022-03-10 16:15:41 +02:00
parent f8bbc25c0d
commit 6b38de9892
9 changed files with 195 additions and 270 deletions

View File

@ -3,12 +3,12 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { PermissionsService } from '@services/permissions.service';
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { AnnotationActionsService } from '../../services/annotation-actions.service';
import { WebViewerInstance } from '@pdftron/webviewer';
import { UserService } from '@services/user.service';
import { AnnotationReferencesService } from '../../services/annotation-references.service';
import { MultiSelectService } from '../../services/multi-select.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { HelpModeService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
import { PdfViewer } from '../../services/pdf-viewer.service';
export const AnnotationButtonTypes = {
dark: 'dark',
@ -26,7 +26,6 @@ export class AnnotationActionsComponent implements OnChanges {
@Input() buttonType: AnnotationButtonType = AnnotationButtonTypes.dark;
@Input() tooltipPosition: 'before' | 'above' = 'before';
@Input() canPerformAnnotationActions: boolean;
@Input() viewer: WebViewerInstance;
@Input() alwaysVisible: boolean;
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
annotationPermissions: AnnotationPermissions;
@ -37,6 +36,7 @@ export class AnnotationActionsComponent implements OnChanges {
readonly annotationReferencesService: AnnotationReferencesService,
readonly helpModeService: HelpModeService,
private readonly _userService: UserService,
private readonly _pdf: PdfViewer,
private readonly _state: FilePreviewStateService,
private readonly _permissionsService: PermissionsService,
) {}
@ -53,8 +53,8 @@ export class AnnotationActionsComponent implements OnChanges {
}
get viewerAnnotations() {
if (this.viewer?.Core.annotationManager) {
return this._annotations.map(a => this.viewer?.Core.annotationManager?.getAnnotationById(a.id));
if (this._pdf.annotationManager) {
return this._annotations.map(a => this._pdf.annotationManager.getAnnotationById(a.id));
} else {
return [];
}
@ -76,6 +76,10 @@ export class AnnotationActionsComponent implements OnChanges {
return ScrollableParentViews.ANNOTATIONS_LIST;
}
get helpModeKey() {
return this.annotations[0]?.typeLabel?.split('.')[1];
}
async ngOnChanges(): Promise<void> {
await this._setPermissions();
}
@ -95,28 +99,28 @@ export class AnnotationActionsComponent implements OnChanges {
hideAnnotation($event: MouseEvent) {
$event.stopPropagation();
this.viewer.Core.annotationManager.hideAnnotations(this.viewerAnnotations);
this.viewer.Core.annotationManager.deselectAllAnnotations();
this._pdf.annotationManager.hideAnnotations(this.viewerAnnotations);
this._pdf.annotationManager.deselectAllAnnotations();
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, true);
}
showAnnotation($event: MouseEvent) {
$event.stopPropagation();
this.viewer.Core.annotationManager.showAnnotations(this.viewerAnnotations);
this.viewer.Core.annotationManager.deselectAllAnnotations();
this._pdf.annotationManager.showAnnotations(this.viewerAnnotations);
this._pdf.annotationManager.deselectAllAnnotations();
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, false);
}
resize($event: MouseEvent) {
this.annotationActionsService.resize($event, this.viewer, this.annotations[0]);
this.annotationActionsService.resize($event, this.annotations[0]);
}
acceptResize($event: MouseEvent) {
return this.annotationActionsService.acceptResize($event, this.viewer, this.annotations[0], this.annotationsChanged);
return this.annotationActionsService.acceptResize($event, this.annotations[0], this.annotationsChanged);
}
cancelResize($event: MouseEvent) {
this.annotationActionsService.cancelResize($event, this.viewer, this.annotations[0], this.annotationsChanged);
this.annotationActionsService.cancelResize($event, this.annotations[0], this.annotationsChanged);
}
private async _setPermissions() {
@ -127,8 +131,4 @@ export class AnnotationActionsComponent implements OnChanges {
this.annotations,
);
}
get helpModeKey() {
return this.annotations[0]?.typeLabel?.split('.')[1];
}
}

View File

@ -60,7 +60,6 @@
[alwaysVisible]="true"
[annotations]="selectedAnnotations"
[canPerformAnnotationActions]="state.isWritable$ | async"
[viewer]="viewer"
buttonType="primary"
tooltipPosition="above"
></redaction-annotation-actions>

View File

@ -25,7 +25,6 @@ import {
shareLast,
} from '@iqser/common-ui';
import { PermissionsService } from '@services/permissions.service';
import { WebViewerInstance } from '@pdftron/webviewer';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { File } from '@red/domain';
@ -36,6 +35,7 @@ import { SkippedService } from '../../services/skipped.service';
import { FilePreviewStateService } from '../../services/file-preview-state.service';
import { ViewModeService } from '../../services/view-mode.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { PdfViewer } from '../../services/pdf-viewer.service';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
@ -56,7 +56,6 @@ export class FileWorkloadComponent {
@Input() dialogRef: MatDialogRef<unknown>;
@Input() file!: File;
@Input() annotationActionsTemplate: TemplateRef<unknown>;
@Input() viewer: WebViewerInstance;
@Output() readonly selectAnnotations = new EventEmitter<AnnotationWrapper[]>();
@Output() readonly deselectAnnotations = new EventEmitter<AnnotationWrapper[]>();
@Output() readonly selectPage = new EventEmitter<number>();
@ -73,6 +72,7 @@ export class FileWorkloadComponent {
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
constructor(
private readonly _pdf: PdfViewer,
readonly filterService: FilterService,
readonly skippedService: SkippedService,
readonly state: FilePreviewStateService,

View File

@ -66,7 +66,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
@Output() readonly manualAnnotationRequested = new EventEmitter<ManualRedactionEntryWrapper>();
@Output() readonly pageChanged = new EventEmitter<number>();
@Output() readonly keyUp = new EventEmitter<KeyboardEvent>();
@Output() readonly viewerReady = new EventEmitter<WebViewerInstance>();
@Output() readonly viewerReady = new EventEmitter<void>();
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
@ViewChild('viewer', { static: true }) viewer: ElementRef;
@ViewChild('compareFileInput', { static: true }) compareFileInput: ElementRef;
@ -118,6 +118,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.addActiveScreenSubscription = this.stateService.blob$
.pipe(
withLatestFrom(this.stateService.file$),
tap(() => (this.pdf.ready = false)),
tap(([blob, file]) => this._loadDocument(blob, file)),
)
.subscribe();
@ -473,8 +474,8 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
this.documentViewer.getTool('AnnotationCreateRectangle').setStyles({
StrokeThickness: 2,
StrokeColor: this._annotationDrawService.getAndConvertColor(this.instance, dossierTemplateId, 'manual'),
FillColor: this._annotationDrawService.getAndConvertColor(this.instance, dossierTemplateId, 'manual'),
StrokeColor: this._annotationDrawService.getAndConvertColor(dossierTemplateId, 'manual'),
FillColor: this._annotationDrawService.getAndConvertColor(dossierTemplateId, 'manual'),
Opacity: 0.6,
});
}
@ -519,12 +520,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
]);
}
const actions = this._annotationActionsService.getViewerAvailableActions(
this.instance,
this.dossier,
annotationWrappers,
this.annotationsChanged,
);
const actions = this._annotationActionsService.getViewerAvailableActions(this.dossier, annotationWrappers, this.annotationsChanged);
this.instance.UI.annotationPopup.add(actions);
}
@ -545,7 +541,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private _addRectangleManualRedaction() {
const activeAnnotation = this.annotationManager.getSelectedAnnotations()[0];
const activePage = activeAnnotation.getPageNumber();
const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation, this.instance)];
const quads = [this._annotationDrawService.annotationToQuads(activeAnnotation)];
const manualRedaction = this._getManualRedaction({ [activePage]: quads });
this._cleanUpSelectionAndButtonState();
@ -696,7 +692,7 @@ export class PdfViewerComponent extends AutoUnsubscribe implements OnInit, OnCha
private _setReadyAndInitialState(): void {
this._ngZone.run(() => {
this.pdf.ready = true;
this.viewerReady.emit(this.instance);
this.viewerReady.emit();
const routePageNumber: number = this._activatedRoute.snapshot.queryParams.page;
this.pageChanged.emit(routePageNumber || 1);
this._setInitialDisplayMode();

View File

@ -66,7 +66,7 @@
(keyUp)="handleKeyEvent($event); handleArrowEvent($event)"
(manualAnnotationRequested)="openManualAnnotationDialog($event)"
(pageChanged)="viewerPageChanged($event)"
(viewerReady)="viewerReady($event)"
(viewerReady)="viewerReady()"
*ngIf="displayPdfViewer"
[annotations]="visibleAnnotations"
[canPerformActions]="canPerformAnnotationActions$ | async"
@ -98,7 +98,6 @@
[dialogRef]="dialogRef"
[file]="file"
[selectedAnnotations]="selectedAnnotations"
[viewer]="activeViewer"
></redaction-file-workload>
</div>
</div>
@ -110,7 +109,6 @@
(annotationsChanged)="annotationsChangedByReviewAction($event)"
[annotations]="[annotation]"
[canPerformAnnotationActions]="canPerformAnnotationActions$ | async"
[viewer]="activeViewer"
></redaction-annotation-actions>
</ng-template>

View File

@ -1,7 +1,6 @@
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { PdfViewerComponent } from './components/pdf-viewer/pdf-viewer.component';
import { Core } from '@pdftron/webviewer';
import {
AutoUnsubscribe,
CircleButtonTypes,
@ -71,13 +70,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
selectedAnnotations: AnnotationWrapper[] = [];
displayPdfViewer = false;
activeViewerPage: number = null;
@ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent;
readonly canPerformAnnotationActions$: Observable<boolean>;
readonly fileId = this.stateService.fileId;
readonly dossierId = this.stateService.dossierId;
readonly file$ = this.stateService.file$.pipe(tap(file => this._fileUpdated(file)));
ready = false;
private _instance: WebViewerInstance;
private _lastPage: string;
@ViewChild('fileWorkloadComponent') private readonly _workloadComponent: FileWorkloadComponent;
@ -140,10 +137,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
return this._fileData ? this._fileData.allAnnotations : [];
}
get activeViewer(): WebViewerInstance {
return this._instance;
}
private get _fileData(): FileDataModel {
return this.stateService.fileData;
}
@ -162,19 +155,19 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
async updateViewMode(): Promise<void> {
if (!this._instance?.Core.documentViewer.getDocument()) {
if (!this._pdf.ready) {
return;
}
const textHighlightAnnotationIds = this._fileData.textHighlightAnnotations.map(a => a.id);
const textHighlightAnnotations = this._getAnnotations((a: Core.Annotations.Annotation) =>
const textHighlightAnnotations = this._pdf.getAnnotations((a: Core.Annotations.Annotation) =>
textHighlightAnnotationIds.includes(a.Id),
);
this._pdf.deleteAnnotations(textHighlightAnnotations);
const ocrAnnotationIds = this._fileData.allAnnotations.filter(a => a.isOCR).map(a => a.id);
const annotations = this._getAnnotations(a => a.getCustomData('redact-manager'));
const annotations = this._pdf.getAnnotations(a => a.getCustomData('redact-manager'));
const redactions = annotations.filter(a => a.getCustomData('redaction'));
switch (this._viewModeService.viewMode) {
@ -185,8 +178,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
.filter(a => !ocrAnnotationIds.includes(a.Id));
const nonStandardEntries = annotations.filter(a => a.getCustomData('changeLogRemoved') === 'true');
this._setAnnotationsOpacity(standardEntries, true);
this._show(standardEntries);
this._hide(nonStandardEntries);
this._pdf.showAnnotations(standardEntries);
this._pdf.hideAnnotations(nonStandardEntries);
break;
}
case 'DELTA': {
@ -194,30 +187,24 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
const nonChangeLogEntries = annotations.filter(a => a.getCustomData('changeLog') === 'false');
this._setAnnotationsColor(redactions, 'annotationColor');
this._setAnnotationsOpacity(changeLogEntries, true);
this._show(changeLogEntries);
this._hide(nonChangeLogEntries);
this._pdf.showAnnotations(changeLogEntries);
this._pdf.hideAnnotations(nonChangeLogEntries);
break;
}
case 'REDACTED': {
const nonRedactionEntries = annotations.filter(a => a.getCustomData('redaction') === 'false');
this._setAnnotationsOpacity(redactions);
this._setAnnotationsColor(redactions, 'redactionColor');
this._show(redactions);
this._hide(nonRedactionEntries);
this._pdf.showAnnotations(redactions);
this._pdf.hideAnnotations(nonRedactionEntries);
break;
}
case 'TEXT_HIGHLIGHTS': {
this._loadingService.start();
const textHighlights = await firstValueFrom(this._pdfViewerDataService.loadTextHighlightsFor(this.dossierId, this.fileId));
this._hide(annotations);
this._pdf.hideAnnotations(annotations);
this._fileData.textHighlights = textHighlights;
await this._annotationDrawService.drawAnnotations(
this.activeViewer,
this._fileData.textHighlightAnnotations,
this.dossierId,
this.fileId,
false,
);
await this._annotationDrawService.drawAnnotations(this._fileData.textHighlightAnnotations);
this._loadingService.stop();
}
}
@ -264,8 +251,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
rebuildFilters(deletePreviousAnnotations = false): void {
const startTime = new Date().getTime();
if (deletePreviousAnnotations) {
const annotationsToDelete = this._instance?.Core.annotationManager?.getAnnotationsList() || [];
this._pdf.deleteAnnotations(annotationsToDelete);
this._pdf.deleteAnnotations();
console.log(`[REDACTION] Delete previous annotations time: ${new Date().getTime() - startTime} ms`);
}
@ -303,18 +289,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
selectAnnotations(annotations?: AnnotationWrapper[]) {
if (annotations) {
const annotationsToSelect = this.multiSelectService.isActive ? [...this.selectedAnnotations, ...annotations] : annotations;
this.viewerComponent?.pdf?.selectAnnotations(annotationsToSelect, this.multiSelectService.isActive);
this._pdf.selectAnnotations(annotationsToSelect, this.multiSelectService.isActive);
} else {
this.viewerComponent?.pdf?.deselectAllAnnotations();
this._pdf.deselectAllAnnotations();
}
}
deselectAnnotations(annotations: AnnotationWrapper[]) {
this.viewerComponent.pdf.deselectAnnotations(annotations);
this._pdf.deselectAnnotations(annotations);
}
selectPage(pageNumber: number) {
this.viewerComponent.pdf.navigateToPage(pageNumber);
this._pdf.navigateToPage(pageNumber);
this._workloadComponent?.scrollAnnotationsToPage(pageNumber, 'always');
this._lastPage = pageNumber.toString();
}
@ -333,9 +319,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
const response = new ManualAnnotationResponse(entryWrapper, addAnnotationResponse);
if (response?.annotationId) {
const annotation = this._instance.Core.annotationManager.getAnnotationById(
response.manualRedactionEntryWrapper.rectId,
);
const annotation = this._pdf.annotationManager.getAnnotationById(response.manualRedactionEntryWrapper.rectId);
this._pdf.deleteAnnotations([annotation]);
const distinctPages = manualRedactionEntryWrapper.manualRedactionEntry.positions
.map(p => p.page)
@ -409,19 +393,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
};
await this._router.navigate([], extras);
this._setActiveViewerPage();
this.activeViewerPage = this._pdf.currentPage;
this._changeDetectorRef.markForCheck();
}
async viewerReady($event: WebViewerInstance) {
this._instance = $event;
async viewerReady() {
this.ready = true;
await this._stampPDF();
await this._reloadAnnotations();
this._setExcludedPageStyles();
this._instance.Core.documentViewer.addEventListener('pageComplete', () => {
this._pdf.documentViewer.addEventListener('pageComplete', () => {
this._setExcludedPageStyles();
});
@ -430,7 +413,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
if (pageNumber) {
setTimeout(() => {
this.selectPage(parseInt(pageNumber, 10));
this._setActiveViewerPage();
this.activeViewerPage = this._pdf.currentPage;
this._scrollViews();
this._changeDetectorRef.markForCheck();
this._loadingService.stop();
@ -474,27 +457,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
#deactivateMultiSelect(): void {
this.multiSelectService.deactivate();
this.viewerComponent?.pdf?.deselectAllAnnotations();
this._pdf.deselectAllAnnotations();
this.handleAnnotationSelected([]);
}
private _setActiveViewerPage() {
const currentPage = this._instance?.Core.documentViewer?.getCurrentPage();
if (!currentPage) {
this.activeViewerPage = 1;
} else {
this.activeViewerPage = this._viewModeService.isCompare
? currentPage % 2 === 0
? currentPage / 2
: (currentPage + 1) / 2
: currentPage;
}
}
private _setExcludedPageStyles() {
const file = this._filesMapService.get(this.dossierId, this.fileId);
setTimeout(() => {
const iframeDoc = this._instance.UI.iframeWindow.document;
const iframeDoc = this._pdf.UI.iframeWindow.document;
const pageContainer = iframeDoc.getElementById(`pageWidgetContainer${this.activeViewerPage}`);
if (pageContainer) {
if (file.excludedPages.includes(this.activeViewerPage)) {
@ -507,15 +477,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private async _stampPDF() {
if (!this._instance?.Core.documentViewer.getDocument()) {
if (!this._pdf.ready) {
return;
}
const pdfNet = this._instance.Core.PDFNet;
const pdfDoc = await this._instance.Core.documentViewer.getDocument().getPDFDoc();
const pdfDoc = await this._pdf.documentViewer.getDocument().getPDFDoc();
const file = this._filesMapService.get(this.dossierId, this.fileId);
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
await clearStamps(pdfDoc, pdfNet, allPages);
await clearStamps(pdfDoc, this._pdf.PDFNet, allPages);
if (this._viewModeService.isRedacted) {
const dossier = this._dossiersService.find(this.dossierId);
@ -525,8 +494,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
} else {
await this._stampExcludedPages(pdfDoc, file.excludedPages);
}
this._instance.Core.documentViewer.refreshAll();
this._instance.Core.documentViewer.updateView([this.activeViewerPage], this.activeViewerPage);
this._pdf.documentViewer.refreshAll();
this._pdf.documentViewer.updateView([this.activeViewerPage], this.activeViewerPage);
this._changeDetectorRef.markForCheck();
}
@ -534,7 +503,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
const watermark = await this._watermarkService.getWatermark(dossierTemplateId).toPromise();
await stampPDFPage(
document,
this._instance.Core.PDFNet,
this._pdf.PDFNet,
watermark.text,
watermark.fontSize,
watermark.fontType,
@ -549,7 +518,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
if (excludedPages && excludedPages.length > 0) {
await stampPDFPage(
document,
this._instance.Core.PDFNet,
this._pdf.PDFNet,
this._translateService.instant('file-preview.excluded-from-redaction') as string,
17,
'courier',
@ -642,7 +611,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private _deleteAnnotations(annotationsToDelete?: AnnotationWrapper[]) {
if (!this._instance?.Core.documentViewer.getDocument()) {
if (!this._pdf.ready) {
return;
}
@ -655,7 +624,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private async _cleanupAndRedrawAnnotations(newAnnotationsFilter?: (annotation: AnnotationWrapper) => boolean) {
if (!this._instance?.Core.documentViewer.getDocument()) {
if (!this._pdf.ready) {
return;
}
@ -669,20 +638,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
if (currentFilters) {
this._handleDeltaAnnotationFilters(currentFilters, this.visibleAnnotations);
}
await this._redrawAnnotations(newAnnotations);
await this._annotationDrawService.drawAnnotations(newAnnotations);
console.log(`[REDACTION] Annotations redraw time: ${new Date().getTime() - startTime} ms for ${newAnnotations.length} annotations`);
}
private _redrawAnnotations(annotations = this.allAnnotations) {
return this._annotationDrawService.drawAnnotations(
this._instance,
annotations,
this.fileId,
this.dossierId,
!!this._viewModeService.isCompare,
);
}
private _handleDeltaAnnotationFilters(currentFilters: NestedFilter[], newAnnotations: AnnotationWrapper[]) {
const primaryFilterGroup = this._filterService.getGroup('primaryFilters');
const primaryFilters = primaryFilterGroup.filters;
@ -703,7 +662,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private _findAndDeleteAnnotation(id: string) {
const viewerAnnotation = this._instance?.Core.annotationManager.getAnnotationById(id);
const viewerAnnotation = this._pdf.annotationManager.getAnnotationById(id);
if (viewerAnnotation) {
this._pdf.deleteAnnotations([viewerAnnotation]);
}
@ -717,27 +676,14 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
}
private _handleIgnoreAnnotationsDrawing(hideSkipped: boolean): void {
const ignored = this._getAnnotations(a => a.getCustomData('skipped'));
const ignored = this._pdf.getAnnotations(a => a.getCustomData('skipped'));
if (hideSkipped) {
this._hide(ignored);
this._pdf.hideAnnotations(ignored);
} else {
this._show(ignored);
this._pdf.showAnnotations(ignored);
}
}
private _getAnnotations(predicate: (value) => boolean) {
const annotations = this._instance.Core.annotationManager.getAnnotationsList();
return predicate ? annotations.filter(predicate) : annotations;
}
private _hide(annotations: Annotation[]): void {
this._instance.Core.annotationManager.hideAnnotations(annotations);
}
private _show(annotations: Annotation[]): void {
this._instance.Core.annotationManager.showAnnotations(annotations);
}
private _setAnnotationsOpacity(annotations: Annotation[], restoreToOriginal: boolean = false) {
annotations.forEach(annotation => {
annotation['Opacity'] = restoreToOriginal ? parseFloat(annotation.getCustomData('opacity')) : 1;
@ -746,7 +692,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
private _setAnnotationsColor(annotations: Annotation[], customData: string) {
annotations.forEach(annotation => {
const color = this._annotationDrawService.convertColor(this._instance, annotation.getCustomData(customData));
const color = this._annotationDrawService.convertColor(annotation.getCustomData(customData));
annotation['StrokeColor'] = color;
annotation['FillColor'] = color;
});

View File

@ -9,7 +9,7 @@ import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
import { BASE_HREF } from '../../../../../tokens';
import { UserService } from '@services/user.service';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { Core } from '@pdftron/webviewer';
import { Dossier, IAddRedactionRequest, ILegalBasisChangeRequest, IRectangle, IResizeRequest } from '@red/domain';
import { toPosition } from '../../../utils/pdf-calculation.utils';
import { AnnotationDrawService } from './annotation-draw.service';
@ -24,6 +24,7 @@ import { defaultDialogConfig } from '@iqser/common-ui';
import { filter } from 'rxjs/operators';
import { MatDialog } from '@angular/material/dialog';
import { FilePreviewStateService } from './file-preview-state.service';
import { PdfViewer } from './pdf-viewer.service';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -37,6 +38,7 @@ export class AnnotationActionsService {
private readonly _translateService: TranslateService,
private readonly _dialogService: DossiersDialogService,
private readonly _dialog: MatDialog,
private readonly _pdf: PdfViewer,
private readonly _annotationDrawService: AnnotationDrawService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _screenStateService: FilePreviewStateService,
@ -211,7 +213,6 @@ export class AnnotationActionsService {
}
getViewerAvailableActions(
viewer: WebViewerInstance,
dossier: Dossier,
annotations: AnnotationWrapper[],
annotationsChanged: EventEmitter<AnnotationWrapper>,
@ -238,7 +239,7 @@ export class AnnotationActionsService {
title: this._translateService.instant('annotation-actions.resize-accept.label'),
onClick: () =>
this._ngZone.run(() => {
this.acceptResize(null, viewer, firstAnnotation, annotationsChanged);
this.acceptResize(null, firstAnnotation, annotationsChanged);
}),
});
availableActions.push({
@ -247,7 +248,7 @@ export class AnnotationActionsService {
title: this._translateService.instant('annotation-actions.resize-cancel.label'),
onClick: () =>
this._ngZone.run(() => {
this.cancelResize(null, viewer, firstAnnotation, annotationsChanged);
this.cancelResize(null, firstAnnotation, annotationsChanged);
}),
});
return availableActions;
@ -257,7 +258,7 @@ export class AnnotationActionsService {
type: 'actionButton',
img: this._convertPath('/assets/icons/general/resize.svg'),
title: this._translateService.instant('annotation-actions.resize.label'),
onClick: () => this._ngZone.run(() => this.resize(null, viewer, annotations[0])),
onClick: () => this._ngZone.run(() => this.resize(null, annotations[0])),
});
}
@ -419,32 +420,26 @@ export class AnnotationActionsService {
annotationToBeUpdated.hidden = hidden;
}
resize($event: MouseEvent, viewer: WebViewerInstance, annotationWrapper: AnnotationWrapper) {
resize($event: MouseEvent, annotationWrapper: AnnotationWrapper) {
$event?.stopPropagation();
annotationWrapper.resizing = true;
const annotationManager = viewer.Core.annotationManager;
const viewerAnnotation = annotationManager.getAnnotationById(annotationWrapper.id);
const viewerAnnotation = this._pdf.annotationManager.getAnnotationById(annotationWrapper.id);
viewerAnnotation.ReadOnly = false;
viewerAnnotation.Hidden = false;
viewerAnnotation.disableRotationControl();
annotationManager.redrawAnnotation(viewerAnnotation);
annotationManager.selectAnnotation(viewerAnnotation);
this._pdf.annotationManager.redrawAnnotation(viewerAnnotation);
this._pdf.annotationManager.selectAnnotation(viewerAnnotation);
this._annotationDrawService.annotationToQuads(viewerAnnotation, viewer);
this._annotationDrawService.annotationToQuads(viewerAnnotation);
}
acceptResize(
$event: MouseEvent,
viewer: WebViewerInstance,
annotationWrapper: AnnotationWrapper,
annotationsChanged?: EventEmitter<AnnotationWrapper>,
) {
acceptResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged?: EventEmitter<AnnotationWrapper>) {
const data = { dossier: this._dossier };
const fileId = this._screenStateService.fileId;
this._dialogService.openDialog('resizeAnnotation', $event, data, async (result: { comment: string }) => {
const textAndPositions = await this._extractTextAndPositions(viewer, annotationWrapper.id);
const textAndPositions = await this._extractTextAndPositions(annotationWrapper.id);
const text =
annotationWrapper.value === 'Rectangle' ? 'Rectangle' : annotationWrapper.isImage ? 'Image' : textAndPositions.text;
@ -463,21 +458,15 @@ export class AnnotationActionsService {
});
}
cancelResize(
$event: MouseEvent,
viewer: WebViewerInstance,
annotationWrapper: AnnotationWrapper,
annotationsChanged: EventEmitter<AnnotationWrapper>,
) {
cancelResize($event: MouseEvent, annotationWrapper: AnnotationWrapper, annotationsChanged: EventEmitter<AnnotationWrapper>) {
$event?.stopPropagation();
annotationWrapper.resizing = false;
const annotationManager = viewer.Core.annotationManager;
const viewerAnnotation = annotationManager.getAnnotationById(annotationWrapper.id);
const viewerAnnotation = this._pdf.annotationManager.getAnnotationById(annotationWrapper.id);
viewerAnnotation.ReadOnly = false;
annotationManager.redrawAnnotation(viewerAnnotation);
annotationManager.deselectAllAnnotations();
this._pdf.annotationManager.redrawAnnotation(viewerAnnotation);
this._pdf.annotationManager.deselectAllAnnotations();
annotationsChanged.emit(annotationWrapper);
}
@ -540,19 +529,19 @@ export class AnnotationActionsService {
return this._baseHref + path;
}
private async _extractTextAndPositions(viewer: WebViewerInstance, annotationId: string) {
const viewerAnnotation = viewer.Core.annotationManager.getAnnotationById(annotationId);
private async _extractTextAndPositions(annotationId: string) {
const viewerAnnotation = this._pdf.annotationManager.getAnnotationById(annotationId);
const document = await viewer.Core.documentViewer.getDocument().getPDFDoc();
const document = await this._pdf.documentViewer.getDocument().getPDFDoc();
const page = await document.getPage(viewerAnnotation.getPageNumber());
if (viewerAnnotation instanceof viewer.Core.Annotations.TextHighlightAnnotation) {
if (viewerAnnotation instanceof this._pdf.Annotations.TextHighlightAnnotation) {
const words = [];
const rectangles: IRectangle[] = [];
for (const quad of viewerAnnotation.Quads) {
const rect = toPosition(
viewerAnnotation.getPageNumber(),
viewer.Core.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
this._translateQuads(viewer, viewerAnnotation.getPageNumber(), quad),
this._pdf.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
this._translateQuads(viewerAnnotation.getPageNumber(), quad),
);
rectangles.push(rect);
@ -560,13 +549,13 @@ export class AnnotationActionsService {
// TODO: so that we do not extract text from line above/line below
const percentHeightOffset = rect.height / 10;
const pdfNetRect = new viewer.Core.PDFNet.Rect(
const pdfNetRect = new this._pdf.instance.Core.PDFNet.Rect(
rect.topLeft.x,
rect.topLeft.y + percentHeightOffset,
rect.topLeft.x + rect.width,
rect.topLeft.y + rect.height - percentHeightOffset,
);
const quadWords = await this._extractTextFromRect(viewer, page, pdfNetRect);
const quadWords = await this._extractTextFromRect(page, pdfNetRect);
words.push(...quadWords);
}
@ -579,8 +568,8 @@ export class AnnotationActionsService {
} else {
const rect = toPosition(
viewerAnnotation.getPageNumber(),
viewer.Core.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
this._annotationDrawService.annotationToQuads(viewerAnnotation, viewer),
this._pdf.documentViewer.getPageHeight(viewerAnnotation.getPageNumber()),
this._annotationDrawService.annotationToQuads(viewerAnnotation),
);
return {
positions: [rect],
@ -589,16 +578,16 @@ export class AnnotationActionsService {
}
}
private _translateQuads(viewer: WebViewerInstance, page: number, quads: any) {
const rotation = viewer.Core.documentViewer.getCompleteRotation(page);
private _translateQuads(page: number, quads: any) {
const rotation = this._pdf.documentViewer.getCompleteRotation(page);
return translateQuads(page, rotation, quads);
}
private async _extractTextFromRect(viewer: WebViewerInstance, page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
const txt = await viewer.Core.PDFNet.TextExtractor.create();
private async _extractTextFromRect(page: Core.PDFNet.Page, rect: Core.PDFNet.Rect) {
const txt = await this._pdf.PDFNet.TextExtractor.create();
txt.begin(page, rect); // Read the page.
const words = [];
const words: string[] = [];
// Extract words one by one.
let line = await txt.getFirstLine();
for (; await line.isValid(); line = await line.getNextLine()) {

View File

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Core, WebViewerInstance } from '@pdftron/webviewer';
import { Core } from '@pdftron/webviewer';
import { hexToRgb } from '@utils/functions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { UserPreferenceService } from '@services/user-preference.service';
@ -11,6 +11,9 @@ import { SkippedService } from './skipped.service';
import { firstValueFrom } from 'rxjs';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { DossiersService } from '../../../../../services/dossiers/dossiers.service';
import { PdfViewer } from './pdf-viewer.service';
import { FilePreviewStateService } from './file-preview-state.service';
import { ViewModeService } from './view-mode.service';
import Annotation = Core.Annotations.Annotation;
@Injectable()
@ -25,57 +28,54 @@ export class AnnotationDrawService {
private readonly _redactionLogService: RedactionLogService,
private readonly _userPreferenceService: UserPreferenceService,
private readonly _skippedService: SkippedService,
private readonly _pdf: PdfViewer,
private readonly _state: FilePreviewStateService,
private readonly _viewModeService: ViewModeService,
) {}
async drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
fileId: string,
dossierId: string,
compareMode = false,
) {
if (!activeViewer) {
async drawAnnotations(annotationWrappers: AnnotationWrapper[]) {
if (!this._pdf.instance || !this._pdf.ready) {
return;
}
const pdfNet = activeViewer.Core.PDFNet;
const pdfNet = this._pdf.instance.Core.PDFNet;
await pdfNet.runWithCleanup(
async () => {
await this._drawAnnotations(activeViewer, annotationWrappers, fileId, dossierId, compareMode);
await this._drawAnnotations(annotationWrappers);
},
environment.licenseKey ? atob(environment.licenseKey) : null,
);
}
getColor(activeViewer: WebViewerInstance, dossierTemplateId: string, superType: string, dictionary?: string) {
getColor(superType: string, dictionary?: string) {
let color: string;
switch (superType) {
case 'hint':
case 'redaction':
case 'recommendation':
color = this._dictionariesMapService.getDictionaryColor(dictionary, dossierTemplateId);
color = this._dictionariesMapService.getDictionaryColor(dictionary, this._state.dossierTemplateId);
break;
case 'skipped':
color = this._dictionariesMapService.getDictionaryColor(superType, dossierTemplateId);
color = this._dictionariesMapService.getDictionaryColor(superType, this._state.dossierTemplateId);
break;
default:
color = this._dictionariesMapService.getDictionaryColor(superType, dossierTemplateId);
color = this._dictionariesMapService.getDictionaryColor(superType, this._state.dossierTemplateId);
break;
}
return color;
}
getAndConvertColor(activeViewer: WebViewerInstance, dossierTemplateId: string, superType: string, dictionary?: string) {
return this.convertColor(activeViewer, this.getColor(activeViewer, dossierTemplateId, superType, dictionary));
getAndConvertColor(superType: string, dictionary?: string) {
return this.convertColor(this.getColor(superType, dictionary));
}
convertColor(activeViewer: WebViewerInstance, hexColor: string) {
convertColor(hexColor: string) {
const rgbColor = hexToRgb(hexColor);
return new activeViewer.Core.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
return new this._pdf.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
}
annotationToQuads(annotation: Annotation, activeViewer: WebViewerInstance) {
annotationToQuads(annotation: Annotation) {
const x1 = annotation.getRect().x1;
const y1 = annotation.getRect().y1 + annotation.getRect().getHeight();
@ -88,51 +88,42 @@ export class AnnotationDrawService {
const x4 = annotation.getRect().x1;
const y4 = annotation.getRect().y1;
return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
return new this._pdf.instance.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
}
private async _drawAnnotations(
activeViewer: WebViewerInstance,
annotationWrappers: AnnotationWrapper[],
fileId: string,
dossierId: string,
compareMode: boolean,
) {
const annotations = annotationWrappers
.map(annotation => this._computeAnnotation(activeViewer, annotation, dossierId, compareMode))
.filter(a => !!a);
const annotationManager = activeViewer.Core.annotationManager;
private async _drawAnnotations(annotationWrappers: AnnotationWrapper[]) {
const annotations = annotationWrappers.map(annotation => this._computeAnnotation(annotation)).filter(a => !!a);
const annotationManager = this._pdf.annotationManager;
annotationManager.addAnnotations(annotations, { imported: true });
await annotationManager.drawAnnotationsFromList(annotations);
if (this._userPreferenceService.areDevFeaturesEnabled) {
const sectionsGrid = await firstValueFrom(this._redactionLogService.getSectionGrid(dossierId, fileId)).catch(() => ({
rectanglesPerPage: {},
}));
await this._drawSections(activeViewer, sectionsGrid, dossierId);
const { dossierId, fileId } = this._state;
const sectionsGrid$ = this._redactionLogService.getSectionGrid(dossierId, fileId);
const sectionsGrid = await firstValueFrom(sectionsGrid$).catch(() => ({ rectanglesPerPage: {} }));
await this._drawSections(sectionsGrid);
}
}
private async _drawSections(activeViewer: WebViewerInstance, sectionGrid: ISectionGrid, dossierId: string) {
private async _drawSections(sectionGrid: ISectionGrid) {
const sections: Core.Annotations.RectangleAnnotation[] = [];
for (const page of Object.keys(sectionGrid.rectanglesPerPage)) {
const sectionRectangles = sectionGrid.rectanglesPerPage[page];
sectionRectangles.forEach(sectionRectangle => {
sections.push(this._computeSection(activeViewer, parseInt(page, 10), sectionRectangle, dossierId));
sections.push(this._computeSection(parseInt(page, 10), sectionRectangle));
// sectionRectangle.tableCells?.forEach(cell =>{
// sections.push(this.computeSection(activeViewer, parseInt(page, 10), cell));
// })
});
}
const annotationManager = activeViewer.Core.annotationManager;
const annotationManager = this._pdf.annotationManager;
annotationManager.addAnnotations(sections, { imported: true });
await annotationManager.drawAnnotationsFromList(sections);
}
private _computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: ISectionRectangle, dossierId: string) {
const dossierTemplateId = this._dossiersService.find(dossierId).dossierTemplateId;
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
private _computeSection(pageNumber: number, sectionRectangle: ISectionRectangle) {
const rectangleAnnot = new this._pdf.Annotations.RectangleAnnotation();
const pageHeight = this._pdf.documentViewer.getPageHeight(pageNumber);
const rectangle: IRectangle = {
topLeft: sectionRectangle.topLeft,
page: pageNumber,
@ -145,27 +136,22 @@ export class AnnotationDrawService {
rectangleAnnot.Width = rectangle.width + 2;
rectangleAnnot.Height = rectangle.height + 2;
rectangleAnnot.ReadOnly = true;
rectangleAnnot.StrokeColor = this.getAndConvertColor(activeViewer, dossierTemplateId, 'analysis', 'analysis');
rectangleAnnot.StrokeColor = this.getAndConvertColor('analysis', 'analysis');
rectangleAnnot.StrokeThickness = 1;
return rectangleAnnot;
}
private _computeAnnotation(
activeViewer: WebViewerInstance,
annotationWrapper: AnnotationWrapper,
dossierId: string,
compareMode: boolean,
) {
const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
if (pageNumber > activeViewer.Core.documentViewer.getPageCount()) {
private _computeAnnotation(annotationWrapper: AnnotationWrapper) {
const pageNumber = this._viewModeService.isCompare ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
if (pageNumber > this._pdf.documentViewer.getPageCount()) {
// skip imported annotations from files that have more pages than the current one
return;
}
if (annotationWrapper.superType === 'text-highlight') {
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
const rectangleAnnot = new this._pdf.Annotations.RectangleAnnotation();
const pageHeight = this._pdf.documentViewer.getPageHeight(pageNumber);
const rectangle: IRectangle = annotationWrapper.positions[0];
rectangleAnnot.PageNumber = pageNumber;
rectangleAnnot.X = rectangle.topLeft.x;
@ -173,37 +159,30 @@ export class AnnotationDrawService {
rectangleAnnot.Width = rectangle.width;
rectangleAnnot.Height = rectangle.height;
rectangleAnnot.ReadOnly = true;
rectangleAnnot.StrokeColor = this.convertColor(activeViewer, annotationWrapper.color);
rectangleAnnot.StrokeColor = this.convertColor(annotationWrapper.color);
rectangleAnnot.StrokeThickness = 1;
rectangleAnnot.Id = annotationWrapper.id;
return rectangleAnnot;
}
const dossierTemplateId = this._dossiersService.find(dossierId).dossierTemplateId;
let annotation: Core.Annotations.RectangleAnnotation | Core.Annotations.TextHighlightAnnotation;
if (annotationWrapper.rectangle || annotationWrapper.isImage) {
annotation = new activeViewer.Core.Annotations.RectangleAnnotation();
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
annotation = new this._pdf.Annotations.RectangleAnnotation();
const pageHeight = this._pdf.documentViewer.getPageHeight(pageNumber);
const firstPosition = annotationWrapper.positions[0];
annotation.X = firstPosition.topLeft.x;
annotation.Y = pageHeight - (firstPosition.topLeft.y + firstPosition.height);
annotation.Width = firstPosition.width;
annotation.FillColor = this.getAndConvertColor(
activeViewer,
dossierTemplateId,
annotationWrapper.superType,
annotationWrapper.type,
);
annotation.FillColor = this.getAndConvertColor(annotationWrapper.superType, annotationWrapper.type);
annotation.Opacity = annotationWrapper.isChangeLogRemoved
? AnnotationDrawService.DEFAULT_REMOVED_ANNOTATION_OPACITY
: AnnotationDrawService.DEFAULT_RECTANGLE_ANNOTATION_OPACITY;
annotation.Height = firstPosition.height;
annotation.Intensity = 100;
} else {
annotation = new activeViewer.Core.Annotations.TextHighlightAnnotation();
annotation.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber);
annotation = new this._pdf.Annotations.TextHighlightAnnotation();
annotation.Quads = this._rectanglesToQuads(annotationWrapper.positions, pageNumber);
annotation.Opacity = annotationWrapper.isChangeLogRemoved
? AnnotationDrawService.DEFAULT_REMOVED_ANNOTATION_OPACITY
: AnnotationDrawService.DEFAULT_TEXT_ANNOTATION_OPACITY;
@ -212,12 +191,7 @@ export class AnnotationDrawService {
annotation.setContents(annotationWrapper.content);
annotation.PageNumber = pageNumber;
annotation.StrokeColor = this.getAndConvertColor(
activeViewer,
dossierTemplateId,
annotationWrapper.superType,
annotationWrapper.type,
);
annotation.StrokeColor = this.getAndConvertColor(annotationWrapper.superType, annotationWrapper.type);
annotation.Id = annotationWrapper.id;
annotation.ReadOnly = true;
// change log entries are drawn lighter
@ -233,21 +207,18 @@ export class AnnotationDrawService {
annotation.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry));
annotation.setCustomData('changeLogRemoved', String(annotationWrapper.isChangeLogRemoved));
annotation.setCustomData('opacity', String(annotation.Opacity));
annotation.setCustomData('redactionColor', String(this.getColor(activeViewer, dossierTemplateId, 'redaction', 'preview')));
annotation.setCustomData(
'annotationColor',
String(this.getColor(activeViewer, dossierTemplateId, annotationWrapper.superType, annotationWrapper.type)),
);
annotation.setCustomData('redactionColor', String(this.getColor('redaction', 'redaction')));
annotation.setCustomData('annotationColor', String(this.getColor(annotationWrapper.superType, annotationWrapper.type)));
return annotation;
}
private _rectanglesToQuads(positions: IRectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
private _rectanglesToQuads(positions: IRectangle[], pageNumber: number): any[] {
const pageHeight = this._pdf.documentViewer.getPageHeight(pageNumber);
return positions.map(p => this._rectangleToQuad(p, pageHeight));
}
private _rectangleToQuad(rectangle: IRectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
private _rectangleToQuad(rectangle: IRectangle, pageHeight: number): any {
const x1 = rectangle.topLeft.x;
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);
@ -260,6 +231,6 @@ export class AnnotationDrawService {
const x4 = rectangle.topLeft.x;
const y4 = pageHeight - rectangle.topLeft.y;
return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
return new this._pdf.instance.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
}
}

View File

@ -56,16 +56,20 @@ export class PdfViewer {
return this.instance.UI;
}
get Annotations() {
return this.instance.Core.Annotations;
}
get PDFNet() {
return this.instance.Core.PDFNet;
}
get paginationOffset() {
return this.viewModeService.isCompare ? 2 : 1;
}
get currentPage() {
try {
return this.viewModeService.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
} catch (e) {
return null;
}
return this.viewModeService.isCompare ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
}
get totalPages() {
@ -73,19 +77,36 @@ export class PdfViewer {
return null;
}
try {
return this.viewModeService.isCompare ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
} catch (e) {
return null;
}
return this.viewModeService.isCompare ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
}
private get _currentInternalPage() {
return this.instance?.Core.documentViewer?.getCurrentPage();
return this.documentViewer?.getCurrentPage() ?? 1;
}
private get _totalInternalPages() {
return this.instance?.Core.documentViewer?.getPageCount();
return this.documentViewer?.getPageCount() ?? 1;
}
hideAnnotations(annotations: Annotation[]): void {
this.annotationManager.hideAnnotations(annotations);
}
showAnnotations(annotations: Annotation[]): void {
this.annotationManager.showAnnotations(annotations);
}
getAnnotations(predicate?: (value) => boolean) {
const annotations = this.annotationManager?.getAnnotationsList() ?? [];
return predicate ? annotations.filter(predicate) : annotations;
}
getAnnotationsById(ids: readonly string[]) {
if (this.annotationManager) {
return ids.map(id => this.annotationManager.getAnnotationById(id));
}
return [];
}
async loadViewer(htmlElement: HTMLElement) {
@ -140,6 +161,10 @@ export class PdfViewer {
}
deselectAllAnnotations() {
if (!this.ready) {
return;
}
this.annotationManager.deselectAllAnnotations();
}
@ -147,16 +172,21 @@ export class PdfViewer {
if (!annotations) {
return;
}
if (!multiSelectActive) {
this.deselectAllAnnotations();
}
const annotationsFromViewer = annotations.map(ann => this._getAnnotationById(ann.id));
const annotationsFromViewer = this.getAnnotationsById(annotations.map(a => a.id));
this.annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
this.annotationManager.selectAnnotations(annotationsFromViewer);
}
deleteAnnotations(annotations: Annotation[] = this.annotationManager?.getAnnotationsList() ?? []) {
deleteAnnotations(annotations: Annotation[] = this.getAnnotations()) {
if (!this.ready) {
return;
}
try {
this.annotationManager.deleteAnnotations(annotations, {
imported: true,
@ -168,7 +198,7 @@ export class PdfViewer {
}
deselectAnnotations(annotations: AnnotationWrapper[]) {
const ann = annotations.map(a => this._getAnnotationById(a.id));
const ann = this.getAnnotationsById(annotations.map(a => a.id));
this.annotationManager.deselectAnnotations(ann);
}
@ -178,10 +208,6 @@ export class PdfViewer {
}
}
private _getAnnotationById(id: string): Annotation {
return this.annotationManager.getAnnotationById(id);
}
#convertPath(path: string) {
return `${this._baseHref}${path}`;
}