diff --git a/cell/api.js b/cell/api.js index b7d2ba2961..627c7b4a4e 100644 --- a/cell/api.js +++ b/cell/api.js @@ -8008,16 +8008,27 @@ var editor; } }; - spreadsheet_api.prototype.asc_fillHandleDone = function(startRange, endRange, bCtrl) { + spreadsheet_api.prototype.asc_fillHandleDone = function(range) { if (this.canEdit()) { let wb = this.wb; if (!wb) { return; } - wb.fillHandleDone(startRange, endRange, bCtrl); + wb.fillHandleDone(range); } }; + spreadsheet_api.prototype.asc_canFillHandle = function(range) { + if (this.canEdit()) { + let wb = this.wb; + if (!wb) { + return; + } + return wb.canFillHandle(range); + } + return false; + }; + /* @@ -8564,6 +8575,8 @@ var editor; prot["asc_updateExternalReferences"] = prot.asc_updateExternalReferences; prot["asc_removeExternalReferences"] = prot.asc_removeExternalReferences; + prot["asc_fillHandleDone"] = prot.asc_fillHandleDone; + prot["asc_canFillHandle"] = prot.asc_canFillHandle; })(window); diff --git a/cell/model/autofilters.js b/cell/model/autofilters.js index 9a14e99dac..e8ba46a30d 100644 --- a/cell/model/autofilters.js +++ b/cell/model/autofilters.js @@ -5791,6 +5791,9 @@ }, _isEmptyRange: function (ar, addDelta) { + if (addDelta == null) { + addDelta = 0; + } var range = this.worksheet.getRange3(Math.max(0, ar.r1 - addDelta), Math.max(0, ar.c1 - addDelta), ar.r2 + addDelta, ar.c2 + addDelta); var res = true; range._foreachNoEmpty(function (cell) { diff --git a/cell/view/WorkbookView.js b/cell/view/WorkbookView.js index 08c372a423..9491ef9ad0 100644 --- a/cell/view/WorkbookView.js +++ b/cell/view/WorkbookView.js @@ -1610,11 +1610,17 @@ ws.applyFillHandle(x, y, ctrlPress); }; - WorkbookView.prototype.fillHandleDone = function(startRange, endRange, bCtrl) { + WorkbookView.prototype.fillHandleDone = function(range) { var ws = this.getWorksheet(); - ws.fillHandleDone(startRange, endRange, bCtrl); + ws.fillHandleDone(range); }; + WorkbookView.prototype.canFillHandle = function(range) { + var ws = this.getWorksheet(); + return ws.canFillHandle(range); + }; + + // Обработка перемещения диапазона WorkbookView.prototype._onMoveRangeHandle = function(x, y, callback) { var ws = this.getWorksheet(); diff --git a/cell/view/WorksheetView.js b/cell/view/WorksheetView.js index 5e5353a825..19571878e8 100644 --- a/cell/view/WorksheetView.js +++ b/cell/view/WorksheetView.js @@ -10516,55 +10516,153 @@ } }; - WorksheetView.prototype.fillHandleDone = function (startRange, endRange, bCtrl) { - //на входе имеем два диапазона, определяем точку крайней ячейки автозаполнения - if (!startRange) { - startRange = this.model.selectionRange.getLast().clone(); - } - if (!endRange) { - endRange = this.model.selectionRange.getLast().clone(); - } - - startRange = typeof startRange === "string" ? AscCommonExcel.g_oRangeCache.getAscRange(startRange) : startRange; - endRange = typeof endRange === "string" ? AscCommonExcel.g_oRangeCache.getAscRange(endRange) : endRange; - - this.activeFillHandle = startRange.clone(); - - if (startRange.r1 !== endRange.r1 || startRange.r2 !== endRange.r2) { - this.fillHandleDirection = 1; - if (startRange.r1 === endRange.r1 && startRange.r1 <= endRange.r2 && startRange.r2 >= endRange.r2) { - //попали внутрь диапазона, т.е. маркером пошли наверх - this.activeFillHandle.r2 = endRange.r2 + 1; - this.activeFillHandle.r1 = startRange.r2; - this.fillHandleArea = 2; - } else if (endRange.r1 < startRange.r1) { - this.activeFillHandle.r2 = endRange.r1; - this.activeFillHandle.r1 = startRange.r2; - this.fillHandleArea = 1; - } else if (startRange.r1 === endRange.r1 && endRange.r2 > startRange.r2) { - this.activeFillHandle.r2 = endRange.r2; - this.activeFillHandle.r1 = endRange.r1; - this.fillHandleArea = 3; + WorksheetView.prototype.canFillHandle = function (range) { + //if don't have empty rows/columns + //if all range is empty + if (!range) { + range = this.model.selectionRange.getLast().clone(); + } + + range = typeof range === "string" ? AscCommonExcel.g_oRangeCache.getAscRange(range) : range; + + if (this.model.autoFilters._isEmptyRange(range)) { + return false; + } + + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c1, range.r1, range.c2, range.r1))) { + return true; + } + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c1, range.r2, range.c2, range.r2))) { + return true; + } + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c1, range.r1, range.c1, range.r2))) { + return true; + } + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c2, range.r1, range.c2, range.r2))) { + return true; + } + + return false; + }; + + WorksheetView.prototype.fillHandleDone = function (range) { + let t = this; + + let doFill = function (_start, _end) { + t.model.selectionRange.getLast().assign2(_start); + t.activeFillHandle = _end.clone(); + + if (_start.r1 !== _end.r1 || _start.r2 !== _end.r2) { + t.fillHandleDirection = 1; + if (_start.r1 === _end.r1 && _start.r1 <= _end.r2 && _start.r2 >= _end.r2) { + //inside range, go up + t.activeFillHandle.r2 = _end.r2 + 1; + t.activeFillHandle.r1 = _start.r2; + t.fillHandleArea = 2; + } else if (_end.r1 < _start.r1) { + t.activeFillHandle.r2 = _end.r1; + t.activeFillHandle.r1 = _start.r2; + t.fillHandleArea = 1; + } else if (_start.r1 === _end.r1 && _end.r2 > _start.r2) { + t.activeFillHandle.r2 = _end.r2; + t.activeFillHandle.r1 = _end.r1; + t.fillHandleArea = 3; + } + } else { + t.fillHandleDirection = 0; + if (_start.c1 === _end.c1 && _start.c1 <= _end.c2 && _start.c2 >= _end.c2) { + //inside range, gp down + t.activeFillHandle.c2 = _end.c2 + 1; + t.activeFillHandle.c1 = _start.c2; + t.fillHandleArea = 2; + } else if (_end.c1 < _start.c1) { + t.activeFillHandle.c2 = _end.c1; + t.activeFillHandle.c1 = _start.c2; + t.fillHandleArea = 1; + } else if (_start.c1 === _end.c1 && _end.c2 > _start.c2) { + t.activeFillHandle.c2 = _end.c2; + t.activeFillHandle.c1 = _end.c1; + t.fillHandleArea = 3; + } + } + + t.applyFillHandle(null, null, null, true); + }; + + + //only end range - selected range + //1. search base + var activeCell = this.model.selectionRange.activeCell.clone(); + + if (!range) { + range = this.model.selectionRange.getLast().clone(); + } + range = typeof range === "string" ? AscCommonExcel.g_oRangeCache.getAscRange(range) : range; + + let i; + let baseRow1 = range.r1; + let baseRow2 = range.r2; + for (i = range.r1; i <= range.r2; i++) { + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c1, i, range.c2, i))) { + baseRow1++; + } else { + break; } - } else { - this.fillHandleDirection = 0; - if (startRange.c1 === endRange.c1 && startRange.c1 <= endRange.c2 && startRange.c2 >= endRange.c2) { - //попали внутрь диапазона, т.е. маркером пошли наверх - this.activeFillHandle.c2 = endRange.c2 + 1; - this.activeFillHandle.c1 = startRange.c2; - this.fillHandleArea = 2; - } else if (endRange.c1 < startRange.c1) { - this.activeFillHandle.c2 = endRange.c1; - this.activeFillHandle.c1 = startRange.c2; - this.fillHandleArea = 1; - } else if (startRange.c1 === endRange.c1 && endRange.c2 > startRange.c2) { - this.activeFillHandle.c2 = endRange.c2; - this.activeFillHandle.c1 = endRange.c1; - this.fillHandleArea = 3; + } + for (i = range.r2; i >= range.r1; i--) { + if (this.model.autoFilters._isEmptyRange(new Asc.Range(range.c1, i, range.c2, i))) { + baseRow2--; + } else { + break; + } + } + let baseCol1 = range.c1; + let baseCol2 = range.c2; + for (i = range.c1; i <= range.c2; i++) { + if (this.model.autoFilters._isEmptyRange(new Asc.Range(i, range.r1, i, range.r2))) { + baseCol1++; + } else { + break; } } + for (i = range.c2; i >= range.c1; i--) { + if (this.model.autoFilters._isEmptyRange(new Asc.Range(i, range.r1, i, range.r2))) { + baseCol2--; + } else { + break; + } + } + + History.Create_NewPoint(); + History.StartTransaction(); + + let baseRange = new Asc.Range(baseCol1, baseRow1, baseCol2, baseRow2); + //1. take base and expand up/down in empty cells + if (range.r1 !== baseRow1) { + doFill(baseRange, new Asc.Range(baseRange.c1, range.r1, baseRange.c2, baseRange.r2)); + } + if (range.r2 !== baseRow2) { + doFill(baseRange, new Asc.Range(baseRange.c1, baseRange.r1, baseRange.c2, range.r2)); + } + + //get new base + baseRange = new Asc.Range(baseCol1, range.r1, baseCol2, range.r2); + + //2. take base and expand left/right in empty cells + if (range.c1 !== baseCol1) { + doFill(baseRange, new Asc.Range(range.c1, baseRange.r1, baseRange.c2, baseRange.r2)); + } + if (range.c2 !== baseCol2) { + doFill(baseRange, new Asc.Range(baseRange.c1, baseRange.r1, range.c2, baseRange.r2)); + } - this.applyFillHandle(null, null, bCtrl); + History.SetSelection(range); + History.SetSelectionRedo(range); + History.EndTransaction(); + + t.model.selectionRange.getLast().assign2(range); + t.model.selectionRange.activeCell = activeCell; + t.draw(); }; /* Функция для работы автозаполнения (selection). (x, y) - координаты точки мыши на области */ @@ -10951,7 +11049,7 @@ }; /* Функция для применения автозаполнения */ - WorksheetView.prototype.applyFillHandle = function (x, y, ctrlPress) { + WorksheetView.prototype.applyFillHandle = function (x, y, ctrlPress, opt_doNotDraw) { var t = this; if (null !== this.resizeTableIndex) { @@ -10964,16 +11062,14 @@ t.af_changeTableRange(table.DisplayName, t.activeFillHandle.clone()); } } - this.cleanSelection(); + !opt_doNotDraw && this.cleanSelection(); t.activeFillHandle = null; t.resizeTableIndex = null; t.fillHandleDirection = -1; - t._drawSelection(); + !opt_doNotDraw && t._drawSelection(); return; } - console.log("r1: " + this.activeFillHandle.r1 + " r2: " + this.activeFillHandle.r2 + "c1: " + this.activeFillHandle.c1 + " c2: " + this.activeFillHandle.c2) - // Текущее выделение (к нему применится автозаполнение) var arn = t.model.selectionRange.getLast(); var range = t.model.getRange3(arn.r1, arn.c1, arn.r2, arn.c2); @@ -11091,7 +11187,7 @@ // Обновляем выделенные ячейки t._updateRange(arn); - t.draw(); + !opt_doNotDraw && t.draw(); } else { t.handlers.trigger("onErrorEvent", c_oAscError.ID.CannotFillRange, c_oAscError.Level.NoCritical); @@ -11108,7 +11204,7 @@ t.activeFillHandle = null; t.fillHandleDirection = -1; // Перерисовываем - t._drawSelection(); + !opt_doNotDraw && t._drawSelection(); } }; @@ -11123,7 +11219,7 @@ t.activeFillHandle = null; t.fillHandleDirection = -1; // Перерисовываем - t._drawSelection(); + !opt_doNotDraw && t._drawSelection(); } }, true); return; @@ -11133,7 +11229,7 @@ this.activeFillHandle = null; this.fillHandleDirection = -1; // Перерисовываем - this._drawSelection(); + !opt_doNotDraw && this._drawSelection(); this.model.workbook.handlers.trigger("asc_onError", c_oAscError.ID.LockedCellPivot, c_oAscError.Level.NoCritical); @@ -11146,7 +11242,7 @@ this.activeFillHandle = null; this.fillHandleDirection = -1; // Перерисовываем - this._drawSelection(); + !opt_doNotDraw && this._drawSelection(); this.model.workbook.handlers.trigger("asc_onError", c_oAscError.ID.CannotChangeFormulaArray, c_oAscError.Level.NoCritical); @@ -11162,7 +11258,7 @@ this.activeFillHandle = null; this.fillHandleDirection = -1; // Перерисовываем - this._drawSelection(); + !opt_doNotDraw && this._drawSelection(); } };