177 lines
5.2 KiB
TypeScript
177 lines
5.2 KiB
TypeScript
import { IRectangle, ViewMode } from '@red/domain';
|
|
import { translateQuads } from '@utils/pdf-coordinates';
|
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
|
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
|
import Annotation = Core.Annotations.Annotation;
|
|
|
|
const DISABLED_HOTKEYS = [
|
|
'CTRL+SHIFT+EQUAL',
|
|
'COMMAND+SHIFT+EQUAL',
|
|
'CTRL+SHIFT+MINUS',
|
|
'COMMAND+SHIFT+MINUS',
|
|
'CTRL+V',
|
|
'COMMAND+V',
|
|
'CTRL+Y',
|
|
'COMMAND+Y',
|
|
'CTRL+O',
|
|
'COMMAND+O',
|
|
'CTRL+P',
|
|
'COMMAND+P',
|
|
'SPACE',
|
|
'UP',
|
|
'DOWN',
|
|
'R',
|
|
'P',
|
|
'A',
|
|
'C',
|
|
'E',
|
|
'I',
|
|
'L',
|
|
'N',
|
|
'O',
|
|
'T',
|
|
'S',
|
|
'G',
|
|
'H',
|
|
'K',
|
|
'U',
|
|
] as const;
|
|
|
|
export class PdfViewerUtils {
|
|
ready = false;
|
|
excludedPages: number[] = [];
|
|
|
|
constructor(readonly instance: WebViewerInstance, public viewMode: ViewMode, public multiSelectActive: boolean) {}
|
|
|
|
get isCompareMode() {
|
|
return this.viewMode === 'COMPARE';
|
|
}
|
|
|
|
get paginationOffset() {
|
|
return this.isCompareMode ? 2 : 1;
|
|
}
|
|
|
|
get isCurrentPageExcluded() {
|
|
const currentPage = this.currentPage;
|
|
return !!this.excludedPages?.includes(currentPage);
|
|
}
|
|
|
|
get currentPage() {
|
|
try {
|
|
return this.isCompareMode ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
get totalPages() {
|
|
if (!this.ready) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return this.isCompareMode ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private get _documentViewer() {
|
|
return this.instance?.Core.documentViewer;
|
|
}
|
|
|
|
private get _annotationManager() {
|
|
return this.instance?.Core.annotationManager;
|
|
}
|
|
|
|
private get _currentInternalPage() {
|
|
return this.instance?.Core.documentViewer?.getCurrentPage();
|
|
}
|
|
|
|
private get _totalInternalPages() {
|
|
return this.instance?.Core.documentViewer?.getPageCount();
|
|
}
|
|
|
|
navigateToPage(pageNumber: string | number) {
|
|
const parsedNumber = typeof pageNumber === 'string' ? parseInt(pageNumber, 10) : pageNumber;
|
|
this._navigateToPage(this.paginationOffset === 2 ? parsedNumber * this.paginationOffset - 1 : parsedNumber);
|
|
}
|
|
|
|
previousPage() {
|
|
if (this._currentInternalPage > 1) {
|
|
this._navigateToPage(Math.max(this._currentInternalPage - this.paginationOffset, 1));
|
|
}
|
|
}
|
|
|
|
nextPage() {
|
|
if (this._currentInternalPage < this._totalInternalPages) {
|
|
this._navigateToPage(Math.min(this._currentInternalPage + this.paginationOffset, this._totalInternalPages));
|
|
}
|
|
}
|
|
|
|
disableHotkeys(): void {
|
|
for (const hotkey of DISABLED_HOTKEYS) {
|
|
this.instance.UI.hotkeys.off(hotkey);
|
|
}
|
|
}
|
|
|
|
translateQuads(page: number, quads: any) {
|
|
const rotation = this._documentViewer.getCompleteRotation(page);
|
|
return translateQuads(page, rotation, quads);
|
|
}
|
|
|
|
toPosition(page: number, selectedQuad: { x1: number; x2: number; x3: number; x4: number; y4: number; y2: number }): IRectangle {
|
|
const pageHeight = this._documentViewer.getPageHeight(page);
|
|
const height = selectedQuad.y2 - selectedQuad.y4;
|
|
return {
|
|
page: page,
|
|
topLeft: {
|
|
x: Math.min(selectedQuad.x3, selectedQuad.x4, selectedQuad.x2, selectedQuad.x1),
|
|
y: pageHeight - (selectedQuad.y4 + height),
|
|
},
|
|
height: height,
|
|
width: Math.max(4, Math.abs(selectedQuad.x3 - selectedQuad.x4), Math.abs(selectedQuad.x3 - selectedQuad.x1)),
|
|
};
|
|
}
|
|
|
|
deselectAllAnnotations() {
|
|
this._annotationManager.deselectAllAnnotations();
|
|
}
|
|
|
|
selectAnnotations($event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
|
|
let annotations: AnnotationWrapper[];
|
|
let multiSelect: boolean;
|
|
if ($event instanceof Array) {
|
|
annotations = $event;
|
|
multiSelect = false;
|
|
} else {
|
|
annotations = $event.annotations;
|
|
multiSelect = $event.multiSelect;
|
|
}
|
|
|
|
if (!this.multiSelectActive && !multiSelect) {
|
|
this.deselectAllAnnotations();
|
|
}
|
|
|
|
const annotationsFromViewer = annotations.map(ann => this._getAnnotationById(ann.id));
|
|
this._annotationManager.selectAnnotations(annotationsFromViewer);
|
|
// this.navigateToPage(annotations[0].pageNumber*this.paginationOffset);
|
|
this._annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
|
|
}
|
|
|
|
deselectAnnotations(annotations: AnnotationWrapper[]) {
|
|
const ann = annotations.map(a => this._getAnnotationById(a.id));
|
|
this._annotationManager.deselectAnnotations(ann);
|
|
}
|
|
|
|
private _navigateToPage(pageNumber) {
|
|
if (this._currentInternalPage !== pageNumber) {
|
|
this._documentViewer.displayPageLocation(pageNumber, 0, 0);
|
|
}
|
|
}
|
|
|
|
private _getAnnotationById(id: string): Annotation {
|
|
return this._annotationManager.getAnnotationById(id);
|
|
}
|
|
}
|