Wed, 14 Mar 2018 12:08:03 +0200
added an MVC interface to the primitives tree
CMakeLists.txt | file | annotate | diff | comparison | revisions | |
data/primitive-categories.cfg | file | annotate | diff | comparison | revisions | |
src/canvas.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/primitives.cpp | file | annotate | diff | comparison | revisions | |
src/primitives.h | file | annotate | diff | comparison | revisions |
--- a/CMakeLists.txt Sun Mar 11 23:42:03 2018 +0200 +++ b/CMakeLists.txt Wed Mar 14 12:08:03 2018 +0200 @@ -185,6 +185,7 @@ set (LDFORGE_OTHER_FILES src/configurationoptions.txt + data/primitive-categories.cfg ) set (LDFORGE_RESOURCES ldforge.qrc)
--- a/data/primitive-categories.cfg Sun Mar 11 23:42:03 2018 +0200 +++ b/data/primitive-categories.cfg Wed Mar 14 12:08:03 2018 +0200 @@ -15,6 +15,9 @@ # # All lines starting with # are comments and are ignored. +Moved +t:~Moved to.* + Rings f:[0-9]+\-[0-9]+ring[0-9]\.dat f:[0-9]+\-[0-9]+rin[0-9]+\.dat @@ -100,8 +103,37 @@ Spheres (48) f:48\\[0-9]+\-[0-9]+sphe\.dat -Other (48) -f:48\\.*\.dat +Rings (8) +f:8\\[0-9]+\-[0-9]+ring[0-9]\.dat + +Cones (8) +f:8\\[0-9]+\-[0-9]+cone[0-9]\.dat +f:8\\[0-9]+\-[0-9]+con[0-9]+\.dat + +Circles (8) +f:8\\[0-9]+\-[0-9]+edge?\.dat + +Cylinders (8) +f:8\\[0-9]+\-[0-9]+cyli[0-9]*\.dat +f:8\\[0-9]+\-[0-9]+cyl\.dat + +Discs (8) +f:8\\[0-9]+\-[0-9]+disc\.dat + +Disc Negatives (8) +f:8\\[0-9]+\-[0-9]+ndis\.dat + +Open/Closed Cylinders (8) +f:8\\[0-9]+\-[0-9]+cyl(o|c|c2)\.dat + +Sloped Cylinders (8) +f:8\\[0-9]+\-[0-9]+cyl(s|2|se)\.dat + +Chords (8) +f:8\\[0-9]+\-[0-9]+chrd?\.dat + +Spheres (8) +f:8\\[0-9]+\-[0-9]+sphe\.dat Rectangles f:rect.*\.dat @@ -114,6 +146,7 @@ Studs (Fast-Draw) f:stu2.*\.dat +f:8\\stud.*\.dat Stud Groups f:stug.*\.dat @@ -138,4 +171,10 @@ t:Technic .* Ball Joint-8 -f:joint-8-.*\.dat \ No newline at end of file +f:joint8.*\.dat + +Other (48) +f:48\\.*\.dat + +Other (8) +f:8\\.*\.dat
--- a/src/canvas.cpp Sun Mar 11 23:42:03 2018 +0200 +++ b/src/canvas.cpp Wed Mar 14 12:08:03 2018 +0200 @@ -242,6 +242,7 @@ void Canvas::dropEvent(QDropEvent* event) { + /* if (m_window and event->source() == m_window->getPrimitivesTree()) { PrimitiveTreeItem* item = static_cast<PrimitiveTreeItem*> (m_window->getPrimitivesTree()->currentItem()); @@ -256,6 +257,7 @@ update(); event->acceptProposedAction(); } + */ } void Canvas::keyReleaseEvent(QKeyEvent* event) @@ -372,6 +374,8 @@ void Canvas::dragEnterEvent(QDragEnterEvent* event) { + /* if (m_window and event->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem()) event->acceptProposedAction(); + */ }
--- a/src/mainwindow.cpp Sun Mar 11 23:42:03 2018 +0200 +++ b/src/mainwindow.cpp Wed Mar 14 12:08:03 2018 +0200 @@ -69,6 +69,7 @@ m_tabs = new QTabBar; m_tabs->setTabsClosable (true); ui.verticalLayout->insertWidget (0, m_tabs); + ui.primitives->setModel(m_primitives); createBlankDocument(); ui.rendererStack->setCurrentWidget(getRendererForDocument(m_currentDocument)); @@ -76,11 +77,6 @@ connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int))); connect(m_documents, SIGNAL(documentClosed(LDDocument*)), this, SLOT(documentClosed(LDDocument*))); - if (m_primitives->activeScanner()) - connect (m_primitives->activeScanner(), SIGNAL (workDone()), this, SLOT (updatePrimitives())); - else - updatePrimitives(); - m_quickColors = m_guiUtilities->loadQuickColorList(); updateActions(); @@ -760,13 +756,6 @@ // --------------------------------------------------------------------------------------------------------------------- // -void MainWindow::updatePrimitives() -{ - m_primitives->populateTreeWidget(ui.primitives); -} - -// --------------------------------------------------------------------------------------------------------------------- -// void MainWindow::closeTab (int tabindex) { LDDocument* doc = m_documents->findDocumentByName (m_tabs->tabData (tabindex).toString()); @@ -822,13 +811,6 @@ // --------------------------------------------------------------------------------------------------------------------- // -QTreeWidget* MainWindow::getPrimitivesTree() const -{ - return ui.primitives; -} - -// --------------------------------------------------------------------------------------------------------------------- -// QKeySequence MainWindow::defaultShortcut (QAction* act) { return m_defaultShortcuts[act];
--- a/src/mainwindow.h Sun Mar 11 23:42:03 2018 +0200 +++ b/src/mainwindow.h Wed Mar 14 12:08:03 2018 +0200 @@ -82,7 +82,6 @@ void endAction(); class ExtProgramToolset* externalPrograms(); QVariant getConfigValue (QString name); - QTreeWidget* getPrimitivesTree() const; class QSettings* getSettings() { return m_settings; } LDColor getUniformSelectedColor(); Canvas* getRendererForDocument(LDDocument* document); @@ -137,7 +136,6 @@ void historyTraversed(); void ringToolHiResClicked (bool clicked); void tabSelected(); - void updatePrimitives(); void documentClosed(LDDocument* document); protected:
--- a/src/mainwindow.ui Sun Mar 11 23:42:03 2018 +0200 +++ b/src/mainwindow.ui Wed Mar 14 12:08:03 2018 +0200 @@ -166,18 +166,16 @@ </attribute> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> - <widget class="QTreeWidget" name="primitives"> + <widget class="QTreeView" name="primitives"> <property name="dragDropMode"> <enum>QAbstractItemView::DragOnly</enum> </property> <attribute name="headerVisible"> <bool>false</bool> </attribute> - <column> - <property name="text"> - <string notr="true">1</string> - </property> - </column> + <attribute name="headerDefaultSectionSize"> + <number>0</number> + </attribute> </widget> </item> </layout>
--- a/src/primitives.cpp Sun Mar 11 23:42:03 2018 +0200 +++ b/src/primitives.cpp Wed Mar 14 12:08:03 2018 +0200 @@ -33,10 +33,10 @@ #include "linetypes/triangle.h" PrimitiveManager::PrimitiveManager(QObject* parent) : - QObject(parent), - HierarchyElement(parent), - m_activeScanner(nullptr), - m_unmatched(nullptr) {} + QAbstractItemModel {parent}, + HierarchyElement {parent}, + m_activeScanner {nullptr}, + m_unmatched {nullptr} {} PrimitiveScanner* PrimitiveManager::activeScanner() @@ -95,10 +95,12 @@ if (m_activeScanner) { m_primitives = m_activeScanner->scannedPrimitives(); + emit layoutAboutToBeChanged(); populateCategories(); print(tr("%1 primitives scanned"), countof(m_primitives)); delete m_activeScanner; m_activeScanner = nullptr; + emit layoutChanged(); } }); } @@ -514,36 +516,149 @@ } /* - * PrimitiveManager :: populateTreeWidget - * - * Fills in a tree widget with all known primitives. + * Returns the amount of columns in the primitives tree (1) */ -void PrimitiveManager::populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault) +int PrimitiveManager::columnCount(const QModelIndex&) const +{ + return 1; +} + +/* + * For an index that points to a primitive, returns the category that contains it + */ +static PrimitiveCategory* categoryForPrimitiveIndex(const QModelIndex& primitiveIndex) { - tree->clear(); + return static_cast<PrimitiveCategory*>(primitiveIndex.internalPointer()); +} - for (PrimitiveCategory* category : m_categories) +/* + * Returns data from the tree model. + */ +QVariant PrimitiveManager::data(const QModelIndex& index, int role) const +{ + if (index.isValid()) { - PrimitiveTreeItem* parentItem = new PrimitiveTreeItem {tree, nullptr}; - parentItem->setText(0, category->name()); - //QList<QTreeWidgetItem*> subfileItems; + if (categoryForPrimitiveIndex(index) != nullptr) + { + // Index points to a primitive, return primitive information. + Primitive& primitive = categoryForPrimitiveIndex(index)->primitives[index.row()]; - for (Primitive& primitive : category->primitives) + switch(role) + { + case Qt::DisplayRole: + return format("%1 - %2", primitive.name, primitive.title); + case Qt::DecorationRole: + return MainWindow::getIcon("subfilereference"); + default: + return {}; + } + } + else { - PrimitiveTreeItem* item = new PrimitiveTreeItem {parentItem, &primitive}; - item->setText(0, format("%1 - %2", primitive.name, primitive.title)); - //subfileItems.append(item); + // Index points to a category, return category information. + PrimitiveCategory* category = this->m_categories[index.row()]; - // If this primitive is the one the current object points to, - // select it by default - if (selectByDefault == primitive.name) - tree->setCurrentItem(item); + switch (role) + { + case Qt::DisplayRole: + return category->name(); + case Qt::DecorationRole: + return MainWindow::getIcon("folder"); + default: + return {}; + } } - - tree->addTopLevelItem(parentItem); + } + else + { + // Index is invalid. + return {}; } } +/* + * For a row and parent index, returns a child index. + */ +QModelIndex PrimitiveManager::index(int row, int, const QModelIndex& parent) const +{ + if (parent.isValid()) + { + if (categoryForPrimitiveIndex(parent)) + { + // Parent is a primitive index. Primitives cannot have children so return an + // invalid index. + return {}; + } + else + { + // Parent is a category, return an index to a primitive + PrimitiveCategory* category = m_categories[parent.row()]; + + // Create an index inside the category + if (row >= 0 and row < category->primitives.size()) + return this->createIndex(row, 0, category); + else + return {}; + } + } + else + { + // Create a top-level index pointing to a category + if (row >= 0 and row < this->m_categories.size()) + return this->createIndex(row, 0, nullptr); + else + return {}; + } +} + +/* + * For a primitive index, find the category index that contains it. + */ +QModelIndex PrimitiveManager::parent(const QModelIndex &index) const +{ + int row = this->m_categories.indexOf(categoryForPrimitiveIndex(index)); + + if (row != -1) + return this->createIndex(row, 0, nullptr); + else + return {}; +} + +/* + * Returns the amount of rows contained inside the given index. + */ +int PrimitiveManager::rowCount(const QModelIndex& parent) const +{ + if (parent.isValid()) + { + if (categoryForPrimitiveIndex(parent)) + { + // Primitives don't have child nodes, so return 0. + return 0; + } + else + { + // For categories, return the amount of primitives contained. + return this->m_categories[parent.row()]->primitives.size(); + } + } + else + { + // For top-level, return the amount of categories. + return this->m_categories.size(); + } +} + +/* + * Returns a static "Primitives" text for the header. + */ +QVariant PrimitiveManager::headerData(int section, Qt::Orientation, int role) const +{ + if (section == 0 and role == Qt::DisplayRole) + return tr("Primitives"); + else + return {}; +} // // --------------------------------------------------------------------------------------------------------------------- @@ -626,6 +741,14 @@ if (not m_iterator.hasNext()) { // If there are no more primitives to iterate, we're done. Now save this information into a cache file. + std::sort( + m_scannedPrimitives.begin(), + m_scannedPrimitives.end(), + [](const Primitive& one, const Primitive& other) -> bool + { + return one.title < other.title; + } + ); QString path = m_manager->getPrimitivesCfgPath(); QFile configFile = {path};
--- a/src/primitives.h Sun Mar 11 23:42:03 2018 +0200 +++ b/src/primitives.h Wed Mar 14 12:08:03 2018 +0200 @@ -86,7 +86,7 @@ QString m_name; }; -class PrimitiveManager : public QObject, HierarchyElement +class PrimitiveManager : public QAbstractItemModel, HierarchyElement { Q_OBJECT @@ -98,9 +98,15 @@ LDDocument* getPrimitive(const PrimitiveModel &spec); QString getPrimitivesCfgPath() const; void loadPrimitives(); - void populateTreeWidget(QTreeWidget* tree, const QString& selectByDefault = {}); void startScan(); + int columnCount(const QModelIndex &parent = {}) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override; + QModelIndex parent(const QModelIndex &index) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + private: QList<PrimitiveCategory*> m_categories; PrimitiveScanner* m_activeScanner;