Sun, 03 Jul 2022 23:54:22 +0300
Replace item view with a text editor
src/documentmanager.cpp | file | annotate | diff | comparison | revisions | |
src/main.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.ui | file | annotate | diff | comparison | revisions | |
src/model.cpp | file | annotate | diff | comparison | revisions | |
src/model.h | file | annotate | diff | comparison | revisions | |
src/parser.cpp | file | annotate | diff | comparison | revisions | |
src/parser.h | file | annotate | diff | comparison | revisions |
--- 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<Model> newModel = std::make_unique<Model>(nullptr); QTextStream textStream{&file}; - Parser parser{file}; + Parser parser{textStream}; parser.parseBody(*newModel); std::optional<ModelId> 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());
--- 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 <GL/glew.h> static const QDir LOCALE_DIR {":/locale"}; @@ -48,10 +49,11 @@ public: ModelData(QObject* parent) : QObject {parent} {} std::unique_ptr<PartRenderer> canvas; - std::unique_ptr<QItemSelectionModel> itemSelectionModel; std::unique_ptr<EditTools> tools; std::unique_ptr<AxesLayer> axesLayer; std::unique_ptr<GridLayer> gridLayer; + std::unique_ptr<QTextDocument> textbuffer; + std::unique_ptr<QTextCursor> textcursor; Model* model; }; @@ -401,13 +403,13 @@ static QSet<ElementId> resolveIdsFromSelection(const ModelData* data) { - const auto selection = data->itemSelectionModel->selection(); +// const auto selection = data->itemSelectionModel->selection(); QSet<ElementId> 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<Setting::RecentFiles>(); @@ -502,8 +511,6 @@ ModelData* data = new ModelData(&documents); data->tools = std::make_unique<EditTools>(); data->canvas = std::make_unique<PartRenderer>(model, &documents, colorTable); - data->itemSelectionModel = std::make_unique<QItemSelectionModel>(); - data->itemSelectionModel->setModel(model); data->axesLayer = std::make_unique<AxesLayer>(); 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<GridLayer>(); @@ -514,31 +521,18 @@ data->canvas->setLayerEnabled(data->axesLayer.get(), setting<Setting::DrawAxes>()); 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<QTextDocument>(); + data->textbuffer->setPlainText(modeltext); + data->textbuffer->setDocumentLayout(new QPlainTextDocumentLayout(data->textbuffer.get())); + data->textcursor = std::make_unique<QTextCursor>(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<std::size_t> 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<int> 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<int> selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); - std::sort(selectedRows.begin(), selectedRows.end(), std::greater<int>{}); - 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<ModelData>(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<int> selectedRows = rows(ui.modelListView->selectionModel()->selectedRows()); - QString text; - for (int row : selectedRows) { - const std::size_t i = static_cast<std::size_t>(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);
--- 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 @@ <widget class="QWidget" name="dockWidgetContents_3"> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> - <widget class="QListView" name="modelListView"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - <property name="verticalScrollMode"> - <enum>QAbstractItemView::ScrollPerPixel</enum> - </property> - <property name="horizontalScrollMode"> - <enum>QAbstractItemView::ScrollPerPixel</enum> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="selectionRectVisible"> - <bool>true</bool> - </property> - </widget> + <widget class="QPlainTextEdit" name="modelEdit"/> </item> </layout> </widget> @@ -609,21 +587,5 @@ </hint> </hints> </connection> - <connection> - <sender>actionSelectAll</sender> - <signal>triggered()</signal> - <receiver>modelListView</receiver> - <slot>selectAll()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>589</x> - <y>216</y> - </hint> - </hints> - </connection> </connections> </ui>
--- 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"; } }
--- 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<typename T>
--- 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.
--- 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);