Merge commit

Sat, 23 Jul 2022 01:38:43 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Sat, 23 Jul 2022 01:38:43 +0300
changeset 340
e17e07661f4c
parent 339
4787d05e9c89 (current diff)
parent 338
719b909a7d2b (diff)
child 341
71c8cea3c205

Merge commit

--- a/src/documentmanager.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/documentmanager.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -20,6 +20,7 @@
 #include <QDir>
 #include <QFileInfo>
 #include <QSaveFile>
+#include <QPlainTextDocumentLayout>
 #include <deque>
 #include "src/documentmanager.h"
 #include "src/parser.h"
@@ -29,6 +30,13 @@
 {
 }
 
+static std::unique_ptr<QTextDocument> newTextDocument()
+{
+	std::unique_ptr<QTextDocument> newModel = std::make_unique<QTextDocument>(nullptr);
+	newModel->setDocumentLayout(new QPlainTextDocumentLayout{newModel.get()});
+	return newModel;
+}
+
 /**
  * @brief Creates a new model.
  * @returns the ID of the new model
@@ -37,7 +45,7 @@
 {
 	const ModelId modelId{++this->modelIdCounter};
 	this->openModels.emplace(std::make_pair(modelId, ModelInfo{
-		.model = std::make_unique<Model>(this),
+		.model = newTextDocument(),
 		.id = modelId,
 		.opentype = OpenType::ManuallyOpened,
 	}));
@@ -46,7 +54,7 @@
 	return modelId;
 }
 
-Model* DocumentManager::findDependencyByName(const ModelId modelId, const QString& name)
+QTextDocument* DocumentManager::findDependencyByName(const ModelId modelId, const QString& name)
 {
 	const auto modelsIterator = this->openModels.find(modelId);
 	if (modelsIterator != std::end(this->openModels)) {
@@ -70,7 +78,7 @@
  * @param modelId id of model to find
  * @returns model pointer or null
  */
-Model *DocumentManager::getModelById(ModelId modelId)
+QTextDocument *DocumentManager::getModelById(ModelId modelId)
 {
 	const auto iterator = this->openModels.find(modelId);
 	if (iterator != this->openModels.end())
@@ -111,7 +119,6 @@
  * @param openType rationale behind opening this file
  * @returns model id, or no value on error
  */
-#include <QPlainTextDocumentLayout>
 std::optional<ModelId> DocumentManager::openModel(
 	const QString& path,
 	QTextStream& errorStream,
@@ -120,8 +127,7 @@
 	QFile file{path};
 	const QString name = pathToName(QFileInfo{path});
 	file.open(QFile::ReadOnly | QFile::Text);
-	std::unique_ptr<QTextDocument> newModel = std::make_unique<QTextDocument>(nullptr);
-	newModel->setDocumentLayout(new QPlainTextDocumentLayout{newModel.get()});
+	std::unique_ptr<QTextDocument> newModel = newTextDocument();
 	newModel->setPlainText(file.readAll());
 	std::optional<ModelId> result;
 	if (file.error() == QFile::NoError)
@@ -195,7 +201,7 @@
 		QSaveFile file{info->path};
 		file.setDirectWriteFallback(true);
 		if (file.open(QSaveFile::WriteOnly)) {
-			file.write(info->model->toPlainText().toUtf8());
+			file.write(info->model->toPlainText().replace("\n", "\r\n").toUtf8());
 			const bool commitSucceeded = file.commit();
 			if (not commitSucceeded) {
 				errors << QObject::tr("Could not save: %1").arg(file.errorString());
@@ -222,7 +228,7 @@
  * @param model model to look for
  * @return id or no value if not found
  */
-std::optional<ModelId> DocumentManager::findIdForModel(const Model *model) const
+std::optional<ModelId> DocumentManager::findIdForModel(const QTextDocument *model) const
 {
 	std::optional<ModelId> result;
 	for (auto it = this->openModels.begin(); it != this->openModels.end(); ++it)
@@ -319,7 +325,7 @@
 
 void DocumentManager::makePolygonCacheForModel(const ModelId modelId)
 {
-	Model* model = this->getModelById(modelId);
+	QTextDocument* model = this->getModelById(modelId);
 	if (model != nullptr)
 	{
 		const auto modelModified = [this, model]{
@@ -352,7 +358,7 @@
 	return referencedFilePath;
 }
 
-static std::set<QString> referenceNames(const Model* model)
+static std::set<QString> referenceNames(const QTextDocument* model)
 {
 	std::set<QString> result;
 	for (const QString& line : model->toPlainText().split("\n")) {
--- a/src/documentmanager.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/documentmanager.h	Sat Jul 23 01:38:43 2022 +0300
@@ -48,8 +48,8 @@
 	auto begin() const { return this->openModels.begin(); }
 	auto end() const { return this->openModels.end(); }
 	ModelId newModel();
-	Model* findDependencyByName(const ModelId modelId, const QString& name);
-	Model* getModelById(ModelId modelId);
+	QTextDocument* findDependencyByName(const ModelId modelId, const QString& name);
+	QTextDocument* getModelById(ModelId modelId);
 	std::optional<ModelId> openModel(const QString& path, QTextStream& errorStream, const OpenType openType);
 	std::map<QString, QString> loadDependenciesForAllModels(const LibrariesModel &libraries);
 	void closeDocument(const ModelId modelId);
@@ -60,7 +60,7 @@
 			const LibrariesModel &libraries,
 			QTextStream &errorStream);
 	bool saveModel(const ModelId modelId, QTextStream& errors);
-	std::optional<ModelId> findIdForModel(const Model* model) const;
+	std::optional<ModelId> findIdForModel(const QTextDocument* model) const;
 	PolygonCache* getPolygonCacheForModel(ModelId modelId);
 	const ModelInfo* find(ModelId modelId) const;
 	void setModelPayload(ModelId modelId, QObject* object);
@@ -75,7 +75,7 @@
 private:
 	int modelIdCounter = 0;
 	std::map<ModelId, ModelInfo> openModels;
-	void collectReferences(QSet<QString> &referenced, const QString& name, const Model* model);
+	void collectReferences(QSet<QString> &referenced, const QString& name, const QTextDocument* model);
 	void updateDependencies(ModelInfo* model);
 	void prune();
 	void makePolygonCacheForModel(const ModelId modelId);
--- a/src/gl/compiler.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/gl/compiler.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -222,7 +222,7 @@
 }
 
 template<typename Fn>
-void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn)
+void iterateModelPolygons(QTextDocument* model, DocumentManager* context, Fn&& fn)
 {
 	PolygonCache* const cache = findPolygonCacheForModel(model, context);
 	if (cache != nullptr) {
@@ -260,7 +260,7 @@
 /**
  * @brief Computes the minimum bounding box for a model
  */
-BoundingBox gl::boundingBoxForModel(Model* model, DocumentManager* context)
+BoundingBox gl::boundingBoxForModel(QTextDocument* model, DocumentManager* context)
 {
 	BoundingBox result = emptyBoundingBox;
 	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
@@ -277,7 +277,7 @@
  */
 void gl::build(
 	gl::ModelShaders* shaders,
-	Model* model,
+	QTextDocument* model,
 	const ColorTable& colorTable,
 	DocumentManager* context,
 	const gl::RenderPreferences& preferences)
--- a/src/gl/compiler.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/gl/compiler.h	Sat Jul 23 01:38:43 2022 +0300
@@ -72,7 +72,7 @@
 	};
 
 	void build(ModelShaders* shaders,
-		Model* model,
+		QTextDocument* model,
 		const ColorTable& colorTable,
 		DocumentManager* context,
 		const RenderPreferences& preferences);
@@ -114,7 +114,7 @@
 		setShaderUniform(shaders, uniformName, value.x, value.y, value.z, value.w);
 	}
 
-	BoundingBox boundingBoxForModel(Model* model, DocumentManager* context);
+	BoundingBox boundingBoxForModel(QTextDocument* model, DocumentManager* context);
 }
 
 #define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); }
--- a/src/gl/partrenderer.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/gl/partrenderer.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -35,7 +35,7 @@
 static constexpr double MAX_ZOOM = 3.0;
 
 PartRenderer::PartRenderer(
-	Model* model,
+	QTextDocument* model,
 	DocumentManager* documents,
 	const ColorTable& colorTable,
 	QWidget* parent) :
--- a/src/gl/partrenderer.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/gl/partrenderer.h	Sat Jul 23 01:38:43 2022 +0300
@@ -9,7 +9,7 @@
 class PartRenderer final : public QOpenGLWidget
 {
 	Q_OBJECT
-	Model* const model;
+	QTextDocument* const model;
 	DocumentManager* const documents;
 	const ColorTable& colorTable;
 	BoundingBox boundingBox;
@@ -32,7 +32,7 @@
 	bool frozen = false;
 public:
 	PartRenderer(
-		Model* model,
+		QTextDocument* model,
 		DocumentManager* documents,
 		const ColorTable& colorTable,
 		QWidget* parent = nullptr);
--- a/src/ldrawalgorithm.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/ldrawalgorithm.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -1,3 +1,4 @@
+#include <QTextBlock>
 #include "src/ldrawalgorithm.h"
 
 std::pair<Triangle, Triangle> splitTriangles(
@@ -17,31 +18,28 @@
 	return result;
 }
 
-std::vector<ModelAction> ldraw::makeUnofficial(const Model* model)
+std::vector<ModelAction> ldraw::makeUnofficial(const QTextDocument* model)
 {
 	std::vector<ModelAction> actions;
-#if 0
-	if (model->size() >= 4) {
-		if (const Comment* comment = std::get_if<Comment>(&(*model)[3])) {
-			const QString& body = comment->text;
-			if (body.startsWith("!LDRAW_ORG ") and not body.startsWith("!LDRAW_ORG Unofficial_"))
+	constexpr int ldrawOrgLinePosition = 3;
+	const QTextBlock block = model->findBlockByLineNumber(ldrawOrgLinePosition);
+	if (block.isValid()) {
+		const QString body = block.text().simplified();
+		if (body.startsWith("0 !LDRAW_ORG ") and not body.startsWith("0 !LDRAW_ORG Unofficial_")) {
+			// Add Unofficial_ to part type
+			QStringList tokens = body.split(" ");
+			tokens[2] = "Unofficial_" + tokens[2];
+			// Remove the UPDATE tag if it's there
+			if (tokens.size() >= 5 && tokens[3] == "UPDATE")
 			{
-				// Add Unofficial_ to part type
-				QStringList tokens = body.split(" ");
-				tokens[1] = "Unofficial_" + tokens[1];
-				// Remove the UPDATE tag if it's there
-				if (tokens.size() >= 4 && tokens[2] == "UPDATE")
-				{
-					tokens.removeAt(3);
-					tokens.removeAt(2);
-				}
-				actions.push_back(ModifyModel{
-					.position = 3,
-					.newElement = Comment{.text = tokens.join(" ")}
-				});
+				tokens.removeAt(4);
+				tokens.removeAt(3);
 			}
+			actions.push_back(ModifyModel{
+				.position = ldrawOrgLinePosition,
+				.newElement = Comment{.text = tokens.mid(1).join(" ")}
+			});
 		}
 	}
-#endif
 	return actions;
 }
--- a/src/ldrawalgorithm.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/ldrawalgorithm.h	Sat Jul 23 01:38:43 2022 +0300
@@ -15,7 +15,7 @@
 		const Quadrilateral& q,
 		ldraw::Diagonal diagonal);
 
-	std::vector<ModelAction> makeUnofficial(const Model *model);
+	std::vector<ModelAction> makeUnofficial(const QTextDocument *model);
 
 	constexpr float circleAngle(unsigned int divisions, unsigned int i)
 	{
--- a/src/main.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/main.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -53,7 +53,7 @@
 	std::unique_ptr<AxesLayer> axesLayer;
 	std::unique_ptr<GridLayer> gridLayer;
 	std::unique_ptr<QTextCursor> textcursor;
-	Model* model;
+	QTextDocument* model;
 };
 
 class Signal final : public QObject
@@ -86,6 +86,7 @@
 	qRegisterMetaTypeStreamOperators<Libraries>("Libraries");
 	qRegisterMetaTypeStreamOperators<gl::RenderStyle>();
 	qRegisterMetaTypeStreamOperators<QMdiArea::ViewMode>();
+	qRegisterMetaTypeStreamOperators<Qt::ToolButtonStyle>();
 #endif
 }
 
@@ -168,16 +169,6 @@
 	}
 }
 
-static Model* currentModelBody(Ui_MainWindow* ui, DocumentManager* documents)
-{
-	if (auto* const activeSubWindow = currentModelSubWindow(ui)) {
-		return documents->getModelById(activeSubWindow->modelId);
-	}
-	else {
-		return nullptr;
-	}
-}
-
 static std::optional<ModelId> findCurrentModelId(Ui_MainWindow* ui)
 {
 	ModelSubWindow* activeSubWindow = qobject_cast<ModelSubWindow*>(ui->mdiArea->activeSubWindow());
@@ -331,15 +322,6 @@
 	}
 }
 
-static QFont monospace()
-{
-	QFont font{"Monospace"};
-	font.setStyleHint(QFont::TypeWriter);
-	font.setPointSize(10);
-	font.setFixedPitch(true);
-	return font;
-}
-
 constexpr bool sortModelIndexesByRow(const QModelIndex& a, const QModelIndex& b)
 {
 	return a.row() < b.row();
@@ -408,17 +390,6 @@
 	return subWindow;
 }
 
-static QSet<ElementId> resolveIdsFromSelection(const ModelData* data)
-{
-//	const auto selection = data->itemSelectionModel->selection();
-	QSet<ElementId> selectedIndexes;
-/*	for (const QModelIndex& qindex : selection.indexes()) {
-		const std::size_t row = unsigned_cast(qindex.row());
-		selectedIndexes.insert(data->model->idAt(row));
-	}
-*/	return selectedIndexes;
-}
-
 int main(int argc, char *argv[])
 {
 	doQtRegistrations();
@@ -468,21 +439,30 @@
 		}
 	};
 	const auto executeAction = [&](
-		Model* model, const ModelAction& action
+		QTextDocument* model, const ModelAction& action
 	) {
-		/*
 		std::visit(overloaded{
 			[model](const AppendToModel& action){
-				model->append(action.newElement);
+				QTextCursor cursor{model};
+				cursor.movePosition(QTextCursor::End);
+				const QString newText = modelElementToString(action.newElement);
+				// Make sure we have an empty line
+				if (not model->lastBlock().text().isEmpty()) {
+					cursor.insertBlock();
+				}
+				cursor.insertText(newText);
 			},
-			[model](const DeleteFromModel& action){
-					model->remove(action.position);
-			},
+			[](const DeleteFromModel&){},
 			[model](const ModifyModel& action){
-				model->assignAt(action.position, action.newElement);
+				QTextBlock block = model->findBlockByLineNumber((int) action.position);
+				if (block.isValid()) {
+					QTextCursor cursor{block};
+					cursor.select(QTextCursor::LineUnderCursor);
+					cursor.insertText(modelElementToString(action.newElement));
+				}
+				//model->assignAt(action.position, action.newElement);
 			},
 		}, action);
-		*/
 		
 	};
 	const auto restoreSettings = [&]{
@@ -494,6 +474,7 @@
 		updateRenderPreferences(&ui, &renderPreferences, &documents);
 		ui.mdiArea->setViewMode(setting<Setting::ViewMode>());
 		ui.retranslateUi(&mainWindow);
+		mainWindow.setToolButtonStyle(setting<Setting::ToolButtonStyle>());
 		settingsChanged.emit();
 	};
 	const auto addRecentlyOpenedFile = [&](const QString& path){
@@ -508,7 +489,7 @@
 		updateRecentlyOpenedDocumentsMenu();
 	};
 	const auto openModelForEditing = [&](const ModelId modelId){
-		Model* model = documents.getModelById(modelId);
+		QTextDocument* model = documents.getModelById(modelId);
 		if (model != nullptr) {
 			ModelData* data = new ModelData(&documents);
 			data->tools = std::make_unique<EditTools>();
@@ -745,7 +726,7 @@
 		&QAction::triggered,
 		[&]{
 			if (ModelData* data = currentModelData(&ui, &documents)) {
-				Model* const model = data->model;
+				QTextDocument* const model = data->model;
 				for (const ModelAction& action : ldraw::makeUnofficial(model)) {
 					executeAction(model, action);
 				}
--- a/src/mainwindow.ui	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/mainwindow.ui	Sat Jul 23 01:38:43 2022 +0300
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>729</width>
+    <width>959</width>
     <height>600</height>
    </rect>
   </property>
@@ -44,8 +44,8 @@
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>729</width>
-     <height>35</height>
+     <width>959</width>
+     <height>29</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -88,13 +88,6 @@
     <property name="title">
      <string>Edit</string>
     </property>
-    <addaction name="actionCut"/>
-    <addaction name="actionCopy"/>
-    <addaction name="actionPaste"/>
-    <addaction name="actionDelete"/>
-    <addaction name="separator"/>
-    <addaction name="actionSelectAll"/>
-    <addaction name="separator"/>
     <addaction name="actionInvert"/>
     <addaction name="separator"/>
     <addaction name="actionGridFine"/>
@@ -120,9 +113,6 @@
    <property name="windowTitle">
     <string>toolBar</string>
    </property>
-   <property name="toolButtonStyle">
-    <enum>Qt::ToolButtonTextUnderIcon</enum>
-   </property>
    <attribute name="toolBarArea">
     <enum>TopToolBarArea</enum>
    </attribute>
@@ -138,9 +128,6 @@
    <property name="windowTitle">
     <string>toolBar</string>
    </property>
-   <property name="toolButtonStyle">
-    <enum>Qt::ToolButtonTextUnderIcon</enum>
-   </property>
    <attribute name="toolBarArea">
     <enum>TopToolBarArea</enum>
    </attribute>
@@ -157,9 +144,6 @@
    <property name="windowTitle">
     <string>toolBar_2</string>
    </property>
-   <property name="toolButtonStyle">
-    <enum>Qt::ToolButtonTextUnderIcon</enum>
-   </property>
    <attribute name="toolBarArea">
     <enum>TopToolBarArea</enum>
    </attribute>
@@ -168,17 +152,11 @@
    </attribute>
    <addaction name="actionInvert"/>
    <addaction name="actionDelete"/>
-   <addaction name="actionGridFine"/>
-   <addaction name="actionGridMedium"/>
-   <addaction name="actionGridCoarse"/>
   </widget>
   <widget class="QToolBar" name="editingModesToolBar">
    <property name="windowTitle">
     <string>toolBar_2</string>
    </property>
-   <property name="toolButtonStyle">
-    <enum>Qt::ToolButtonTextUnderIcon</enum>
-   </property>
    <attribute name="toolBarArea">
     <enum>LeftToolBarArea</enum>
    </attribute>
@@ -272,6 +250,21 @@
     </layout>
    </widget>
   </widget>
+  <widget class="QToolBar" name="gridToolBar">
+   <property name="windowTitle">
+    <string>toolBar_2</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+   <addaction name="actionGridFine"/>
+   <addaction name="actionGridMedium"/>
+   <addaction name="actionGridCoarse"/>
+   <addaction name="actionAdjustGridToView"/>
+  </widget>
   <action name="actionQuit">
    <property name="icon">
     <iconset resource="../resources.qrc">
--- a/src/model.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/model.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -175,16 +175,11 @@
 	}
 }
 
-void save(const Model &model, QTextStream* stream)
-{
-	*stream << model.toPlainText();
-}
-
 /**
  * @brief Sets the path to the model
  * @param path New path to use
  */
-void updateHeaderNameField(Model& model, const QString &name)
+void updateHeaderNameField(QTextDocument& model, const QString &name)
 {
 #if 0
 	// Update the "Name: 1234.dat" comment
--- a/src/model.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/model.h	Sat Jul 23 01:38:43 2022 +0300
@@ -21,9 +21,7 @@
 #include <memory>
 #include "src/basics.h"
 #include "src/colors.h"
-
 #include <QTextDocument>
-using Model = QTextDocument;
 
 struct SubfileReference
 {
@@ -206,3 +204,5 @@
 	AppendToModel,
 	DeleteFromModel,
 	ModifyModel>;
+
+QString modelElementToString(const ModelElement &element);
--- a/src/parser.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/parser.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -22,9 +22,9 @@
 #include "src/model.h"
 #include "src/parser.h"
 
-#define NUMBER_REGEX R"([+-]?(?:(?:\d+\.?\d*)|(?:\.\d+)))"
+#define NUMBER_REGEX R"(([+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))))"
 #define SPACE_REGEX R"(\s+)"
-#define VEC3_REGEX "(" NUMBER_REGEX SPACE_REGEX NUMBER_REGEX SPACE_REGEX NUMBER_REGEX ")"
+#define VEC3_REGEX NUMBER_REGEX SPACE_REGEX NUMBER_REGEX SPACE_REGEX NUMBER_REGEX
 #define TWO_VECTORS VEC3_REGEX SPACE_REGEX VEC3_REGEX
 #define THREE_VECTORS TWO_VECTORS SPACE_REGEX VEC3_REGEX
 #define FOUR_VECTORS THREE_VECTORS SPACE_REGEX VEC3_REGEX
@@ -64,6 +64,7 @@
 {
 	const int index = attribIndex<LineType<T, Attribs...>, Attrib>;
 	const TextRange& range = parsed.positions[index];
+	const QString content = parsed.content;
 	return parsed.content.mid(range.start, range.length);
 }
 
@@ -103,6 +104,7 @@
 				.length = match.capturedLength(i + 1),
 			};
 		}
+		parsed->content = match.captured(0);
 		return parsed;
 	};
 	if (auto line1Match = tryRe(exprs().subfileRe)) {
--- a/src/polygoncache.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/polygoncache.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -4,7 +4,7 @@
 #include "src/polygoncache.h"
 #include "src/parser.h"
 
-Model* resolve(const QString& name, const ModelId callingModelId, DocumentManager* documents)
+QTextDocument* resolve(const QString& name, const ModelId callingModelId, DocumentManager* documents)
 {
 	return documents->findDependencyByName(callingModelId, name);
 }
@@ -19,7 +19,7 @@
 	return element;
 }
 
-PolygonCache* findPolygonCacheForModel(Model* model, DocumentManager* context)
+PolygonCache* findPolygonCacheForModel(QTextDocument* model, DocumentManager* context)
 {
 	std::optional<ModelId> modelId = context->findIdForModel(model);
 	if (modelId.has_value()) {
@@ -74,7 +74,7 @@
 	}
 }
 
-static Model* findDependency(const SubfileReference& ref, GetPolygonsContext* context)
+static QTextDocument* findDependency(const SubfileReference& ref, GetPolygonsContext* context)
 {
 	return context->documents->findDependencyByName(context->modelId, ref.name);
 }
@@ -118,7 +118,7 @@
 			add({line5.value, line5.value.color});
 		},
 		[&add, context, &reserve](const LineType1& line1) {
-			Model* const dependency = findDependency(line1.value, context);
+			QTextDocument* const dependency = findDependency(line1.value, context);
 			if (PolygonCache* cache = (dependency != nullptr)
 				? findPolygonCacheForModel(dependency, context->documents)
 				: nullptr
@@ -144,7 +144,7 @@
 }
 
 static std::vector<WithId<PolygonElement>> inlinePolygons(
-	const Model* model,
+	const QTextDocument* model,
 	GetPolygonsContext* context)
 {
 	Winding winding = NoWinding;
@@ -169,7 +169,7 @@
 	return result;
 }
 
-void recacheIfNeeded(PolygonCache *cache, Model *model, DocumentManager *documents)
+void recacheIfNeeded(PolygonCache *cache, QTextDocument *model, DocumentManager *documents)
 {
 	if (cache->needRecache)
 	{
--- a/src/polygoncache.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/polygoncache.h	Sat Jul 23 01:38:43 2022 +0300
@@ -19,6 +19,6 @@
 
 void recacheIfNeeded(
 	PolygonCache* cache,
-	Model* model,
+	QTextDocument* model,
 	class DocumentManager* documents);
 PolygonCache* findPolygonCacheForModel(QTextDocument* model, DocumentManager* context);
--- a/src/settings.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/settings.h	Sat Jul 23 01:38:43 2022 +0300
@@ -25,6 +25,7 @@
 // Setting definitions
 
 Q_DECLARE_METATYPE(QMdiArea::ViewMode)
+Q_DECLARE_METATYPE(Qt::ToolButtonStyle)
 
 // Rendering options
 SETTING(BackgroundColor, (QColor{48, 48, 48}))
@@ -41,6 +42,7 @@
 SETTING(RecentFiles, QStringList{})
 SETTING(ViewMode, QMdiArea::TabbedView)
 SETTING(LogOpenGLDebugMessages, false)
+SETTING(ToolButtonStyle, Qt::ToolButtonFollowStyle)
 
 // File management options
 SETTING(Libraries, Libraries{})
--- a/src/settingseditor/settingseditor.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/settingseditor/settingseditor.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -22,6 +22,11 @@
 	this->ui.keyboardShortcutsView->setModel(new KeyboardShortcutsEditor{parent, this});
 	this->ui.viewModeButtonGroup->setId(this->ui.viewModeTabs, int{QMdiArea::TabbedView});
 	this->ui.viewModeButtonGroup->setId(this->ui.viewModeSubWindows, int{QMdiArea::SubWindowView});
+	this->ui.toolButtonStyle->addItem(tr("Icons only"), Qt::ToolButtonIconOnly);
+	this->ui.toolButtonStyle->addItem(tr("Text only"), Qt::ToolButtonTextOnly);
+	this->ui.toolButtonStyle->addItem(tr("Text beside icon"), Qt::ToolButtonTextBesideIcon);
+	this->ui.toolButtonStyle->addItem(tr("Text under icon"), Qt::ToolButtonTextUnderIcon);
+	this->ui.toolButtonStyle->addItem(tr("Style default"), Qt::ToolButtonFollowStyle);
 	this->loadSettings();
 	this->setWindowTitle(tr("Settings"));
 	this->setWindowIcon(QIcon{":/icons/settings-outline.png"});
@@ -55,6 +60,11 @@
 	if (viewMode != -1) {
 		setSetting<Setting::ViewMode>(static_cast<QMdiArea::ViewMode>(viewMode));
 	}
+	const QVariant toolButtonStyle = this->ui.toolButtonStyle->currentData();
+	if (toolButtonStyle.isValid()) {
+		setSetting<Setting::ToolButtonStyle>(
+			static_cast<Qt::ToolButtonStyle>(toolButtonStyle.toInt()));
+	}
 	this->librariesEditor.saveSettings();
 	Q_EMIT this->settingsChanged();
 }
@@ -72,4 +82,9 @@
 	if (viewModeButton != nullptr) {
 		viewModeButton->setChecked(true);
 	}
+	int toolButtonStyleIndex = this->ui.toolButtonStyle->findData(
+		setting<Setting::ToolButtonStyle>());
+	if (toolButtonStyleIndex != -1) {
+		this->ui.toolButtonStyle->setCurrentIndex(toolButtonStyleIndex);
+	}
 }
--- a/src/settingseditor/settingseditor.ui	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/settingseditor/settingseditor.ui	Sat Jul 23 01:38:43 2022 +0300
@@ -30,8 +30,8 @@
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>694</width>
-        <height>563</height>
+        <width>690</width>
+        <height>558</height>
        </rect>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout">
@@ -90,6 +90,16 @@
                   </item>
                  </layout>
                 </item>
+                <item row="1" column="0">
+                 <widget class="QLabel" name="label">
+                  <property name="text">
+                   <string>Tool button style:</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="1">
+                 <widget class="QComboBox" name="toolButtonStyle"/>
+                </item>
                </layout>
               </widget>
              </item>
--- a/src/vertexmap.cpp	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/vertexmap.cpp	Sat Jul 23 01:38:43 2022 +0300
@@ -10,7 +10,7 @@
 	});
 }
 
-VertexMap::VertexMap(const Model *model) :
+VertexMap::VertexMap(const QTextDocument *model) :
 	model{model}
 {
 	this->build();
--- a/src/vertexmap.h	Sat Jul 23 01:38:06 2022 +0300
+++ b/src/vertexmap.h	Sat Jul 23 01:38:43 2022 +0300
@@ -19,13 +19,13 @@
 		glm::mat4 transform;
 	};
 	using ApplyFunction = std::function<void(const glm::vec3&, const VertexInfo&)>;
-	VertexMap(const Model *model);
+	VertexMap(const QTextDocument *model);
 	Q_SLOT void build();
 	void apply(ApplyFunction fn) const;
 Q_SIGNALS:
 	Q_SIGNAL void verticesChanged();
 private:
-	const Model* const model;
+	const QTextDocument* const model;
 	QSet<hash_t> vertexHashes;
 	std::vector<glm::vec3> vertices;
 	std::map<hash_t, VertexInfo> map;

mercurial