diff options
-rw-r--r-- | Userland/Applications/Spreadsheet/Spreadsheet.cpp | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/Userland/Applications/Spreadsheet/Spreadsheet.cpp b/Userland/Applications/Spreadsheet/Spreadsheet.cpp index 91538d068f..a1552a4246 100644 --- a/Userland/Applications/Spreadsheet/Spreadsheet.cpp +++ b/Userland/Applications/Spreadsheet/Spreadsheet.cpp @@ -294,6 +294,12 @@ Position Sheet::offset_relative_to(const Position& base, const Position& offset, void Sheet::copy_cells(Vector<Position> from, Vector<Position> to, Optional<Position> resolve_relative_to, CopyOperation copy_operation) { + // Disallow misaligned copies. + if (to.size() > 1 && from.size() != to.size()) { + dbgln("Cannot copy {} cells to {} cells", from.size(), to.size()); + return; + } + Vector<Position> target_cells; for (auto& position : from) target_cells.append(resolve_relative_to.has_value() ? offset_relative_to(to.first(), position, resolve_relative_to.value()) : to.first()); @@ -313,39 +319,46 @@ void Sheet::copy_cells(Vector<Position> from, Vector<Position> to, Optional<Posi source_cell->set_data(""); }; - if (from.size() == to.size()) { - auto from_it = from.begin(); - // FIXME: Ordering. - for (auto& position : to) - copy_to(*from_it++, position); - - return; + // Resolve each index as relative to the first index offset from the selection. + auto& target = to.first(); + + auto top_left_most_position_from = from.first(); + auto bottom_right_most_position_from = from.first(); + for (auto& position : from) { + if (position.row > bottom_right_most_position_from.row) + bottom_right_most_position_from = position; + else if (position.column > bottom_right_most_position_from.column) + bottom_right_most_position_from = position; + + if (position.row < top_left_most_position_from.row) + top_left_most_position_from = position; + else if (position.column < top_left_most_position_from.column) + top_left_most_position_from = position; } - if (to.size() == 1) { - // Resolve each index as relative to the first index offset from the selection. - auto& target = to.first(); - - for (auto& position : from) { - dbgln_if(COPY_DEBUG, "Paste from '{}' to '{}'", position.to_url(*this), target.to_url(*this)); - copy_to(position, resolve_relative_to.has_value() ? offset_relative_to(target, position, resolve_relative_to.value()) : target); + Vector<Position> ordered_from; + auto current_column = top_left_most_position_from.column; + auto current_row = top_left_most_position_from.row; + for ([[maybe_unused]] auto& position : from) { + for (auto& position : from) + if (position.row == current_row && position.column == current_column) + ordered_from.append(position); + + if (current_column >= bottom_right_most_position_from.column) { + current_column = top_left_most_position_from.column; + current_row += 1; + } else { + current_column += 1; } - - return; } - if (from.size() == 1) { - // Fill the target selection with the single cell. - auto& source = from.first(); - for (auto& position : to) { - dbgln_if(COPY_DEBUG, "Paste from '{}' to '{}'", source.to_url(*this), position.to_url(*this)); - copy_to(source, resolve_relative_to.has_value() ? offset_relative_to(position, source, resolve_relative_to.value()) : position); - } - return; - } + if (target.row > top_left_most_position_from.row || (target.row >= top_left_most_position_from.row && target.column > top_left_most_position_from.column)) + ordered_from.reverse(); - // Just disallow misaligned copies. - dbgln("Cannot copy {} cells to {} cells", from.size(), to.size()); + for (auto& position : ordered_from) { + dbgln_if(COPY_DEBUG, "Paste from '{}' to '{}'", position.to_url(*this), target.to_url(*this)); + copy_to(position, resolve_relative_to.has_value() ? offset_relative_to(target, position, resolve_relative_to.value()) : target); + } } RefPtr<Sheet> Sheet::from_json(const JsonObject& object, Workbook& workbook) |