Skip to content

Commit

Permalink
fix(editor): range selector and range drag (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
DR-Univer committed Mar 27, 2024
1 parent 9ab34b6 commit 02e9647
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 11 deletions.
71 changes: 68 additions & 3 deletions packages/sheets-formula/src/controllers/prompt.controller.ts
Expand Up @@ -74,6 +74,7 @@ import {
getPrimaryForRange,
NORMAL_SELECTION_PLUGIN_NAME,
SelectionManagerService,
setEndForRange,
} from '@univerjs/sheets';
import type { EditorBridgeService, SelectionShape } from '@univerjs/sheets-ui';
import {
Expand Down Expand Up @@ -149,7 +150,7 @@ export class PromptController extends Disposable {

private _previousEditorUnitId: Nullable<string>;

private _executeBlurSetTimeout: number | NodeJS.Timeout = -1;
private _existsSequenceNode = false;

constructor(
@ICommandService private readonly _commandService: ICommandService,
Expand Down Expand Up @@ -882,9 +883,11 @@ export class PromptController extends Disposable {
this._selectionManagerService.clear();

if (sequenceNodes == null || sequenceNodes.length === 0) {
this._existsSequenceNode = false;
bodyList.forEach((body) => (body!.textRuns = []));
} else {
// this._lastSequenceNodes = sequenceNodes;
this._existsSequenceNode = true;
const { textRuns, refSelections } = this._buildTextRuns(sequenceNodes);
bodyList.forEach((body) => (body!.textRuns = textRuns));

Expand Down Expand Up @@ -988,7 +991,13 @@ export class PromptController extends Disposable {

const gridRange = deserializeRangeWithSheet(token);

const { unitId: refUnitId, sheetName, range } = gridRange;
const { unitId: refUnitId, sheetName, range: rawRange } = gridRange;

/**
* pro/issues/436
* When the range is an entire row or column, NaN values need to be corrected.
*/
const range = setEndForRange(rawRange, worksheet.getRowCount(), worksheet.getColumnCount());

if (refUnitId != null && refUnitId.length > 0 && unitId !== refUnitId) {
continue;
Expand Down Expand Up @@ -1381,9 +1390,65 @@ export class PromptController extends Disposable {
// }
}

/**
* pro/issues/450
* In range selection mode, certain measures are implemented to ensure that the selection behavior is processed correctly.
*/
private _focusIsOnlyRange(selectionCount: number) {
const currentEditor = this._editorService.getFocusEditor();
if (!currentEditor) {
return true;
}

if (!currentEditor.onlyInputRange()) {
return true;
}

if (this._existsSequenceNode) {
return true;
}

if (selectionCount > 1 || (this._previousSequenceNodes != null && this._previousSequenceNodes.length > 0)) {
return true;
}

if (this._previousInsertRefStringIndex != null) {
this._previousInsertRefStringIndex += 1;
}

return false;
}

/**
* pro/issues/450
* In range selection mode, certain measures are implemented to ensure that the selection behavior is processed correctly.
*/
private _resetSequenceNodes(selectionCount: number) {
const currentEditor = this._editorService.getFocusEditor();
if (!currentEditor) {
return;
}

if (!currentEditor.onlyInputRange()) {
return;
}

if (selectionCount > 1) {
return;
}

if (this._existsSequenceNode) {
this._formulaPromptService.clearSequenceNodes();
this._previousRangesCount = 0;
this._existsSequenceNode = false;
}
}

private _inertControlSelection(selectionWithStyles: ISelectionWithStyle[]) {
const currentSelection = selectionWithStyles[selectionWithStyles.length - 1];

this._resetSequenceNodes(selectionWithStyles.length);

if (
(selectionWithStyles.length === this._previousRangesCount || this._previousRangesCount === 0) &&
this._previousSequenceNodes != null
Expand All @@ -1405,7 +1470,7 @@ export class PromptController extends Disposable {

this._previousInsertRefStringIndex = this._currentInsertRefStringIndex;

if (!matchRefDrawToken(char)) {
if (!matchRefDrawToken(char) && this._focusIsOnlyRange(selectionWithStyles.length)) {
this._formulaPromptService.insertSequenceString(this._currentInsertRefStringIndex, matchToken.COMMA);

insertNodes = this._formulaPromptService.getSequenceNodes();
Expand Down
38 changes: 31 additions & 7 deletions packages/sheets/src/commands/commands/utils/selection-utils.ts
Expand Up @@ -98,21 +98,45 @@ export function getCellAtRowCol(row: number, col: number, worksheet: Worksheet):
return destRange;
}

export function setEndForRange(range: IRange, rowCount: number, columnCount: number) {
const { startRow, startColumn, endRow, endColumn } = range;

if (Number.isNaN(startRow)) {
range.startRow = 0;
}

if (Number.isNaN(endRow)) {
range.endRow = rowCount;
}

if (Number.isNaN(startColumn)) {
range.startColumn = 0;
}

if (Number.isNaN(endColumn)) {
range.endColumn = columnCount;
}

return range;
}

/**
* Get the default primary cell (the most top-left cell) of a range.
* @param range
* @param worksheet
*/
export function getPrimaryForRange(range: IRange, worksheet: Worksheet): ISelectionCell {
const mergedRange = worksheet.getMergedCell(range.startRow, range.startColumn);
const startRow = Number.isNaN(range.startRow) ? 0 : range.startRow;
const startColumn = Number.isNaN(range.startColumn) ? 0 : range.startColumn;
const mergedRange = worksheet.getMergedCell(startRow, startColumn);
if (!mergedRange) {
return {
startRow: range.startRow,
startColumn: range.startColumn,
startRow,
startColumn,
endRow: range.startRow,
endColumn: range.startColumn,
actualRow: range.startRow,
actualColumn: range.startColumn,
actualRow: startRow,
actualColumn: startColumn,
rangeType: RANGE_TYPE.NORMAL,
isMerged: false,
isMergedMainCell: false,
Expand All @@ -121,8 +145,8 @@ export function getPrimaryForRange(range: IRange, worksheet: Worksheet): ISelect

return {
...mergedRange,
actualRow: range.startRow,
actualColumn: range.startColumn,
actualRow: startRow,
actualColumn: startColumn,
rangeType: RANGE_TYPE.NORMAL,
isMerged: true,
isMergedMainCell: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/sheets/src/index.ts
Expand Up @@ -42,7 +42,7 @@ export {
SELECTION_CONTROL_BORDER_BUFFER_WIDTH,
transformCellDataToSelectionData,
} from './basics/selection';
export { alignToMergedCellsBorders, getCellAtRowCol } from './commands/commands/utils/selection-utils';
export { alignToMergedCellsBorders, getCellAtRowCol, setEndForRange } from './commands/commands/utils/selection-utils';
export { MAX_CELL_PER_SHEET_KEY } from './controllers/config/config';
export { BorderStyleManagerService, type IBorderInfo } from './services/border-style-manager.service';
export { getCurrentSheetDisabled$, SheetEditablePermission, SheetPermissionService } from './services/permission';
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/src/services/editor/editor.service.ts
Expand Up @@ -307,6 +307,8 @@ export interface IEditorService {

setFocusId(id: Nullable<string>): void;
getFocusId(): Nullable<string>;

getFocusEditor(): Readonly<Nullable<Editor>>;
}

export class EditorService extends Disposable implements IEditorService, IDisposable {
Expand Down Expand Up @@ -367,6 +369,12 @@ export class EditorService extends Disposable implements IEditorService, IDispos
return this._focusEditorUnitId;
}

getFocusEditor() {
if (this._focusEditorUnitId) {
return this.getEditor(this._focusEditorUnitId);
}
}

isEditor(editorUnitId: string) {
return this._editors.has(editorUnitId);
}
Expand Down

0 comments on commit 02e9647

Please sign in to comment.