Tue, 13 Feb 2018 14:19:07 +0200
changed Model into an MVC list model and replaced the objects list with a view into the model
--- 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 +}