UNPKG

devexpress-gantt

Version:

DevExpress Gantt Control

138 lines (130 loc) 5.29 kB
import { IHistory } from "./IHistory"; import { HistoryItemInfo } from "./HistoryItems/HistoryItemInfo"; import { CompositionHistoryItem } from "./HistoryItems/CompositionHistoryItem"; import { HistoryItem } from "./HistoryItems/HistoryItem"; import { IHistoryListener } from "../../Interfaces/IHistiryListener"; export class History implements IHistory { private static MAX_HISTORY_ITEM_COUNT: number = 100; historyItems: HistoryItem[] = []; currentIndex: number = -1; currentProcessingItemInfo: HistoryItemInfo = null; transaction: CompositionHistoryItem = null; private transactionLevel: number = -1; private _listener: IHistoryListener; constructor(listener?: IHistoryListener) { this._listener = listener; } public undo(): void { if(this.canUndo()) { this.activateItem(this.historyItems[this.currentIndex], true); this.currentIndex--; } } public redo(): void { if(this.canRedo()) { this.currentIndex++; this.activateItem(this.historyItems[this.currentIndex]); } } public beginTransaction(): void { this.transactionLevel++; if(this.transactionLevel == 0) { this.transaction = new CompositionHistoryItem(); this._listener?.onTransactionStart(); } } public endTransaction(): void { if(--this.transactionLevel >= 0) return; const transactionLength: number = this.transaction.historyItems.length; if(transactionLength > 1) this.addInternal(this.transaction); else if(transactionLength == 1) this.addInternal(this.transaction.historyItems.pop()); this.transaction = null; this._listener?.onTransactionEnd(); } public addAndRedo(historyItem: HistoryItem): void { this.add(historyItem); this.activateItem(historyItem); } public add(historyItem: HistoryItem): void { if(this.transactionLevel >= 0) this.transaction.add(historyItem); else this.addInternal(historyItem); } public canUndo(): boolean { return this.currentIndex >= 0; } public canRedo(): boolean { return this.currentIndex < this.historyItems.length - 1; } private addInternal(historyItem: HistoryItem) { if(this.currentIndex < this.historyItems.length - 1) this.historyItems.splice(this.currentIndex + 1); this.historyItems.push(historyItem); this.currentIndex++; this.deleteOldItems(); } private deleteOldItems() { const exceedItemsCount: number = this.historyItems.length - History.MAX_HISTORY_ITEM_COUNT; if(exceedItemsCount > 0 && this.currentIndex > exceedItemsCount) { this.historyItems.splice(0, exceedItemsCount); this.currentIndex -= exceedItemsCount; } } public clear(): void { this.currentIndex = -1; this.historyItems = []; } activateItem(historyItem: HistoryItem, isUndo: boolean = false): void { this.currentProcessingItemInfo = new HistoryItemInfo(historyItem, isUndo); if(isUndo) historyItem.undo(); else historyItem.redo(); this.currentProcessingItemInfo = null; } getCurrentProcessingItemInfo(): HistoryItemInfo { return this.currentProcessingItemInfo; } rollBackAndRemove(info: HistoryItemInfo): void { const item = info.item; if(!this.checkAndRemoveItem(item)) return; if(info.isUndo) item.redo(); else if(item instanceof CompositionHistoryItem) (item as CompositionHistoryItem).undoItemsQuery(); else item.undo(); } checkAndRemoveItem(item: HistoryItem): boolean { let index = this.historyItems.indexOf(item); if(index > -1) { this.historyItems.splice(index, 1); this.currentIndex--; } else if(this.transaction) { index = this.transaction.historyItems.indexOf(item); if(index > -1) this.transaction.historyItems.splice(index, 1); } return index > -1; } public updateObsoleteInsertedKey(oldKey: string, newKey: string, type: string): void { if(this.transaction) this.updateItemsObsoleteInsertedKey(oldKey, newKey, type, [ this.transaction ]); this.updateItemsObsoleteInsertedKey(oldKey, newKey, type, this.historyItems); } updateItemsObsoleteInsertedKey(oldKey: string, newKey: string, type: string, historyItems: HistoryItem[]): void { if(historyItems) for(let i = 0; i < historyItems.length; i++) { const item = historyItems[i]; const keyUpdaters = item.keyUpdaters.filter(k => k.getKey() === oldKey && k.objectType === type); keyUpdaters.forEach(k => k.updateKey(newKey)); if(item instanceof CompositionHistoryItem) this.updateItemsObsoleteInsertedKey(oldKey, newKey, type, item.historyItems); } } }