1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-25 13:05:07 +00:00

Spreadsheet: Add support for copying ranges of cells to other cells

Now the entire range is copied to the area around the target cell,
translating the current cursor to the target.
This commit is contained in:
AnotherTest 2020-11-07 23:18:41 +03:30 committed by Andreas Kling
parent 7878596532
commit e99c2261e3
8 changed files with 187 additions and 53 deletions

View file

@ -27,6 +27,7 @@
#include "HelpWindow.h"
#include "Spreadsheet.h"
#include "SpreadsheetWidget.h"
#include <AK/ScopeGuard.h>
#include <LibCore/ArgsParser.h>
#include <LibCore/File.h>
#include <LibGUI/AboutDialog.h>
@ -153,11 +154,26 @@ int main(int argc, char* argv[])
auto& edit_menu = menubar->add_menu("Edit");
edit_menu.add_action(GUI::CommonActions::make_copy_action([&](auto&) {
/// text/x-spreadsheet-data:
/// - currently selected cell
/// - selected cell+
auto& cells = spreadsheet_widget.current_worksheet().selected_cells();
ASSERT(!cells.is_empty());
StringBuilder text_builder, url_builder;
bool first = true;
auto cursor = spreadsheet_widget.current_selection_cursor();
if (cursor) {
Spreadsheet::Position position { spreadsheet_widget.current_worksheet().column(cursor->column()), (size_t)cursor->row() };
url_builder.append(position.to_url().to_string());
url_builder.append('\n');
}
for (auto& cell : cells) {
if (first && !cursor) {
url_builder.append(cell.to_url().to_string());
url_builder.append('\n');
}
url_builder.append(cell.to_url().to_string());
url_builder.append('\n');
@ -175,41 +191,30 @@ int main(int argc, char* argv[])
},
window));
edit_menu.add_action(GUI::CommonActions::make_paste_action([&](auto&) {
ScopeGuard update_after_paste { [&] { spreadsheet_widget.current_worksheet().update(); } };
auto& cells = spreadsheet_widget.current_worksheet().selected_cells();
ASSERT(!cells.is_empty());
const auto& data = GUI::Clipboard::the().data_and_type();
if (auto spreadsheet_data = data.metadata.get("text/x-spreadsheet-data"); spreadsheet_data.has_value()) {
Vector<URL> urls;
for (auto line : spreadsheet_data.value().split_view('\n')) {
if (line.is_empty())
continue;
URL url { line };
if (!url.is_valid())
continue;
urls.append(move(url));
Vector<Spreadsheet::Position> source_positions, target_positions;
auto& sheet = spreadsheet_widget.current_worksheet();
for (auto& line : spreadsheet_data.value().split_view('\n')) {
dbg() << "Paste line '" << line << "'";
auto position = sheet.position_from_url(line);
if (position.has_value())
source_positions.append(position.release_value());
}
if (urls.size() == 1 && cells.size() == 1) {
auto& cell = *cells.begin();
auto& url = urls.first();
auto* source_cell = spreadsheet_widget.current_worksheet().from_url(url);
if (source_cell) {
auto& target_cell = spreadsheet_widget.current_worksheet().ensure(cell);
auto references = target_cell.referencing_cells;
target_cell = *source_cell;
target_cell.referencing_cells = move(references);
target_cell.dirty = true;
spreadsheet_widget.update();
}
for (auto& position : spreadsheet_widget.current_worksheet().selected_cells())
target_positions.append(position);
if (source_positions.is_empty())
return;
}
if (urls.size() != cells.size()) {
// FIXME: Somehow copy a bunch of cells into another bunch of cells.
TODO();
}
auto first_position = source_positions.take_first();
sheet.copy_cells(move(source_positions), move(target_positions), first_position);
} else {
for (auto& cell : spreadsheet_widget.current_worksheet().selected_cells())
spreadsheet_widget.current_worksheet().ensure(cell).set_data(StringView { data.data.data(), data.data.size() });