/**
* Structure represents a cell address. Note that row and column are 0-based.
*/
export interface ICellAddress {
/** 0-based row */
row: number;
/** 0-based column */
column: number;
absolute_row?: boolean;
absolute_column?: boolean;
sheet_id?: number;
/** spill reference */
spill?: boolean;
}
/**
* this version of the interface requires a sheet ID
*/
export interface ICellAddress2 extends ICellAddress {
sheet_id: number;
}
/**
* Structure represents a 2d range of cells.
*
* @privateRemarks
*
* FIXME: should be just Partial? (...) OTOH, this at least
* enforces two addresses, which seems useful
*/
export interface IArea {
start: ICellAddress;
end: ICellAddress;
}
export type SerializedArea = IArea & {
start: ICellAddress & {
sheet: string;
};
};
export interface PatchOptions {
before_column: number;
column_count: number;
before_row: number;
row_count: number;
}
/**
* type guard function
* FIXME: is there a naming convention for these?
*
* @internal
*/
export declare const IsCellAddress: (obj: unknown) => obj is ICellAddress;
/** @internal */
export declare const IsArea: (obj: unknown) => obj is IArea;
export interface Dimensions {
rows: number;
columns: number;
}
/**
* class represents a rectangular area on a sheet. can be a range,
* single cell, entire row/column, or entire sheet.
*
* "entire" row/column/sheet is represented with an infinity in the
* start/end value for row/column/both, so watch out on loops. the
* sheet class has a method for reducing infinite ranges to actual
* populated ranges.
*
* infinitiy is turning into a headache because it doesn't serialize
* to json properly. should we switch to a flag, or -1, or something?
*/
export declare class Area implements IArea {
private start_;
private end_;
/**
*
* @param start
* @param end
* @param normalize: calls the normalize function
*/
constructor(start: ICellAddress, end?: ICellAddress, normalize?: boolean);
static FromColumn(column: number): Area;
static FromRow(row: number): Area;
static ColumnToLabel(c: number): string;
static CellAddressToLabel(address: ICellAddress, sheet_id?: boolean): string;
/**
* merge two areas and return a new area.
* UPDATE to support arbitrary arguments
*/
static Join(base: IArea, ...args: Array): Area;
/**
* creates an area that expands the original area in all directions
* (except at the top/left edges)
*/
static Bleed(area: IArea, length?: number): Area;
/**
* adjust an area in response to an insert/delete operation.
* I noticed we were doing this in several places. moved here to unify.
*
* @param source - the starting area. we'll create a new object to return
* (we will not mutate in place)
*/
static PatchArea(source: IArea, options: PatchOptions): Area | false;
/** accessor returns a _copy_ of the start address */
get start(): ICellAddress;
/** accessor */
set start(value: ICellAddress);
/** accessor returns a _copy_ of the end address */
get end(): ICellAddress;
/** accessor */
set end(value: ICellAddress);
/** returns number of rows, possibly infinity */
get rows(): number;
/** returns number of columns, possibly infinity */
get columns(): number;
/** returns number of cells, possibly infinity */
get count(): number;
/** returns flag indicating this is the entire sheet, usually after "select all" */
get entire_sheet(): boolean;
/** returns flag indicating this range includes infinite rows */
get entire_column(): boolean;
/** returns flag indicating this range includes infinite columns */
get entire_row(): boolean;
PatchNull(address: ICellAddress): ICellAddress;
SetSheetID(id: number): void;
Normalize(): void;
/** returns the top-left cell in the area */
TopLeft(): ICellAddress;
/** returns the bottom-right cell in the area */
BottomRight(): ICellAddress;
ContainsRow(row: number): boolean;
ContainsColumn(column: number): boolean;
Contains(address: ICellAddress): boolean;
/**
* returns true if this area completely contains the argument area
* (also if areas are ===, as a side effect). note that this returns
* true if A contains B, but not vice-versa
*/
ContainsArea(area: Area): boolean;
/**
* returns true if there's an intersection. note that this won't work
* if there are infinities -- needs real area ?
*/
Intersects(area: Area): boolean;
Equals(area: Area): boolean;
Equals2(area: IArea): boolean;
Clone(): Area;
get left(): Area;
get right(): Area;
get top(): Area;
get bottom(): Area;
/** shifts range in place */
Shift(rows: number, columns: number): Area;
/** Resizes range in place so that it includes the given address */
ConsumeAddress(addr: ICellAddress): void;
/** utility for removing headers from dataset selection */
RemoveHeaderRow(): this;
/** utility for removing headers from dataset selection */
RemoveHeaderColumn(): this;
/** returns one column of the area */
GetColumn(column: number): Area;
/** returns one column of the area */
GetRow(row: number): Area;
/** Resizes range in place to be the requested shape */
Reshape(rows: number, columns: number): Area;
/** Resizes range in place so that it includes the given area (merge) */
ConsumeArea(area: IArea): void;
/** resizes range in place (updates end) */
Resize(rows: number, columns: number): Area;
/**
* modernizing. this is a proper iterator. generators are prettier
* but there's at least some performance cost -- I'm not sure how
* much, but it's non-zero.
*/
[Symbol.iterator](): Iterator;
/**
* returns the range in A1-style spreadsheet addressing. if the
* entire sheet is selected, returns nothing (there's no way to
* express that in A1 notation). returns the row numbers for entire
* columns and vice-versa for rows.
*/
get spreadsheet_label(): string;
/**
* FIXME: is this different than what would be returned if
* we just used the default json serializer? (...)
*
* NOTE: we could return just the start if size === 1. if
* you pass an undefined to the Area class ctor it will reuse
* the start.
*
*/
toJSON(): IArea;
}