# HG changeset patch # User Teemu Piippo # Date 1656881662 -10800 # Node ID 3ea38fd469caff400c2dee1f6635488e7dc70120 # Parent 2aa15daa021614255c108cad0ab0ec7aa4abe0ce Replace item view with a text editor diff -r 2aa15daa0216 -r 3ea38fd469ca src/documentmanager.cpp --- a/src/documentmanager.cpp Sun Jul 03 22:32:50 2022 +0300 +++ b/src/documentmanager.cpp Sun Jul 03 23:54:22 2022 +0300 @@ -121,7 +121,7 @@ file.open(QFile::ReadOnly | QFile::Text); std::unique_ptr newModel = std::make_unique(nullptr); QTextStream textStream{&file}; - Parser parser{file}; + Parser parser{textStream}; parser.parseBody(*newModel); std::optional result; if (file.error() == QFile::NoError) @@ -195,7 +195,8 @@ QSaveFile file{info->path}; file.setDirectWriteFallback(true); if (file.open(QSaveFile::WriteOnly)) { - ::save(*info->model.get(), &file); + QTextStream stream{&file}; + ::save(*info->model.get(), &stream); const bool commitSucceeded = file.commit(); if (not commitSucceeded) { errors << QObject::tr("Could not save: %1").arg(file.errorString()); diff -r 2aa15daa0216 -r 3ea38fd469ca src/main.cpp --- a/src/main.cpp Sun Jul 03 22:32:50 2022 +0300 +++ b/src/main.cpp Sun Jul 03 23:54:22 2022 +0300 @@ -21,6 +21,7 @@ #include "src/ui/objecteditor.h" #include "src/version.h" #include "src/widgets/colorselectdialog.h" +#include "src/parser.h" #include static const QDir LOCALE_DIR {":/locale"}; @@ -48,10 +49,11 @@ public: ModelData(QObject* parent) : QObject {parent} {} std::unique_ptr canvas; - std::unique_ptr itemSelectionModel; std::unique_ptr tools; std::unique_ptr axesLayer; std::unique_ptr gridLayer; + std::unique_ptr textbuffer; + std::unique_ptr textcursor; Model* model; }; @@ -401,13 +403,13 @@ static QSet resolveIdsFromSelection(const ModelData* data) { - const auto selection = data->itemSelectionModel->selection(); +// const auto selection = data->itemSelectionModel->selection(); QSet selectedIndexes; - for (const QModelIndex& qindex : selection.indexes()) { +/* for (const QModelIndex& qindex : selection.indexes()) { const std::size_t row = unsigned_cast(qindex.row()); selectedIndexes.insert(data->model->idAt(row)); } - return selectedIndexes; +*/ return selectedIndexes; } int main(int argc, char *argv[]) @@ -427,6 +429,11 @@ MessageLog messageLog; Signal settingsChanged; ui.setupUi(&mainWindow); + QFont monospace{"Monospace"}; + monospace.setStyleHint(QFont::TypeWriter); + monospace.setPointSize(10); + monospace.setFixedPitch(true); + ui.modelEdit->setFont(monospace); ToolWidgets toolWidgets{ .circleToolOptions = new CircleToolOptionsWidget{&mainWindow}, .objectEditor = new ObjectEditor{&mainWindow}, @@ -462,6 +469,7 @@ const auto executeAction = [&]( Model* model, const ModelAction& action ) { + /* std::visit(overloaded{ [model](const AppendToModel& action){ model->append(action.newElement); @@ -473,6 +481,7 @@ model->assignAt(action.position, action.newElement); }, }, action); + */ }; const auto restoreSettings = [&]{ recentlyOpenedFiles = setting(); @@ -502,8 +511,6 @@ ModelData* data = new ModelData(&documents); data->tools = std::make_unique(); data->canvas = std::make_unique(model, &documents, colorTable); - data->itemSelectionModel = std::make_unique(); - data->itemSelectionModel->setModel(model); data->axesLayer = std::make_unique(); constexpr glm::mat4 XZ = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}; data->gridLayer = std::make_unique(); @@ -514,31 +521,18 @@ data->canvas->setLayerEnabled(data->axesLayer.get(), setting()); data->canvas->addRenderLayer(data->gridLayer.get()); data->canvas->addRenderLayer(data->tools.get()); + QString modeltext; + QTextStream stream{&modeltext}; + ::save(*model, &stream); + data->textbuffer = std::make_unique(); + data->textbuffer->setPlainText(modeltext); + data->textbuffer->setDocumentLayout(new QPlainTextDocumentLayout(data->textbuffer.get())); + data->textcursor = std::make_unique(data->textbuffer.get()); documents.setModelPayload(modelId, data); QObject::connect( data->tools.get(), &EditTools::modelAction, std::bind(executeAction, model, std::placeholders::_1)); - QObject::connect( - data->itemSelectionModel.get(), - &QItemSelectionModel::selectionChanged, - [modelId, &documents, &toolWidgets]{ - ModelData* data = findModelData(&documents, modelId); - if (data != nullptr) { - data->canvas->setSelection(resolveIdsFromSelection(data)); - /* - if (indices.size() == 1) { - opt index = data->model->find(*indices.begin()); - if (index.has_value()) { - toolWidgets.objectEditor->setObject((*data->model)[*index]); - } - } - else { - toolWidgets.objectEditor->reset(); - } - */ - } - }); data->canvas->setRenderPreferences(renderPreferences); QObject::connect( data->tools.get(), @@ -546,6 +540,7 @@ [&](const QString& newStatusText) { mainWindow.statusBar()->showMessage(newStatusText); }); +#if 0 QObject::connect( data->tools.get(), &EditTools::select, @@ -553,7 +548,7 @@ ModelData* data = findModelData(&documents, modelId); if (data != nullptr) { if (not retain) { - data->itemSelectionModel->clear(); + data->textcursor->clearSelection(); } for (const ElementId id : indices) { opt index = data->model->find(id); @@ -564,6 +559,7 @@ } } }); +#endif QObject::connect(&settingsChanged, &Signal::triggered, [modelId, &documents]{ ModelData* data = findModelData(&documents, modelId); if (data != nullptr) { @@ -675,15 +671,6 @@ } } }); - QObject::connect(ui.actionDelete, &QAction::triggered, [&]{ - if (Model* model = currentModelBody(&ui, &documents)) { - std::vector selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); - std::sort(selectedRows.begin(), selectedRows.end(), std::greater{}); - for (int row : selectedRows) { - executeAction(model, DeleteFromModel{.position = unsigned_cast(row)}); - } - } - }); QObject::connect(ui.actionDrawAxes, &QAction::triggered, [&](bool drawAxes){ renderPreferences.drawAxes = drawAxes; saveSettings(); @@ -725,10 +712,8 @@ if (modelSubWindow != nullptr) { if (ModelData* data = documents.findPayload(modelSubWindow->modelId)) { checkEditingModeAction(data->tools->currentEditingMode()); - if (data->itemSelectionModel != nullptr) { - ui.modelListView->setModel(data->model); - ui.modelListView->setSelectionModel(data->itemSelectionModel.get()); - } + ui.modelEdit->setDocument(data->textbuffer.get()); + ui.modelEdit->setTextCursor(*data->textcursor); } } else { @@ -781,18 +766,17 @@ } ); QObject::connect( - ui.actionCopy, - &QAction::triggered, + ui.modelEdit, + &QPlainTextEdit::textChanged, [&]{ - if (Model* model = currentModelBody(&ui, &documents)) { - std::vector selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); - QString text; - for (int row : selectedRows) { - const std::size_t i = static_cast(row); - text += modelElementToString((*model)[i]); - text += QStringLiteral("\r\n"); - } - app.clipboard()->setText(text); + if (ModelData* data = currentModelData(&ui, &documents)) { + Model* const model = data->model; + model->clear(); + QString text = ui.modelEdit->toPlainText(); + QTextStream stream{&text}; + Parser parser(stream); + parser.parseBody(*data->model); + data->canvas->update(); } }); mainWindow.tabifyDockWidget(ui.messageLogDock, ui.toolOptionsDock); diff -r 2aa15daa0216 -r 3ea38fd469ca src/mainwindow.ui --- a/src/mainwindow.ui Sun Jul 03 22:32:50 2022 +0300 +++ b/src/mainwindow.ui Sun Jul 03 23:54:22 2022 +0300 @@ -217,29 +217,7 @@ - - - true - - - QAbstractItemView::ExtendedSelection - - - QAbstractItemView::SelectRows - - - QAbstractItemView::ScrollPerPixel - - - QAbstractItemView::ScrollPerPixel - - - true - - - true - - + @@ -609,21 +587,5 @@ - - actionSelectAll - triggered() - modelListView - selectAll() - - - -1 - -1 - - - 589 - 216 - - - diff -r 2aa15daa0216 -r 3ea38fd469ca src/model.cpp --- a/src/model.cpp Sun Jul 03 22:32:50 2022 +0300 +++ b/src/model.cpp Sun Jul 03 23:54:22 2022 +0300 @@ -274,11 +274,17 @@ return this->body.size(); } -void save(const Model &model, QIODevice *device) +void Model::clear() { - QTextStream out{device}; + this->beginResetModel(); + this->body.clear(); + this->endResetModel(); +} + +void save(const Model &model, QTextStream* stream) +{ for (std::size_t i = 0; i < model.size(); ++i) { - out << modelElementToString(model[i]) << "\r\n"; + (*stream) << modelElementToString(model[i]) << "\r\n"; } } diff -r 2aa15daa0216 -r 3ea38fd469ca src/model.h --- a/src/model.h Sun Jul 03 22:32:50 2022 +0300 +++ b/src/model.h Sun Jul 03 23:54:22 2022 +0300 @@ -228,6 +228,7 @@ QVariant data(const QModelIndex& index, int role) const override; const ModelElement& operator[](std::size_t index) const; std::size_t size() const; + void clear(); auto operator[](const std::size_t index) { struct { Model& model; @@ -247,7 +248,7 @@ } }; -void save(const Model& model, QIODevice *device); +void save(const Model& model, QTextStream* stream); void updateHeaderNameField(Model& model, const QString &name); template diff -r 2aa15daa0216 -r 3ea38fd469ca src/parser.cpp --- a/src/parser.cpp Sun Jul 03 22:32:50 2022 +0300 +++ b/src/parser.cpp Sun Jul 03 23:54:22 2022 +0300 @@ -30,16 +30,16 @@ /* * Constructs an LDraw parser */ -Parser::Parser(QIODevice& device, QObject* parent) : +Parser::Parser(QTextStream& stream, QObject* parent) : QObject {parent}, - device {device} {} + stream {stream} {} /* * Reads a single line from the device. */ QString Parser::readLine() { - return QString::fromUtf8(this->device.readLine()).trimmed(); + return this->stream.readLine().trimmed(); } /** @@ -49,7 +49,7 @@ void Parser::parseBody(Model& model) { bool invertNext = false; - while (not this->device.atEnd()) + while (not this->stream.atEnd()) { // Some LDraw parts such as 53588.dat can contain "BFC INVERTNEXT" with multiple inner whitespaces. // So we need to pass the string through QString::simplified to catch these cases. diff -r 2aa15daa0216 -r 3ea38fd469ca src/parser.h --- a/src/parser.h Sun Jul 03 22:32:50 2022 +0300 +++ b/src/parser.h Sun Jul 03 23:54:22 2022 +0300 @@ -24,11 +24,11 @@ { Q_OBJECT public: - Parser(QIODevice& device, QObject* parent = nullptr); + Parser(QTextStream& stream, QObject* parent = nullptr); void parseBody(Model &model); private: QString readLine(); - QIODevice& device; + QTextStream& stream; }; ModelElement parseLDrawLine(QString line);