/** @packageDocumentation * @module Editing */ import { EditTxn, IModelDb } from "@itwin/core-backend"; import { SaveChangesArgs } from "@itwin/core-common"; import { EditCommandIpc } from "@itwin/editor-common"; /** @beta */ export type EditCommandType = typeof EditCommand; /** * An EditCommand performs an editing action on the backend. * Any writes to the iModel in an editing session should be done from an EditCommand: * - All changes to an iModel are made within a transaction (Txn). * - Calling SaveChanges ends the current Txn and starts a new one. * - Using EditCommand ensures all of the changes in a Txn are from the same source, as only one EditCommand may be active at a time. * - Because there is currently no way to enforce this, it is important that all applications follow this rule. * EditCommands are usually paired with and driven by EditTools on the frontend that can either be interactive tools or immediate tools. * Interactive EditTools: * - Can be a [PrimitiveTool]($frontend). * - Can be an [InputCollector]($frontend) in special cases such as [EditManipulator.HandleTool]($frontend). * - Should not be a [ViewTool]($frontend), these should never write changes to the iModel. * Immediate EditTools: * - As direct subclasses of [Tool]($frontend) that perform their function without further input or becoming the active tool, * they potentially leave the current [PrimitiveTool]($frontend) in an invalid state. * - To avoid issues, immediate tools that start an EditCommand must call [ToolAdmin.restartPrimitiveTool]($frontend) when they complete. * EditCommands have a *commandId* that uniquely identifies them, so they can be found via a lookup in the [[EditCommandAdmin]]. * Each EditCommand must be registered in the [[EditCommandAdmin]] with [[EditCommandAdmin.register]] or [[EditCommandAdmin.registerModule]]. * Every time an EditCommand runs, a new instance of (a subclass of) this class is created. * @see [[BasicManipulationCommand]] for an example EditCommand. * @beta */ export declare class EditCommand implements EditCommandIpc { /** The unique string that identifies this EditCommand class. This must be overridden in every subclass. */ static commandId: string; static version: string; /** The iModel this EditCommand may modify. */ readonly iModel: IModelDb; /** The explicit editing transaction for this command. Subclasses use this to perform writes to the iModel. */ protected readonly txn: EditTxn; /** Application-specific data included when this command commits its EditTxn. */ protected appData?: SaveChangesArgs["appData"]; constructor(iModel: IModelDb, ..._args: any[]); get ctor(): EditCommandType; onStart(): Promise; /** Start this command's transaction if it has not already started. */ protected beginEditing(): void; /** Returns true if this command's transaction is currently active. */ get isTxnActive(): boolean; /** Abandon any pending changes and end this command's EditTxn */ abandonEdits(): Promise; /** Save all pending edits and end this command's EditTxn */ endEdits(description?: string): Promise; ping(): Promise<{ commandId: string; version: string; [propName: string]: any; }>; /** Save any pending changes on this command's EditTxn. Leaves the EditTxn active for further edits. * @param description Optional description saved with the changes. */ saveChanges(description?: string): Promise; /** Abandon any pending changes on this command's EditTxn. Leaves the EditTxn active for further edits. */ abandonChanges(): Promise; /** * Called when another EditCommand wishes to become the active EditCommand. * The default implementation abandons pending edits (does not save changes) and returns "done". * Subclasses should complete and call end their work as soon as possible before returning "done". * If it is not currently possible to finish, return any string other than "done" and the other EditCommand will have to wait and retry, * potentially showing the returned string to the user. */ requestFinish(): Promise<"done" | string>; private resolveSaveChangesArg; } /** * EditCommandAdmin holds a mapping between commandIds and their corresponding [[EditCommand]] class. This provides the mechanism to * run EditCommands by commandId. * It also keeps track of the currently active EditCommand. When a new EditCommand attempts to start, the active EditCommand * is requested to finish, and the new EditCommand cannot start until it does. * @beta */ export declare class EditCommandAdmin { static readonly commands: Map; private static _activeCommand?; private static _isInitialized; static get activeCommand(): EditCommand | undefined; /** If any command is currently active, wait for it to finish. * Afterward, no command will be active. * This method is invoked by [[runCommand]] before starting a new command. * @throws BackendError if the command fails to finish. */ static finishCommand(): Promise; /** Start running the specified command. * The new command will not begin running until the currently-active command (if any) finishes. * Afterward, the new command becomes the active command. * @throws BackendError if the currently-active command fails to finish. */ static runCommand(cmd: EditCommand): Promise; /** * Un-register a previously registered EditCommand class. * @param commandId the commandId of a previously registered EditCommand to unRegister. */ static unRegister(commandId: string): void; /** * Register an EditCommand class. This establishes a connection between the commandId of the class and the class itself. * @param commandType the subclass of Tool to register. */ static register(commandType: EditCommandType): void; /** * Register all the EditCommand classes found in a module. * @param modelObj the module to search for subclasses of EditCommand. */ static registerModule(moduleObj: any): void; } //# sourceMappingURL=EditCommand.d.ts.map