changed Model into an MVC list model and replaced the objects list with a view into the model

Tue, 13 Feb 2018 14:19:07 +0200

author
Santeri Piippo
date
Tue, 13 Feb 2018 14:19:07 +0200
changeset 1240
cebb7ef54f41
parent 1239
f1cf9d2d463a
child 1241
0b5f84d2a68a

changed Model into an MVC list model and replaced the objects list with a view into the model

src/canvas.cpp file | annotate | diff | comparison | revisions
src/editmodes/magicWandMode.cpp file | annotate | diff | comparison | revisions
src/lddocument.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h 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/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/basictoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/filetoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/movetoolset.cpp file | annotate | diff | comparison | revisions
--- a/src/canvas.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/canvas.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -259,7 +259,6 @@
 		LDSubfileReference* reference = currentDocument()->emplaceAt<LDSubfileReference>(m_window->suggestInsertPoint());
 		reference->setFileInfo (m_documents->getDocumentByName(primitiveName));
 		currentDocument()->addToSelection(reference);
-		m_window->buildObjectList();
 		update();
 		event->acceptProposedAction();
 	}
--- a/src/editmodes/magicWandMode.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/editmodes/magicWandMode.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -79,10 +79,7 @@
 	if (obj == nullptr)
 	{
 		if (type == Set)
-		{
 			currentDocument()->clearSelection();
-			m_window->buildObjectList();
-		}
 
 		return;
 	}
@@ -194,9 +191,6 @@
 	case InternalRecursion:
 		break;
 	}
-
-	if (type != InternalRecursion)
-		m_window->buildObjectList();
 }
 
 bool MagicWandMode::mouseReleased (MouseEventData const& data)
--- a/src/lddocument.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/lddocument.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -223,7 +223,6 @@
 		{
 			QString newname = shortenName (path);
 			nameComment->setText (format ("Name: %1", newname));
-			m_window->buildObjectList();
 		}
 	}
 
@@ -285,9 +284,6 @@
 	}
 
 	m_needsRecache = true;
-
-	if (this == m_window->currentDocument())
-		m_window->buildObjectList();
 }
 
 // =============================================================================
--- a/src/mainwindow.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/mainwindow.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -60,8 +60,7 @@
 	m_externalPrograms (nullptr),
     m_settings (makeSettings (this)),
 	m_documents (new DocumentManager (this)),
-	m_currentDocument (nullptr),
-	m_isSelectionLocked (false)
+	m_currentDocument (nullptr)
 {
 	m_messageLog = new MessageManager {this};
 	ui.setupUi (this);
@@ -72,9 +71,6 @@
 	createBlankDocument();
 	ui.rendererStack->setCurrentWidget(getRendererForDocument(m_currentDocument));
 
-	connect (ui.objectList, SIGNAL (itemSelectionChanged()), this, SLOT (selectionChanged()));
-	connect (ui.objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this,
-			 SLOT (objectListDoubleClicked (QListWidgetItem*)));
 	connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (tabSelected()));
 	connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int)));
 	connect(m_documents, SIGNAL(documentClosed(LDDocument*)), this, SLOT(documentClosed(LDDocument*)));
@@ -335,110 +331,6 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void MainWindow::buildObjectList()
-{
-	if (not m_currentDocument)
-		return;
-
-	// Lock the selection while we do this so that refreshing the object list
-	// doesn't trigger selection updating so that the selection doesn't get lost
-	// while this is done.
-	m_isSelectionLocked = true;
-	m_objectsInList.clear();
-
-	for (int i = 0; i < ui.objectList->count(); ++i)
-		delete ui.objectList->item (i);
-
-	ui.objectList->clear();
-
-	for (LDObject* obj : m_currentDocument->objects())
-	{
-		QListWidgetItem* item = new QListWidgetItem {obj->objectListText()};
-		item->setIcon (getIcon (obj->typeName()));
-
-		if (obj->isInverted())
-			item->setText("↺ " + item->text());
-
-		// Use italic font if hidden
-		if (obj->isHidden())
-		{
-			QFont font = item->font();
-			font.setItalic (true);
-			item->setFont (font);
-		}
-
-		// Color gibberish orange on red so it stands out.
-		if (obj->type() == LDObjectType::Error)
-		{
-			item->setBackground (QColor ("#AA0000"));
-			item->setForeground (QColor ("#FFAA00"));
-		}
-		else if (m_config.colorizeObjectsList()
-			and obj->isColored()
-			and obj->color().isValid()
-			and obj->color() != MainColor
-			and obj->color() != EdgeColor)
-		{
-			// If the object isn't in the main or edge color, draw this list entry in that color.
-			item->setForeground (obj->color().faceColor());
-		}
-
-		m_objectsInList.insert (obj, item);
-		ui.objectList->insertItem (ui.objectList->count(), item);
-	}
-
-	m_isSelectionLocked = false;
-	updateSelection();
-	scrollToSelection();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-// Scrolls the object list so that it points to the first selected object.
-//
-void MainWindow::scrollToSelection()
-{
-	if (selectedObjects().isEmpty())
-		return;
-
-	// TODO: Need a way to properly figure out the first selected object!
-	LDObject* obj = *selectedObjects().begin();
-	ui.objectList->scrollToItem (m_objectsInList[obj]);
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-void MainWindow::selectionChanged()
-{
-	if (m_isSelectionLocked == true or m_currentDocument == nullptr)
-		return;
-
-	QSet<LDObject*> priorSelection = selectedObjects();
-
-	// Get the objects from the object list selection
-	m_currentDocument->clearSelection();
-	const QList<QListWidgetItem*> items = ui.objectList->selectedItems();
-
-	for (LDObject* obj : m_currentDocument->objects())
-	{
-		for (QListWidgetItem* item : items)
-		{
-			if (item == m_objectsInList[obj])
-			{
-				m_currentDocument->addToSelection(obj);
-				break;
-			}
-		}
-	}
-
-	// The select() method calls may have selected additional items (i.e. invertnexts)
-	// Update it all now.
-	updateSelection();
-	renderer()->update();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
 void MainWindow::recentFileClicked()
 {
 	QAction* qAct = static_cast<QAction*> (sender());
@@ -495,7 +387,6 @@
 //
 void MainWindow::doFullRefresh()
 {
-	buildObjectList();
 	renderer()->update();
 }
 
@@ -505,7 +396,6 @@
 //
 void MainWindow::refresh()
 {
-	buildObjectList();
 	renderer()->update();
 }
 
@@ -513,46 +403,7 @@
 //
 void MainWindow::updateSelection()
 {
-	m_isSelectionLocked = true;
-	QItemSelection itemselect;
-	int top = -1;
-	int bottom = -1;
-
-	for (LDObject* obj : selectedObjects())
-	{
-		QListWidgetItem** itempointer = m_objectsInList.find (obj);
-
-		if (not itempointer)
-			continue;
-
-		int row = ui.objectList->row (*itempointer);
-
-		if (top == -1)
-		{
-			top = bottom = row;
-		}
-		else
-		{
-			if (row != bottom + 1)
-			{
-				itemselect.select (ui.objectList->model()->index (top, 0),
-					ui.objectList->model()->index (bottom, 0));
-				top = -1;
-			}
-
-			bottom = row;
-		}
-	}
-
-	if (top != -1)
-	{
-		itemselect.select (ui.objectList->model()->index (top, 0),
-			ui.objectList->model()->index (bottom, 0));
-	}
-
-	// Select multiple objects at once for performance reasons
-	ui.objectList->selectionModel()->select (itemselect, QItemSelectionModel::ClearAndSelect);
-	m_isSelectionLocked = false;
+#warning stub method
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -704,14 +555,6 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void MainWindow::objectListDoubleClicked (QListWidgetItem* listitem)
-{
-	LDObject* object = m_objectsInList.reverseLookup(listitem);
-	// TODO: ...
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
 bool MainWindow::save (LDDocument* doc, bool saveAs)
 {
 	if (doc->isFrozen())
@@ -873,15 +716,6 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-// Updates the object list. Right now this just rebuilds it.
-//
-void MainWindow::refreshObjectList()
-{
-	buildObjectList();
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
 // Updates various actions, undo/redo are set enabled/disabled where appropriate, togglable actions are updated based
 // on configuration, etc.
 //
@@ -1132,9 +966,9 @@
 	{
 		// A ton of stuff needs to be updated
 		updateDocumentListItem (document);
-		buildObjectList();
 		updateTitle();
 		print ("Changed document to %1", document->getDisplayName());
+		ui.objectList->setModel(document);
 	}
 }
 
--- a/src/mainwindow.h	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/mainwindow.h	Tue Feb 13 14:19:07 2018 +0200
@@ -67,7 +67,6 @@
 
 	void addMessage (QString msg);
 	void applyToActions (std::function<void(QAction*)> function);
-	void buildObjectList();
 	void changeDocument (LDDocument* f);
 	void closeInitialDocument();
 	Configuration* config();
@@ -96,12 +95,10 @@
 	PrimitiveManager* primitives();
 	Canvas* renderer();
 	void refresh();
-	void refreshObjectList();
 	bool ringToolHiRes() const;
 	int ringToolSegments() const;
 	bool save (LDDocument* doc, bool saveAs);
 	void saveShortcuts();
-	void scrollToSelection();
 	const QSet<LDObject*>& selectedObjects();
 	void setQuickColors (const QVector<ColorToolbarItem> &colors);
 	void spawnContextMenu (const QPoint& position);
@@ -153,7 +150,6 @@
 	PrimitiveManager* m_primitives;
 	Grid* m_grid;
 	MathFunctions* m_mathFunctions;
-	QVector<LDObject*> m_sel;
 	QVector<ColorToolbarItem>	m_quickColors;
 	QList<QToolButton*>	m_colorButtons;
 	QList<QAction*> m_recentFiles;
@@ -167,13 +163,10 @@
 	DocumentManager* m_documents;
 	LDDocument* m_currentDocument;
 	DoubleMap<LDObject*, QListWidgetItem*> m_objectsInList;
-	bool m_isSelectionLocked;
 	QMap<QAction*, QKeySequence> m_defaultShortcuts;
 
 private slots:
 	void finishInitialization();
-	void selectionChanged();
 	void recentFileClicked();
 	void quickColorClicked();
-	void objectListDoubleClicked (QListWidgetItem* listitem);
 };
--- a/src/mainwindow.ui	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/mainwindow.ui	Tue Feb 13 14:19:07 2018 +0200
@@ -47,8 +47,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>467</width>
-           <height>420</height>
+           <width>465</width>
+           <height>399</height>
           </rect>
          </property>
          <attribute name="label">
@@ -56,7 +56,7 @@
          </attribute>
          <layout class="QVBoxLayout" name="verticalLayout_2">
           <item>
-           <widget class="QListWidget" name="objectList">
+           <widget class="QListView" name="objectList">
             <property name="sizePolicy">
              <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
               <horstretch>0</horstretch>
@@ -75,8 +75,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>467</width>
-           <height>420</height>
+           <width>465</width>
+           <height>399</height>
           </rect>
          </property>
          <attribute name="label">
@@ -157,8 +157,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>467</width>
-           <height>420</height>
+           <width>465</width>
+           <height>399</height>
           </rect>
          </property>
          <attribute name="label">
@@ -194,7 +194,7 @@
      <x>0</x>
      <y>0</y>
      <width>1010</width>
-     <height>26</height>
+     <height>31</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -1727,6 +1727,7 @@
  </widget>
  <resources>
   <include location="../ldforge.qrc"/>
+  <include location="../ldforge.qrc"/>
  </resources>
  <connections/>
 </ui>
--- a/src/model.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/model.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -27,7 +27,7 @@
 #include "linetypes/triangle.h"
 
 Model::Model(DocumentManager* manager) :
-    QObject {manager},
+	QAbstractListModel {manager},
     _manager {manager} {}
 
 Model::~Model()
@@ -525,6 +525,72 @@
 		return nullptr;
 }
 
+int Model::rowCount(const QModelIndex&) const
+{
+	return this->objects().size();
+}
+
+QVariant Model::data(const QModelIndex& index, int role) const
+{
+	LDObject* object = this->objects()[index.row()];
+
+	switch (role)
+	{
+	case Qt::DisplayRole:
+		{
+			QString result = object->objectListText();
+
+			if (object->isInverted())
+				result.prepend("↺ ");
+
+			return result;
+		}
+
+	case Qt::DecorationRole:
+		return MainWindow::getIcon(object->typeName());
+
+	case Qt::BackgroundColorRole:
+		if (object->type() == LDObjectType::Error)
+			return QColor {"#AA0000"};
+		else
+			return {};
+
+	case Qt::ForegroundRole:
+		if (object->type() == LDObjectType::Error)
+		{
+			return QColor {"#FFAA00"};
+		}
+		else if (
+			object->isColored()
+			and object->color().isValid()
+			and object->color() != MainColor
+			and object->color() != EdgeColor
+		) {
+			// If the object isn't in the main or edge color, draw this list entry in that color.
+			return object->color().faceColor();
+		}
+		else
+		{
+			return {};
+		}
+
+	case Qt::FontRole:
+		if (object->isHidden())
+		{
+			QFont font;
+			font.setItalic(true);
+			return font;
+		}
+		else
+		{
+			return {};
+		}
+
+	default:
+		return {};
+	}
+}
+
 int countof(Model& model)
 {
 	return model.size();
--- a/src/model.h	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/model.h	Tue Feb 13 14:19:07 2018 +0200
@@ -17,13 +17,14 @@
  */
 
 #pragma once
+#include <QAbstractListModel>
 #include "main.h"
 #include "linetypes/modelobject.h"
 
 /*
  * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership.
  */
-class Model : public QObject
+class Model : public QAbstractListModel
 {
 	Q_OBJECT
 
@@ -58,6 +59,9 @@
 	LDObject* addFromString(QString line);
 	LDObject* replaceWithFromString(LDObject* object, QString line);
 
+	int rowCount(const QModelIndex& parent) const override;
+	QVariant data(const QModelIndex& index, int role) const override;
+
 signals:
 	void objectAdded(LDObject* object);
 	void aboutToRemoveObject(LDObject* object);
--- a/src/toolsets/algorithmtoolset.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/toolsets/algorithmtoolset.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -192,7 +192,6 @@
 	}
 
 	print (tr ("Rounded %1 values"), num);
-	m_window->refreshObjectList();
 }
 
 void AlgorithmToolset::replaceCoordinates()
@@ -371,8 +370,6 @@
 	// an empty line
 	if (obj and obj->next() and obj->next()->isScemantic())
 		currentDocument()->emplaceAt<LDEmpty>(idx);
-
-	m_window->buildObjectList();
 }
 
 void AlgorithmToolset::splitLines()
@@ -419,7 +416,6 @@
 		currentDocument()->replace(obj, segments);
 	}
 
-	m_window->buildObjectList();
 	m_window->refresh();
 }
 
--- a/src/toolsets/basictoolset.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/toolsets/basictoolset.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -83,7 +83,6 @@
 
 	print(tr("%1 objects pasted"), count);
 	m_window->refresh();
-	m_window->scrollToSelection();
 }
 
 void BasicToolset::remove()
@@ -190,7 +189,6 @@
 	}
 
 	m_window->refresh();
-	m_window->scrollToSelection();
 }
 
 void BasicToolset::setColor()
@@ -299,4 +297,4 @@
 void BasicToolset::modeLinePath()
 {
 	m_window->renderer()->setEditMode (EditModeType::LinePath);
-}
\ No newline at end of file
+}
--- a/src/toolsets/filetoolset.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/toolsets/filetoolset.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -129,7 +129,6 @@
 			}
 
 			m_window->refresh();
-			m_window->scrollToSelection();
 		}
 		else
 		{
--- a/src/toolsets/movetoolset.cpp	Mon Jan 15 08:20:54 2018 +0200
+++ b/src/toolsets/movetoolset.cpp	Tue Feb 13 14:19:07 2018 +0200
@@ -62,8 +62,6 @@
 		objsToCompile << model->getObject(target);
 		obj->swap(model->getObject(target));
 	}
-
-	m_window->buildObjectList();
 }
 
 void MoveToolset::moveUp()

mercurial