From 4d5962a284fe2b1a0288783216926937f484964f Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 22 Sep 2015 09:38:55 +0200 Subject: [PATCH 01/22] WIP Using a hierarchical view - Replaced the Abstract list model by a standardItem model, that is able to handle hierarchy. - editorEvent are not caught. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 ++ Polyhedron/demo/Polyhedron/Scene.cpp | 28 +++++++++++++---------- Polyhedron/demo/Polyhedron/Scene.h | 25 +++++++++++++++----- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 1dc94f01231..019fc323c72 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -227,6 +227,8 @@ MainWindow::MainWindow(QWidget* parent) // connect(ui->infoLabel, SIGNAL(customContextMenuRequested(const QPoint & )), // this, SLOT(showSceneContextMenu(const QPoint &))); + connect(scene, SIGNAL(updated()), + scene, SLOT(test_rows())); connect(ui->actionRecenterScene, SIGNAL(triggered()), viewer, SLOT(update())); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 184c9926adf..67ac68beed2 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -31,7 +31,7 @@ GlSplat::SplatRenderer* Scene::splatting() } Scene::Scene(QObject* parent) - : QAbstractListModel(parent), + : QStandardItemModel(parent), selected_item(-1), item_A(-1), item_B(-1) @@ -60,9 +60,9 @@ Scene::addItem(Scene_item* item) this, SLOT(callDraw())); if(bbox_before + item->bbox() != bbox_before) { Q_EMIT updated_bbox(); } - QAbstractListModel::beginResetModel(); + QStandardItemModel::beginResetModel(); Q_EMIT updated(); - QAbstractListModel::endResetModel(); + QStandardItemModel::endResetModel(); Item_id id = m_entries.size() - 1; Q_EMIT newItem(id); return id; @@ -89,7 +89,7 @@ Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_ } Q_EMIT updated(); itemChanged(index); - // QAbstractListModel::reset(); + // QStandardItemModel::reset(); return item; } @@ -106,9 +106,9 @@ Scene::erase(int index) selected_item = -1; - QAbstractListModel::beginResetModel(); + QStandardItemModel::beginResetModel(); Q_EMIT updated(); - QAbstractListModel::endResetModel(); + QStandardItemModel::endResetModel(); if(--index >= 0) return index; @@ -140,9 +140,9 @@ Scene::erase(QList indices) } selected_item = -1; - QAbstractListModel::beginResetModel(); + QStandardItemModel::beginResetModel(); Q_EMIT updated(); - QAbstractListModel::endResetModel(); + QStandardItemModel::endResetModel(); int index = max_index + 1 - indices.size(); if(index >= m_entries.size()) { @@ -458,7 +458,9 @@ QVariant Scene::data(const QModelIndex &index, int role) const { if (!index.isValid()) + { return QVariant(); + } if(index.row() < 0 || index.row() >= m_entries.size()) return QVariant(); @@ -548,17 +550,17 @@ Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const } } } - return QAbstractListModel::headerData(section, orientation, role); + return QStandardItemModel::headerData(section, orientation, role); } Qt::ItemFlags Scene::flags ( const QModelIndex & index ) const { if (index.isValid() && index.column() == NameColumn) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; + return QStandardItemModel::flags(index) | ::Qt::ItemIsEditable; } else { - return QAbstractListModel::flags(index); + return QStandardItemModel::flags(index); } } @@ -612,6 +614,7 @@ Scene::setData(const QModelIndex &index, return false; } + Scene::Item_id Scene::mainSelectionIndex() const { return selected_item; } @@ -662,10 +665,11 @@ void Scene::itemChanged(Scene_item* /* item */) this->createIndex(m_entries.size() - 1, LastColumn)); } -bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, +bool SceneDelegate::editorEvent(QEvent *event, QStandardItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { + qDebug()<<"editor event"; QAbstractProxyModel* proxyModel = dynamic_cast(model); Q_ASSERT(proxyModel); Scene *scene = dynamic_cast(proxyModel->sourceModel()); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 459d9867d3b..1ed3532ec70 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -7,7 +7,7 @@ #include "Scene_draw_interface.h" #include -#include +#include #include #include #include @@ -15,11 +15,11 @@ #include #include #include - +#include #include #include #include - +#include "Scene_item.h" class QEvent; class QMouseEvent; namespace GlSplat { class SplatRenderer; } @@ -27,7 +27,7 @@ namespace GlSplat { class SplatRenderer; } class Viewer_interface; class SCENE_EXPORT Scene : - public QAbstractListModel, public Scene_interface, public Scene_draw_interface + public QStandardItemModel, public Scene_interface, public Scene_draw_interface { Q_OBJECT Q_PROPERTY(int numberOfEntries READ numberOfEntries) @@ -99,7 +99,7 @@ public: return std::sqrt(dx*dx + dy*dy + dz*dz); } - // QAbstractItemModel functions + // QStandardItemModel functions int rowCount ( const QModelIndex & parent = QModelIndex() ) const; int columnCount ( const QModelIndex & parent = QModelIndex() ) const; QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; @@ -107,6 +107,7 @@ public: ::Qt::ItemFlags flags ( const QModelIndex & index ) const; bool setData(const QModelIndex &index, const QVariant &value, int role); + // auxiliary public function for QMainWindow QItemSelection createSelection(int i); QItemSelection createSelectionAll(); @@ -161,6 +162,18 @@ Q_SIGNALS: void selectionChanged(int i); private Q_SLOTS: + void test_rows() + { + QList list; + for(int i=0; i<5; i++) + { + list<appendRow(list); + } + } void setSelectionRay(double, double, double, double, double, double); void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} @@ -189,7 +202,7 @@ public: { } - bool editorEvent(QEvent *event, QAbstractItemModel *model, + bool editorEvent(QEvent *event, QStandardItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); void paint(QPainter *painter, const QStyleOptionViewItem &option, From d3336372b7b1fcdbea8f77fd1694cbbf645d7ec7 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 22 Sep 2015 10:11:23 +0200 Subject: [PATCH 02/22] editorEvent Fix - I accidently changed the QAbstractItemModel of the argmument of the function into a QStandardItemModel. --- Polyhedron/demo/Polyhedron/Scene.cpp | 3 +-- Polyhedron/demo/Polyhedron/Scene.h | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 67ac68beed2..4690acb2be0 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -665,11 +665,10 @@ void Scene::itemChanged(Scene_item* /* item */) this->createIndex(m_entries.size() - 1, LastColumn)); } -bool SceneDelegate::editorEvent(QEvent *event, QStandardItemModel *model, +bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { - qDebug()<<"editor event"; QAbstractProxyModel* proxyModel = dynamic_cast(model); Q_ASSERT(proxyModel); Scene *scene = dynamic_cast(proxyModel->sourceModel()); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 1ed3532ec70..9f5f4a8c38e 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -168,6 +168,7 @@ private Q_SLOTS: for(int i=0; i<5; i++) { list<setEditable(false); } for(int i=0; i Date: Fri, 25 Sep 2015 10:08:20 +0200 Subject: [PATCH 03/22] Hierarchy operational. - Must adapt the model so that data() returns the right value. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 4 ++-- Polyhedron/demo/Polyhedron/MainWindow.ui | 8 ++++---- Polyhedron/demo/Polyhedron/Scene.cpp | 18 ++++++++++-------- Polyhedron/demo/Polyhedron/Scene.h | 16 +++++++++++----- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 019fc323c72..e724d023a3b 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -156,7 +156,7 @@ MainWindow::MainWindow(QWidget* parent) // setup the sceneview: delegation and columns sizing... sceneView->setItemDelegate(new SceneDelegate(this)); - sceneView->header()->setStretchLastSection(false); + /* sceneView->header()->setStretchLastSection(false); sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); sceneView->header()->setSectionResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents); @@ -167,7 +167,7 @@ MainWindow::MainWindow(QWidget* parent) sceneView->resizeColumnToContents(Scene::RenderingModeColumn); sceneView->resizeColumnToContents(Scene::ABColumn); sceneView->resizeColumnToContents(Scene::VisibleColumn); - +*/ // setup connections connect(scene, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex & )), this, SLOT(updateInfo())); diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui index d19a1c77d0c..6958e31690a 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.ui +++ b/Polyhedron/demo/Polyhedron/MainWindow.ui @@ -37,7 +37,7 @@ 0 0 978 - 21 + 20 @@ -231,7 +231,7 @@ QAbstractItemView::ExtendedSelection - 0 + 10 @@ -295,8 +295,8 @@ 0 0 - 534 - 174 + 541 + 175 diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 4690acb2be0..8affa283eef 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -45,7 +45,7 @@ Scene::Scene(QObject* parent) if(ms_splatting==0) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; - + viewItem = invisibleRootItem(); } Scene::Item_id @@ -435,17 +435,19 @@ glDepthFunc(GL_LEQUAL); // workaround for Qt-4.2 (see above) #undef lighter - -int +int Scene::rowCount(const QModelIndex & parent) const { - if (parent.isValid()) - return 0; - else + if (!parent.isValid()) return m_entries.size(); + else + for(int i =0; i< m_entries.size(); i++) + if(!parent.child(i,0).isValid()) + return i+1; } -int +/* +int Scene::columnCount(const QModelIndex & parent) const { if (parent.isValid()) @@ -453,7 +455,7 @@ Scene::columnCount(const QModelIndex & parent) const else return NumberOfColumns; } - +*/ QVariant Scene::data(const QModelIndex &index, int role) const { diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 9f5f4a8c38e..262b5dbda31 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -101,7 +101,7 @@ public: // QStandardItemModel functions int rowCount ( const QModelIndex & parent = QModelIndex() ) const; - int columnCount ( const QModelIndex & parent = QModelIndex() ) const; + //int columnCount ( const QModelIndex & parent = QModelIndex() ) const; QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; ::Qt::ItemFlags flags ( const QModelIndex & index ) const; @@ -164,22 +164,28 @@ Q_SIGNALS: private Q_SLOTS: void test_rows() { + // int currentRowCount = rowCount(); + //invisibleRootItem()->removeRow(0); + //for(int i=0; i list; for(int i=0; i<5; i++) { list<setEditable(false); } - for(int i=0; iappendRow(list); - } + + viewItem->appendRow(list); + viewItem = list.at(0); + //} + // viewItem = invisibleRootItem(); } void setSelectionRay(double, double, double, double, double, double); void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} private: void draw_aux(bool with_names, Viewer_interface*); + QStandardItem* viewItem; typedef QList Entries; Entries m_entries; int selected_item; From 0b810bc19d49eaa791727de09f13f2c91b654d77 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 25 Sep 2015 15:52:38 +0200 Subject: [PATCH 04/22] Delegate fix --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 21 ++-- Polyhedron/demo/Polyhedron/Scene.cpp | 123 +++++++++++++--------- Polyhedron/demo/Polyhedron/Scene.h | 37 ++++--- 3 files changed, 108 insertions(+), 73 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index e724d023a3b..d4aed86a812 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -148,13 +148,16 @@ MainWindow::MainWindow(QWidget* parent) proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(scene); + SceneDelegate *delegate = new SceneDelegate(this); + delegate->setProxy(proxyModel); + delegate->setScene(scene); connect(ui->searchEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString))); sceneView->setModel(proxyModel); // setup the sceneview: delegation and columns sizing... - sceneView->setItemDelegate(new SceneDelegate(this)); + sceneView->setItemDelegate(delegate); /* sceneView->header()->setStretchLastSection(false); sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); @@ -940,21 +943,25 @@ void MainWindow::selectAll() int MainWindow::getSelectedSceneItemIndex() const { - QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); - if(selectedRows.size() != 1) + QModelIndexList selectedRows = sceneView->selectionModel()->selectedIndexes(); + + if(selectedRows.size() != 5) return -1; else { QModelIndex i = proxyModel->mapToSource(selectedRows.first()); - return i.row(); + return scene->index_map[i]; } } QList MainWindow::getSelectedSceneItemIndices() const { - QModelIndexList selectedRows = sceneView->selectionModel()->selectedRows(); + + QModelIndexList selectedIndices = sceneView->selectionModel()->selectedIndexes(); QList result; - Q_FOREACH(QModelIndex index, selectedRows) { - result << proxyModel->mapToSource(index).row(); + Q_FOREACH(QModelIndex index, selectedIndices) { + int temp = scene->index_map[proxyModel->mapToSource(index)];; + if(!result.contains(temp)) + result<bbox() != bbox_before) { Q_EMIT updated_bbox(); } + QStandardItemModel::beginResetModel(); + QList list; + for(int i=0; i<5; i++) + { + list<setEditable(false); + } + viewItem->appendRow(list); + for(int i=0; i<5; i++){ + index_map[list.at(i)->index()] = m_entries.size() -1; + } + viewItem = list.at(0); + + Q_EMIT updated(); QStandardItemModel::endResetModel(); Item_id id = m_entries.size() - 1; @@ -143,7 +157,7 @@ Scene::erase(QList indices) QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); - + int index = max_index + 1 - indices.size(); if(index >= m_entries.size()) { index = m_entries.size() - 1; @@ -174,7 +188,7 @@ Scene::item(Item_id index) const return m_entries.value(index); // QList::value checks bounds } -Scene::Item_id +Scene::Item_id Scene::item_id(Scene_item* scene_item) const { return m_entries.indexOf(scene_item); @@ -227,7 +241,7 @@ void Scene::initializeGL() } -bool +bool Scene::keyPressEvent(QKeyEvent* e){ bool res=false; for (QList::iterator it=selected_items_list.begin(),endit=selected_items_list.end(); @@ -239,7 +253,7 @@ Scene::keyPressEvent(QKeyEvent* e){ return res; } -void +void Scene::draw() { draw_aux(false, 0); @@ -249,7 +263,7 @@ Scene::draw(Viewer_interface* viewer) { draw_aux(false, viewer); } -void +void Scene::drawWithNames() { draw_aux(true, 0); @@ -260,7 +274,7 @@ Scene::drawWithNames(Viewer_interface* viewer) draw_aux(true, viewer); } -void +void Scene::draw_aux(bool with_names, Viewer_interface* viewer) { if(!ms_splatting->viewer_is_set) @@ -442,8 +456,10 @@ Scene::rowCount(const QModelIndex & parent) const return m_entries.size(); else for(int i =0; i< m_entries.size(); i++) + { if(!parent.child(i,0).isValid()) - return i+1; + return i; + } } /* @@ -456,7 +472,7 @@ Scene::columnCount(const QModelIndex & parent) const return NumberOfColumns; } */ -QVariant +QVariant Scene::data(const QModelIndex &index, int role) const { if (!index.isValid()) @@ -464,33 +480,33 @@ Scene::data(const QModelIndex &index, int role) const return QVariant(); } - if(index.row() < 0 || index.row() >= m_entries.size()) + int id = index_map[index];\ + if(id < 0 || id >= m_entries.size()) return QVariant(); - if(role == ::Qt::ToolTipRole) { - return m_entries[index.row()]->toolTip(); + return m_entries[id]->toolTip(); } switch(index.column()) { case ColorColumn: if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->color(); + return m_entries.value(id)->color(); else if(role == ::Qt::DecorationRole) - return m_entries.value(index.row())->color(); + return m_entries.value(id)->color(); break; case NameColumn: if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->name(); + return m_entries.value(id)->name(); if(role == ::Qt::FontRole) - return m_entries.value(index.row())->font(); + return m_entries.value(id)->font(); break; case RenderingModeColumn: if(role == ::Qt::DisplayRole) { - return m_entries.value(index.row())->renderingModeName(); + return m_entries.value(id)->renderingModeName(); } else if(role == ::Qt::EditRole) { - return static_cast(m_entries.value(index.row())->renderingMode()); + return static_cast(m_entries.value(id)->renderingMode()); } else if(role == ::Qt::TextAlignmentRole) { return ::Qt::AlignCenter; @@ -498,9 +514,9 @@ Scene::data(const QModelIndex &index, int role) const break; case ABColumn: if(role == ::Qt::DisplayRole) { - if(index.row() == item_A) + if(id == item_A) return "A"; - if(index.row() == item_B) + if(id == item_B) return "B"; } else if(role == ::Qt::TextAlignmentRole) { @@ -509,7 +525,7 @@ Scene::data(const QModelIndex &index, int role) const break; case VisibleColumn: if(role == ::Qt::DisplayRole || role == ::Qt::EditRole) - return m_entries.value(index.row())->visible(); + return m_entries.value(id)->visible(); break; default: return QVariant(); @@ -517,7 +533,7 @@ Scene::data(const QModelIndex &index, int role) const return QVariant(); } -QVariant +QVariant Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const { if(orientation == ::Qt::Horizontal) { @@ -555,7 +571,7 @@ Scene::headerData ( int section, ::Qt::Orientation orientation, int role ) const return QStandardItemModel::headerData(section, orientation, role); } -Qt::ItemFlags +Qt::ItemFlags Scene::flags ( const QModelIndex & index ) const { if (index.isValid() && index.column() == NameColumn) { @@ -566,18 +582,20 @@ Scene::flags ( const QModelIndex & index ) const } } -bool -Scene::setData(const QModelIndex &index, +bool +Scene::setData(const QModelIndex &index, const QVariant &value, int role) { + if( role != ::Qt::EditRole || !index.isValid() ) return false; - if(index.row() < 0 || index.row() >= m_entries.size()) + int id = index_map[index]; + if(id < 0 || id >= m_entries.size()) return false; - Scene_item* item = m_entries[index.row()]; + Scene_item* item = m_entries[id]; if(!item) return false; switch(index.column()) { @@ -635,14 +653,14 @@ int Scene::selectionBindex() const { QItemSelection Scene::createSelection(int i) { - return QItemSelection(this->createIndex(i, 0), - this->createIndex(i, LastColumn)); + return QItemSelection(index_map.keys(i).at(0), + index_map.keys(i).at(4)); } QItemSelection Scene::createSelectionAll() { - return QItemSelection(this->createIndex(0, 0), - this->createIndex(m_entries.size() - 1 , LastColumn)); + return QItemSelection(index_map.keys(0).at(0), + index_map.keys(m_entries.size() - 1).at(4)); } void Scene::itemChanged() @@ -675,6 +693,7 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, Q_ASSERT(proxyModel); Scene *scene = dynamic_cast(proxyModel->sourceModel()); Q_ASSERT(scene); + int id = scene->index_map[proxyModel->mapToSource(index)]; switch(index.column()) { case Scene::VisibleColumn: if (event->type() == QEvent::MouseButtonPress) { @@ -683,7 +702,7 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, int x = mouseEvent->pos().x() - option.rect.x(); if(x >= (option.rect.width() - size)/2 && x <= (option.rect.width() + size)/2) { - model->setData(index, ! model->data(index).toBool() ); + model->setData(index, !model->data(index).toBool()); } } return false; //so that the selection can change @@ -726,19 +745,19 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, break; case Scene::ABColumn: if (event->type() == QEvent::MouseButtonPress) { - if(index.row() == scene->item_B) { - scene->item_A = index.row(); + if(id == scene->item_B) { + scene->item_A = id; scene->item_B = -1; } - else if(index.row() == scene->item_A) { - scene->item_B = index.row(); + else if(id == scene->item_A) { + scene->item_B = id; scene->item_A = -1; } else if(scene->item_A == -1) { - scene->item_A = index.row(); + scene->item_A = id; } else { - scene->item_B = index.row(); + scene->item_B = id; } scene->dataChanged(scene->createIndex(0, Scene::ABColumn), scene->createIndex(scene->rowCount() - 1, Scene::ABColumn)); @@ -753,31 +772,35 @@ bool SceneDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, void SceneDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { + QModelIndex test = proxy->mapToSource(index); if (index.column() != Scene::VisibleColumn) { QItemDelegate::paint(painter, option, index); } else { const QAbstractItemModel *model = index.model(); + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive : QPalette::Disabled; if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight)); - bool checked = model->data(index, ::Qt::DisplayRole).toBool(); int width = option.rect.width(); int height = option.rect.height(); size = (std::min)(width, height); int x = option.rect.x() + (option.rect.width() / 2) - (size / 2);; int y = option.rect.y() + (option.rect.height() / 2) - (size / 2); - if(checked) { - painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); - } - else { - painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), - ::Qt::KeepAspectRatio, - ::Qt::SmoothTransformation)); + if(test.row()>=0 && test.row()m_entries.size()){ + + if(checked) { + painter->drawPixmap(x, y, checkOnPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } + else { + painter->drawPixmap(x, y, checkOffPixmap.scaled(QSize(size, size), + ::Qt::KeepAspectRatio, + ::Qt::SmoothTransformation)); + } } drawFocus(painter, option, option.rect); // since we draw the grid ourselves } @@ -858,7 +881,7 @@ Scene::Bbox Scene::bbox() const namespace scene { namespace details { Q_DECL_EXPORT -Scene_item* +Scene_item* findItem(const Scene_interface* scene_interface, const QMetaObject& metaobj, QString name, Scene_item_name_fn_ptr fn) { @@ -872,8 +895,8 @@ findItem(const Scene_interface* scene_interface, } Q_DECL_EXPORT -QList -findItems(const Scene_interface* scene_interface, +QList +findItems(const Scene_interface* scene_interface, const QMetaObject&, QString name, Scene_item_name_fn_ptr fn) { diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 262b5dbda31..f851814dad4 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ class SCENE_EXPORT Scene : friend class SceneDelegate; public: + QMap index_map; enum Columns { NameColumn = 0, ColorColumn, RenderingModeColumn, @@ -120,6 +122,7 @@ public Q_SLOTS: void setSelectedItemIndex(int i) { + //qDebug()<<"selected item = "< l ) { selected_items_list = l; + qDebug()<removeRow(0); - //for(int i=0; i list; - for(int i=0; i<5; i++) - { - list<setEditable(false); - } - - viewItem->appendRow(list); - viewItem = list.at(0); - //} - // viewItem = invisibleRootItem(); } void setSelectionRay(double, double, double, double, double, double); void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} private: void draw_aux(bool with_names, Viewer_interface*); + //Temp member, used only for dev purpose for now. QStandardItem* viewItem; typedef QList Entries; Entries m_entries; @@ -198,7 +188,7 @@ public: static GlSplat::SplatRenderer* splatting(); }; // end class Scene - +class QAbstractProxyModel; class SCENE_EXPORT SceneDelegate : public QItemDelegate { public: @@ -214,11 +204,26 @@ public: const QModelIndex &index); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + void setProxy(QAbstractProxyModel* p_proxy){ + proxy = p_proxy; + } + void setScene(Scene* p_scene){ + scene = p_scene; + } private: QPixmap checkOnPixmap; QPixmap checkOffPixmap; + QAbstractProxyModel *proxy; + Scene *scene; mutable int size; }; // end class SceneDelegate #endif // SCENE_H + + +/*TO DO +virer viewItem +arranger les choses pour remettre index_map en private. +virer test_rows + */ From 06e885da4c025f87875649194d134367cf608743 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 28 Sep 2015 12:47:34 +0200 Subject: [PATCH 05/22] Handling of the remove function --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 3 ++- Polyhedron/demo/Polyhedron/Scene.cpp | 27 +++++++++++++++++------ Polyhedron/demo/Polyhedron/Scene.h | 2 -- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index d4aed86a812..08c12fac22c 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -889,6 +889,7 @@ void MainWindow::selectSceneItem(int i) else { QItemSelection s = proxyModel->mapSelectionFromSource(scene->createSelection(i)); + sceneView->selectionModel()->select(s, QItemSelectionModel::ClearAndSelect); } @@ -944,7 +945,6 @@ void MainWindow::selectAll() int MainWindow::getSelectedSceneItemIndex() const { QModelIndexList selectedRows = sceneView->selectionModel()->selectedIndexes(); - if(selectedRows.size() != 5) return -1; else { @@ -1290,6 +1290,7 @@ bool MainWindow::on_actionErase_triggered() { int next_index = scene->erase(scene->selectionIndices()); selectSceneItem(next_index); + qDebug()<<"Remaining values : "<index_map.values(); return next_index >= 0; } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 2718677c803..d863c1e28f1 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -51,7 +51,6 @@ Scene::Scene(QObject* parent) Scene::Item_id Scene::addItem(Scene_item* item) { - Bbox bbox_before = bbox(); m_entries.push_back(item); connect(item, SIGNAL(itemChanged()), @@ -60,7 +59,6 @@ Scene::addItem(Scene_item* item) this, SLOT(callDraw())); if(bbox_before + item->bbox() != bbox_before) { Q_EMIT updated_bbox(); } - QStandardItemModel::beginResetModel(); QList list; for(int i=0; i<5; i++) @@ -74,7 +72,6 @@ Scene::addItem(Scene_item* item) } viewItem = list.at(0); - Q_EMIT updated(); QStandardItemModel::endResetModel(); Item_id id = m_entries.size() - 1; @@ -114,6 +111,7 @@ Scene::erase(int index) return -1; Scene_item* item = m_entries[index]; + Q_EMIT itemAboutToBeDestroyed(item); delete item; m_entries.removeAt(index); @@ -123,37 +121,52 @@ Scene::erase(int index) QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); - if(--index >= 0) return index; if(!m_entries.isEmpty()) return 0; return -1; + } int Scene::erase(QList indices) { + clear(); + index_map.clear(); QList to_be_removed; - + viewItem = invisibleRootItem(); int max_index = -1; Q_FOREACH(int index, indices) { if(index < 0 || index >= m_entries.size()) continue; + max_index = (std::max)(max_index, index); + Scene_item* item = m_entries[index]; to_be_removed.push_back(item); } - Q_FOREACH(Scene_item* item, to_be_removed) { Q_EMIT itemAboutToBeDestroyed(item); delete item; m_entries.removeAll(item); } - selected_item = -1; + for(int j =0; j list; + for(int i=0; i<5; i++) + { + list<setEditable(false); + } + viewItem->appendRow(list); + for(int i=0; i<5; i++){ + index_map[list.at(i)->index()] = j; + } + } QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index f851814dad4..c4876c76fdd 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -122,7 +122,6 @@ public Q_SLOTS: void setSelectedItemIndex(int i) { - //qDebug()<<"selected item = "< l ) { selected_items_list = l; - qDebug()< Date: Tue, 29 Sep 2015 14:06:11 +0200 Subject: [PATCH 06/22] (WIP) Addition of .h files --- .../Polyhedron/CGAL_demo/Scene_interface.h | 3 +- Polyhedron/demo/Polyhedron/CMakeLists.txt | 10 +- Polyhedron/demo/Polyhedron/MainWindow.cpp | 7 +- .../Polyhedron_demo_group_plugin.cpp | 85 +++++++++++++ .../Polyhedron/Polyhedron_demo_group_plugin.h | 117 ++++++++++++++++++ .../Polyhedron_demo_group_plugin.ui | 86 +++++++++++++ .../Polyhedron_demo_plugin_helper.h | 2 +- Polyhedron/demo/Polyhedron/Scene.cpp | 9 +- Polyhedron/demo/Polyhedron/Scene.h | 8 +- .../demo/Polyhedron/Scene_group_item.cpp | 72 +++++++++++ Polyhedron/demo/Polyhedron/Scene_group_item.h | 36 ++++++ 11 files changed, 422 insertions(+), 13 deletions(-) create mode 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp create mode 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h create mode 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.ui create mode 100644 Polyhedron/demo/Polyhedron/Scene_group_item.cpp create mode 100644 Polyhedron/demo/Polyhedron/Scene_group_item.h diff --git a/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h b/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h index 9ac8df9842a..bfae22f3911 100644 --- a/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h +++ b/Polyhedron/demo/Polyhedron/CGAL_demo/Scene_interface.h @@ -8,7 +8,6 @@ #include class Scene_item; - // OpenGL rendering mode enum RenderingMode { Points = 0, PointsPlusNormals, @@ -71,7 +70,7 @@ public: typedef int Item_id; - virtual ~Scene_interface() {}; + virtual ~Scene_interface() {} virtual Item_id addItem(Scene_item* item) = 0; virtual Scene_item* replaceItem(Item_id, Scene_item*, bool emit_item_about_to_be_destroyed = false) = 0; diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 0ae3f7a2a2a..16016add5fe 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -135,6 +135,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) Viewer.cpp #Viewer_moc.cpp Viewer_interface_moc.cpp Scene_item.cpp #Scene_item.moc + Scene_group_item.cpp Polyhedron_demo_plugin_helper.cpp) qt5_use_modules(demo_framework OpenGL Gui Widgets Script Xml) @@ -213,7 +214,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) scene_basic_objects scene_polyhedron_item scene_polygon_soup_item - scene_nef_polyhedron_item ) + scene_nef_polyhedron_item) add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${lib} ) endforeach() @@ -493,6 +494,13 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) polyhedron_demo_plugin(shortest_path_plugin Polyhedron_demo_shortest_path_plugin ${shortestPathUI_FILES}) target_link_libraries(shortest_path_plugin scene_polyhedron_item scene_polylines_item scene_polyhedron_selection_item scene_polyhedron_shortest_path_item scene_basic_objects) + + add_item(scene_group_item Scene_group_item.cpp) + + qt5_wrap_ui( groupUI_FILES Polyhedron_demo_group_plugin.ui) + polyhedron_demo_plugin(group_plugin Polyhedron_demo_group_plugin ${groupUI_FILES}) + target_link_libraries(group_plugin scene_group_item) + # # Exporting # diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 08c12fac22c..06175861182 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -159,9 +159,9 @@ MainWindow::MainWindow(QWidget* parent) // setup the sceneview: delegation and columns sizing... sceneView->setItemDelegate(delegate); - /* sceneView->header()->setStretchLastSection(false); - sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); - sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); + //sceneView->header()->setStretchLastSection(false); + /* sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); + sceneView->header()->setSectionResizeMode(Scene::NameColumn, QHeaderView::Stretch); sceneView->header()->setSectionResizeMode(Scene::ColorColumn, QHeaderView::ResizeToContents); sceneView->header()->setSectionResizeMode(Scene::RenderingModeColumn, QHeaderView::Fixed); sceneView->header()->setSectionResizeMode(Scene::ABColumn, QHeaderView::Fixed); @@ -1290,7 +1290,6 @@ bool MainWindow::on_actionErase_triggered() { int next_index = scene->erase(scene->selectionIndices()); selectSceneItem(next_index); - qDebug()<<"Remaining values : "<index_map.values(); return next_index >= 0; } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp new file mode 100644 index 00000000000..4f3a17087c9 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp @@ -0,0 +1,85 @@ +#include "Polyhedron_demo_group_plugin.h" +#include "Polyhedron_demo_group_plugin.moc" +#include "Scene.h" + +/********** + * Models * + **********/ + +QVariant GroupModel::data(const QModelIndex &index, int role) const +{ + + + if(index.row()<0 || index.row()>groups().size()) + return QVariant(); + + if(role != Qt::DisplayRole) + return QVariant(); + + return groups()[index.row()]->name(); +} + + +QVariant ItemsModel::data(const QModelIndex &index, int role) const +{ + + if(index.row()<0 || index.row() > items().size()) + return QVariant(); + + if(role != Qt::DisplayRole) + return QVariant(); + + return items()[index.row()]->name(); +} + +/**************** + * Group Plugin * + ****************/ + +void Polyhedron_demo_group_plugin::init(QMainWindow* mainWindow, + Scene_interface* scene_interface) { + //get the references + Scene* trueScene = dynamic_cast(scene_interface); + this->scene = scene_interface; + this->mw = mainWindow; + group_model = new GroupModel(trueScene); + items_model = new ItemsModel(trueScene); + + //creates and link the actions + actionAddToGroup= new QAction("Add to group", mw); + if(actionAddToGroup) { + connect(actionAddToGroup, SIGNAL(triggered()), + this, SLOT(draw_triangle())); + } +} + +void Polyhedron_demo_group_plugin::GroupChoice() +{ + Polyhedron_demo_group_plugin_dialog *dialog = new Polyhedron_demo_group_plugin_dialog(this); + dialog->show(); + +} +/**************** + * Dialog Class * + ****************/ + +Polyhedron_demo_group_plugin_dialog::Polyhedron_demo_group_plugin_dialog( Polyhedron_demo_group_plugin *p_plugin) +{ + m_plugin= p_plugin; + setupUi(this); + itemsView->setModel(m_plugin->items_model); + groupsView->setModel(m_plugin->group_model); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(selected_scene_items())); +} + +void Polyhedron_demo_group_plugin_dialog::selected_scene_items() +{ + QModelIndexList selectedRows = itemsView->selectionModel()->selectedIndexes(); + QModelIndex selectedGroup= groupsView->selectionModel()->selectedIndexes().first(); + Q_FOREACH(QModelIndex index, selectedRows) + { + m_plugin->selected_items << m_plugin->items_model->items()[index.row()]; + } + m_plugin->selected_group = m_plugin->group_model->groups()[selectedGroup.row()]; + m_plugin->add_to_group(); +} diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h new file mode 100644 index 00000000000..4fb946a84ce --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -0,0 +1,117 @@ +#ifndef POLYHEDRON_DEMO_GROUP_H +#define POLYHEDRON_DEMO_GROUP_H +#include +#include +#include +#include +#include +#include "Scene_group_item.h" +#include "CGAL_demo/Scene_interface.h" +#include "ui_Polyhedron_demo_group_plugin.h" +#include "Scene.h" + +class Scene_interface; + +class GroupModel : public QAbstractListModel +{ + +public: + GroupModel(Scene* scene) + { + data_pool = scene; + } + + QVariant data(const QModelIndex &index, int role) const; + int rowCount(const QModelIndex &parent) const + { + return data_pool->group_entries().size(); + } + QList groups() const + { + return data_pool->group_entries(); + } + +private: + Scene* data_pool; +}; + +class ItemsModel : public QAbstractListModel +{ +public: + ItemsModel(Scene* scene) + { + data_pool = scene; + } + + QVariant data(const QModelIndex &index, int role) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + Q_UNUSED(parent); + return data_pool->item_entries().size(); + } + + QList items() const + { + return data_pool->item_entries(); + } +private: + Scene* data_pool; + +}; + + +#include "Polyhedron_demo_plugin_helper.h" +class Polyhedron_demo_group_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + //Configures CMake to use MOC correctly + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0") +public : + // To silent a warning -Woverloaded-virtual + // See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings + using Polyhedron_demo_plugin_helper::init; + void init(QMainWindow* mainWindow, + Scene_interface* scene_interface); + + bool applicable(QAction*) const + { + return true; + } + QList actions() const { + return QList() << actionAddToGroup; + } + GroupModel *group_model; + ItemsModel *items_model; + void add_to_group() { + Q_FOREACH(Scene_item* item, selected_items) + selected_group->addChild(item); + } + QList selected_items; + Scene_group_item* selected_group; +public Q_SLOTS: + void GroupChoice(); + + +private: + QAction* actionAddToGroup; + +}; //end of class Polyhedron_demo_group_plugin + +class Polyhedron_demo_group_plugin_dialog : public QDialog, private Ui::GroupDialog +{ + Q_OBJECT +public: + Polyhedron_demo_group_plugin_dialog(Polyhedron_demo_group_plugin *p_plugin); + +public Q_SLOTS: + void selected_scene_items(); +private : + Polyhedron_demo_group_plugin * m_plugin; + + +}; +#endif diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.ui new file mode 100644 index 00000000000..c46f985f009 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.ui @@ -0,0 +1,86 @@ + + + GroupDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 30 + 240 + 341 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 9 + 9 + 371 + 211 + + + + + + + + + + + + + + + + buttonBox + accepted() + GroupDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + GroupDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.h index ff813231a65..a81f7d379c5 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.h @@ -13,7 +13,7 @@ class QMainWindow; class QDockWidget; #include "Polyhedron_demo_plugin_interface.h" -#include "Scene_interface.h" +#include "CGAL_demo/Scene_interface.h" class SCENE_ITEM_EXPORT Polyhedron_demo_plugin_helper : public Polyhedron_demo_plugin_interface diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index d863c1e28f1..a7b35fb6190 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -4,7 +4,6 @@ #include "config.h" #include "Scene.h" -#include "Scene_item.h" #include #include @@ -888,7 +887,15 @@ Scene::Bbox Scene::bbox() const } return bbox; } +QList Scene::group_entries() const +{ + return m_group_entries; +} +QList Scene::item_entries() const +{ + return m_entries; +} #include "Scene_find_items.h" namespace scene { namespace details { diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index c4876c76fdd..9ecff4ebdac 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -2,10 +2,8 @@ #define SCENE_H #include "config.h" #include "Scene_config.h" - #include "Scene_interface.h" #include "Scene_draw_interface.h" - #include #include #include @@ -21,6 +19,7 @@ #include #include #include "Scene_item.h" +#include "Scene_group_item.h" class QEvent; class QMouseEvent; namespace GlSplat { class SplatRenderer; } @@ -108,8 +107,8 @@ public: QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; ::Qt::ItemFlags flags ( const QModelIndex & index ) const; bool setData(const QModelIndex &index, const QVariant &value, int role); - - + QList group_entries() const ; + QList item_entries() const ; // auxiliary public function for QMainWindow QItemSelection createSelection(int i); QItemSelection createSelectionAll(); @@ -176,6 +175,7 @@ private: QStandardItem* viewItem; typedef QList Entries; Entries m_entries; + QList m_group_entries; int selected_item; QList selected_items_list; int item_A; diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp new file mode 100644 index 00000000000..2f43e39c3e1 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -0,0 +1,72 @@ +#include "Scene_group_item.h" + + +Scene_group_item::Scene_group_item() + : Scene_item(0,0) +{} + +bool Scene_group_item::isFinite() const +{ + Q_FOREACH(Scene_item *item, children) + if(!item->isFinite()){ + return false; + } + return true; +} + +bool Scene_group_item::isEmpty() const { + Q_FOREACH(Scene_item *item, children) + if(!item->isEmpty()){ + return false; + } + return true; +} + +Scene_group_item::Bbox Scene_group_item::bbox() const +{ + double xmax=0, ymax=0, zmax=0; + double xmin=0, ymin=0, zmin=0; + if(!children.isEmpty()) + { + xmax = children.first()->bbox().xmax; ymax = children.first()->bbox().ymax; zmax = children.first()->bbox().zmax; + xmin = children.first()->bbox().xmin; ymin = children.first()->bbox().ymin; zmin = children.first()->bbox().zmin; + } + + Q_FOREACH(Scene_item* item, children) + { + xmax = std::max(xmax,item->bbox().xmax); ymax = std::max(ymax, item->bbox().ymax); zmax = std::max(zmax, item->bbox().zmax); + xmin = std::min(xmin, item->bbox().xmin); ymin = std::min(ymin,item->bbox().ymin); zmin = std::min(zmin,item->bbox().zmin); + } + return Bbox(xmin, ymin, zmin, xmax, ymax, zmax); +} + + +bool Scene_group_item::supportsRenderingMode(RenderingMode m) const { + Q_FOREACH(Scene_item* item, children) + if(!item->supportsRenderingMode(m)) + return false; + return !children.isEmpty(); + +} + +QString Scene_group_item::toolTip() const { + QString str = + QObject::tr( "

Number of children: %1
").arg(children.size()); + str+="

"; + str += QString("Bounding box: min (%1,%2,%3), max(%4,%5,%6)") + .arg(bbox().xmin) + .arg(bbox().ymin) + .arg(bbox().zmin) + .arg(bbox().xmax) + .arg(bbox().ymax) + .arg(bbox().zmax); + return str; +} + +void Scene_group_item::addChild(Scene_item* new_item) +{ + if(!children.contains(new_item)) + children.append(new_item); + else + print_message("Item is already in group."); +} diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h new file mode 100644 index 00000000000..a07d5b43e91 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -0,0 +1,36 @@ +#ifndef SCENE_GROUP_ITEM_H +#define SCENE_GROUP_ITEM_H + +#include "Scene_item.h" +#include "Messages_interface.h" + +class Q_DECL_EXPORT Scene_group_item : public Scene_item +{ + Q_OBJECT +public : + Scene_group_item(); + ~Scene_group_item() {} + bool isFinite() const; + + bool isEmpty() const ; + + Bbox bbox() const; + + Scene_group_item* clone() const {return 0;} + //! Indicate if rendering mode is supported. + bool supportsRenderingMode(RenderingMode m) const; + + QString toolTip() const; + + void addChild(Scene_item* new_item); + + +private: + QList children; + void print_message(QString message) { messages->information(message); } + Messages_interface* messages; + +}; //end of class Scene_group_item + + +#endif // SCENE_GROUP_ITEM_H From 887b6c5322988f8c3e8d1018455cfde926dcbe17 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 1 Oct 2015 09:21:40 +0200 Subject: [PATCH 07/22] Groups drawing done - The hierarchy display seems to be over. - Remaining : group modifications management. --- .../Polyhedron_demo_group_plugin.cpp | 47 ++++++++++-- .../Polyhedron/Polyhedron_demo_group_plugin.h | 26 +++++-- Polyhedron/demo/Polyhedron/Scene.cpp | 73 +++++++++++++++++-- Polyhedron/demo/Polyhedron/Scene.h | 2 + .../demo/Polyhedron/Scene_group_item.cpp | 12 +-- Polyhedron/demo/Polyhedron/Scene_group_item.h | 6 +- Polyhedron/demo/Polyhedron/Scene_item.h | 3 + 7 files changed, 139 insertions(+), 30 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp index 4f3a17087c9..8da6ae76d5f 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp @@ -8,17 +8,44 @@ QVariant GroupModel::data(const QModelIndex &index, int role) const { - - - if(index.row()<0 || index.row()>groups().size()) + if(index.row()<0 ) return QVariant(); - if(role != Qt::DisplayRole) + if(role != Qt::DisplayRole ) return QVariant(); return groups()[index.row()]->name(); } +Qt::ItemFlags +GroupModel::flags ( const QModelIndex & index ) const +{ + if (index.isValid() && index.row() == 0) { + return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; + } + else { + return QAbstractListModel::flags(index); + } + return 0; +} +bool +GroupModel::setData(const QModelIndex &index, + const QVariant &value, + int role) +{ + + if( role != ::Qt::EditRole || !index.isValid() ) + return false; + + if(index.row() != 0) + return false; + + Scene_group_item* item = groups()[0]; + if(!item) return false; + data_pool->setGroupName(value.toString()); + Q_EMIT dataChanged(index, index); + return true; +} QVariant ItemsModel::data(const QModelIndex &index, int role) const { @@ -37,19 +64,19 @@ QVariant ItemsModel::data(const QModelIndex &index, int role) const ****************/ void Polyhedron_demo_group_plugin::init(QMainWindow* mainWindow, - Scene_interface* scene_interface) { + Scene_interface* scene_interface,Messages_interface* m ) { //get the references - Scene* trueScene = dynamic_cast(scene_interface); + trueScene = dynamic_cast(scene_interface); this->scene = scene_interface; this->mw = mainWindow; + messages = m; group_model = new GroupModel(trueScene); items_model = new ItemsModel(trueScene); - //creates and link the actions actionAddToGroup= new QAction("Add to group", mw); if(actionAddToGroup) { connect(actionAddToGroup, SIGNAL(triggered()), - this, SLOT(draw_triangle())); + this, SLOT(GroupChoice())); } } @@ -68,8 +95,11 @@ Polyhedron_demo_group_plugin_dialog::Polyhedron_demo_group_plugin_dialog( Polyhe m_plugin= p_plugin; setupUi(this); itemsView->setModel(m_plugin->items_model); + itemsView->setSelectionMode(QAbstractItemView::ExtendedSelection); groupsView->setModel(m_plugin->group_model); connect(buttonBox, SIGNAL(accepted()), this, SLOT(selected_scene_items())); + connect(buttonBox, SIGNAL(accepted()), m_plugin->trueScene, SLOT(group_added())); + } void Polyhedron_demo_group_plugin_dialog::selected_scene_items() @@ -82,4 +112,5 @@ void Polyhedron_demo_group_plugin_dialog::selected_scene_items() } m_plugin->selected_group = m_plugin->group_model->groups()[selectedGroup.row()]; m_plugin->add_to_group(); + } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 4fb946a84ce..24d3ad0fcea 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -24,6 +24,7 @@ public: QVariant data(const QModelIndex &index, int role) const; int rowCount(const QModelIndex &parent) const { + Q_UNUSED (parent); return data_pool->group_entries().size(); } QList groups() const @@ -31,6 +32,9 @@ public: return data_pool->group_entries(); } + Qt::ItemFlags flags (const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + private: Scene* data_pool; }; @@ -74,8 +78,7 @@ public : // To silent a warning -Woverloaded-virtual // See http://stackoverflow.com/questions/9995421/gcc-woverloaded-virtual-warnings using Polyhedron_demo_plugin_helper::init; - void init(QMainWindow* mainWindow, - Scene_interface* scene_interface); + void init(QMainWindow* mw, Scene_interface* sc, Messages_interface*); bool applicable(QAction*) const { @@ -88,16 +91,31 @@ public : ItemsModel *items_model; void add_to_group() { Q_FOREACH(Scene_item* item, selected_items) - selected_group->addChild(item); + { + if(selected_group->getChildren().contains(item)) + print_message("Item is already in group."); + else if(selected_group == item) + print_message("A group cannot contain itself."); + else + { + selected_group->addChild(item); + item->has_group = true; + } + + } + selected_items.clear(); } QList selected_items; Scene_group_item* selected_group; + Scene* trueScene; public Q_SLOTS: void GroupChoice(); private: QAction* actionAddToGroup; + void print_message(QString message) { messages->information(message); } + Messages_interface* messages; }; //end of class Polyhedron_demo_group_plugin @@ -111,7 +129,5 @@ public Q_SLOTS: void selected_scene_items(); private : Polyhedron_demo_group_plugin * m_plugin; - - }; #endif diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index a7b35fb6190..5b6c882a853 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -46,6 +46,8 @@ Scene::Scene(QObject* parent) ms_splattingCounter++; viewItem = invisibleRootItem(); + m_group_entries.append(new Scene_group_item("new group")); + } Scene::Item_id Scene::addItem(Scene_item* item) @@ -69,7 +71,6 @@ Scene::addItem(Scene_item* item) for(int i=0; i<5; i++){ index_map[list.at(i)->index()] = m_entries.size() -1; } - viewItem = list.at(0); Q_EMIT updated(); QStandardItemModel::endResetModel(); @@ -466,12 +467,13 @@ Scene::rowCount(const QModelIndex & parent) const { if (!parent.isValid()) return m_entries.size(); - else - for(int i =0; i< m_entries.size(); i++) - { - if(!parent.child(i,0).isValid()) - return i; - } + + for(int i =0; i< m_entries.size(); i++) + { + if(!parent.child(i,0).isValid()) + return i; + } + return 0; } /* @@ -896,6 +898,63 @@ QList Scene::item_entries() const { return m_entries; } + +void Scene::group_added() +{ +//insures that the groupview and data always has a "new group" in first position. + if(m_group_entries.first()->name() != "new group") + { + addItem(m_group_entries.first()); + m_group_entries.prepend(new Scene_group_item("new group")); + } +//makes the hierarchy in the tree + //clears the model + clear(); + index_map.clear(); + viewItem = invisibleRootItem(); + //fills the model + Q_FOREACH(Scene_item* item, m_entries) + { + if(!item->has_group) + { + QList list; + for(int i=0; i<5; i++) + { + list<setEditable(false); + } + viewItem->appendRow(list); + for(int i=0; i<5; i++){ + index_map[list.at(i)->index()] = m_entries.indexOf(item); + } + Scene_group_item* group = + qobject_cast(item); + if(group) + { + viewItem = list.first(); + Q_FOREACH(Scene_item*child, group->getChildren()) + { + QList children; + for(int i=0; i<5; i++) + { + children<setEditable(false); + } + viewItem->appendRow(children); + for(int i=0; i<5; i++){ + index_map[children.at(i)->index()] = m_entries.indexOf(child); + } + } + viewItem = invisibleRootItem(); + } + } + + } +} +void Scene::setGroupName(QString name) +{ + m_group_entries[0]->setName(name); +} #include "Scene_find_items.h" namespace scene { namespace details { diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 9ecff4ebdac..af3af345149 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -112,9 +112,11 @@ public: // auxiliary public function for QMainWindow QItemSelection createSelection(int i); QItemSelection createSelectionAll(); + void setGroupName(QString name); public Q_SLOTS: // Notify the scene that an item was modified + void group_added(); void itemChanged(); // slots called by items themself void itemChanged(int i); void itemChanged(Scene_item*); diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 2f43e39c3e1..f40083a01aa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -1,9 +1,12 @@ #include "Scene_group_item.h" +#include -Scene_group_item::Scene_group_item() +Scene_group_item::Scene_group_item(QString name) : Scene_item(0,0) -{} +{ + this->name_ = name; +} bool Scene_group_item::isFinite() const { @@ -64,9 +67,6 @@ QString Scene_group_item::toolTip() const { } void Scene_group_item::addChild(Scene_item* new_item) -{ - if(!children.contains(new_item)) +{ children.append(new_item); - else - print_message("Item is already in group."); } diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h index a07d5b43e91..077562cb84e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -8,7 +8,7 @@ class Q_DECL_EXPORT Scene_group_item : public Scene_item { Q_OBJECT public : - Scene_group_item(); + Scene_group_item(QString name = QString()); ~Scene_group_item() {} bool isFinite() const; @@ -24,11 +24,9 @@ public : void addChild(Scene_item* new_item); - + QList getChildren() const {return children;} private: QList children; - void print_message(QString message) { messages->information(message); } - Messages_interface* messages; }; //end of class Scene_group_item diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 83f1b5b641f..96bfba2e0c9 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -64,6 +64,7 @@ public: buffers.push_back(n_buf); buffers[i].create(); } + has_group = false; } Scene_item(int buffers_size, int vaos_size) : name_("unamed"), @@ -88,6 +89,7 @@ public: buffers.push_back(n_buf); buffers[i].create(); } + has_group = false; } virtual ~Scene_item(); virtual Scene_item* clone() const = 0; @@ -135,6 +137,7 @@ public: // Event handling virtual bool keyPressEvent(QKeyEvent*){return false;} + bool has_group; public Q_SLOTS: // Call that once you have finished changing something in the item // (either the properties or internal data) From 5616734f26370b5b859fd6ba9880cd25f90c9713 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 2 Oct 2015 10:37:06 +0200 Subject: [PATCH 08/22] Addition of removing features --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 3 +- .../Polyhedron/Polyhedron_demo_group_plugin.h | 7 +- Polyhedron/demo/Polyhedron/Scene.cpp | 151 ++++++++++-------- Polyhedron/demo/Polyhedron/Scene.h | 9 +- .../demo/Polyhedron/Scene_group_item.cpp | 40 +++++ Polyhedron/demo/Polyhedron/Scene_group_item.h | 51 ++++++ Polyhedron/demo/Polyhedron/Scene_item.h | 6 +- 7 files changed, 191 insertions(+), 76 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 06175861182..7e866ddfec1 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -152,6 +152,7 @@ MainWindow::MainWindow(QWidget* parent) delegate->setProxy(proxyModel); delegate->setScene(scene); + connect(ui->searchEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString))); sceneView->setModel(proxyModel); @@ -1004,7 +1005,7 @@ void MainWindow::contextMenuRequested(const QPoint& global_pos) { void MainWindow::showSceneContextMenu(int selectedItemIndex, const QPoint& global_pos) { - Scene_item* item = scene->item(selectedItemIndex); + Scene_item* item = scene->item(scene->index_map.value(scene->index(selectedItemIndex,0)));//scene->item(selectedItemIndex); if(!item) return; const char* prop_name = "Menu modified by MainWindow."; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 24d3ad0fcea..b936462c152 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -93,17 +93,20 @@ public : Q_FOREACH(Scene_item* item, selected_items) { if(selected_group->getChildren().contains(item)) - print_message("Item is already in group."); + selected_group->removeChild(item); else if(selected_group == item) print_message("A group cannot contain itself."); + else if(item->has_group !=0) + print_message("An item can have only one group."); else { selected_group->addChild(item); - item->has_group = true; } } selected_items.clear(); + if(!trueScene->item_entries().contains(selected_group)) + scene->addItem(selected_group); } QList selected_items; Scene_group_item* selected_group; diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 5b6c882a853..fe88d3f35f5 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -111,11 +111,21 @@ Scene::erase(int index) return -1; Scene_item* item = m_entries[index]; + Q_FOREACH(Scene_group_item* group, m_group_entries) + { + if(group->getChildren().contains(item)) + group->removeChild(item); + if (group->getChildren().isEmpty()) + { + m_group_entries.removeOne(group); + m_entries.removeOne(group); + check_first_group(); + } + } Q_EMIT itemAboutToBeDestroyed(item); delete item; m_entries.removeAt(index); - selected_item = -1; QStandardItemModel::beginResetModel(); @@ -147,8 +157,31 @@ Scene::erase(QList indices) to_be_removed.push_back(item); } - Q_FOREACH(Scene_item* item, to_be_removed) { + Scene_group_item* group = + qobject_cast(item); + if(group) + { + QList to_erase; + Q_FOREACH(Scene_item* child, group->getChildren()) + to_erase<getChildren().contains(item)) + { + group->removeChild(item); + if (group->getChildren().isEmpty()) + { + m_group_entries.removeOne(group); + m_entries.removeOne(group); + check_first_group(); + } + } + + } + Q_EMIT itemAboutToBeDestroyed(item); delete item; m_entries.removeAll(item); @@ -462,30 +495,6 @@ glDepthFunc(GL_LEQUAL); // workaround for Qt-4.2 (see above) #undef lighter -int -Scene::rowCount(const QModelIndex & parent) const -{ - if (!parent.isValid()) - return m_entries.size(); - - for(int i =0; i< m_entries.size(); i++) - { - if(!parent.child(i,0).isValid()) - return i; - } - return 0; -} - -/* -int -Scene::columnCount(const QModelIndex & parent) const -{ - if (parent.isValid()) - return 0; - else - return NumberOfColumns; -} -*/ QVariant Scene::data(const QModelIndex &index, int role) const { @@ -606,8 +615,9 @@ Scene::setData(const QModelIndex &index, return false; int id = index_map[index]; - if(id < 0 || id >= m_entries.size()) + if(id < 0 || id >= m_entries.size()){ return false; + } Scene_item* item = m_entries[id]; if(!item) return false; @@ -615,6 +625,7 @@ Scene::setData(const QModelIndex &index, { case NameColumn: item->setName(value.toString()); + check_first_group(); Q_EMIT dataChanged(index, index); return true; break; @@ -634,13 +645,14 @@ Scene::setData(const QModelIndex &index, rendering_mode = static_cast( (rendering_mode+1) % NumberOfRenderingMode ); } item->setRenderingMode(rendering_mode); - Q_EMIT dataChanged(index, index); + QModelIndex nindex = createIndex(m_entries.size()-1,RenderingModeColumn+1); + Q_EMIT dataChanged(index, nindex); return true; break; } case VisibleColumn: item->setVisible(value.toBool()); - Q_EMIT dataChanged(index, index); + Q_EMIT dataChanged(index, createIndex(m_entries.size()-1,VisibleColumn+1)); return true; default: return false; @@ -899,14 +911,27 @@ QList Scene::item_entries() const return m_entries; } -void Scene::group_added() +void Scene::check_first_group() { -//insures that the groupview and data always has a "new group" in first position. - if(m_group_entries.first()->name() != "new group") + + + if(m_group_entries.isEmpty() || m_group_entries.first()->name() != "new group") { - addItem(m_group_entries.first()); m_group_entries.prepend(new Scene_group_item("new group")); } +} +void Scene::group_added() +{ + Q_FOREACH(Scene_group_item *group, m_group_entries) + { + if (group->getChildren().isEmpty()) + { + m_group_entries.removeOne(group); + m_entries.removeOne(group); + } + } + check_first_group(); + //makes the hierarchy in the tree //clears the model clear(); @@ -915,40 +940,7 @@ void Scene::group_added() //fills the model Q_FOREACH(Scene_item* item, m_entries) { - if(!item->has_group) - { - QList list; - for(int i=0; i<5; i++) - { - list<setEditable(false); - } - viewItem->appendRow(list); - for(int i=0; i<5; i++){ - index_map[list.at(i)->index()] = m_entries.indexOf(item); - } - Scene_group_item* group = - qobject_cast(item); - if(group) - { - viewItem = list.first(); - Q_FOREACH(Scene_item*child, group->getChildren()) - { - QList children; - for(int i=0; i<5; i++) - { - children<setEditable(false); - } - viewItem->appendRow(children); - for(int i=0; i<5; i++){ - index_map[children.at(i)->index()] = m_entries.indexOf(child); - } - } - viewItem = invisibleRootItem(); - } - } - + organize_items(item, viewItem, 0); } } void Scene::setGroupName(QString name) @@ -957,6 +949,31 @@ void Scene::setGroupName(QString name) } #include "Scene_find_items.h" +void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop) +{ + if(item->has_group <= loop) + { + QList list; + for(int i=0; i<5; i++) + { + list<setEditable(false); + } + root->appendRow(list); + for(int i=0; i<5; i++){ + index_map[list.at(i)->index()] = m_entries.indexOf(item); + } + Scene_group_item* group = + qobject_cast(item); + if(group) + { + Q_FOREACH(Scene_item*child, group->getChildren()) + { + organize_items(child, list.first(), loop+1); + } + } + } +} namespace scene { namespace details { Q_DECL_EXPORT diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index af3af345149..de3c8a6fc7c 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -101,8 +101,7 @@ public: } // QStandardItemModel functions - int rowCount ( const QModelIndex & parent = QModelIndex() ) const; - //int columnCount ( const QModelIndex & parent = QModelIndex() ) const; + QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; ::Qt::ItemFlags flags ( const QModelIndex & index ) const; @@ -115,8 +114,10 @@ public: void setGroupName(QString name); public Q_SLOTS: - // Notify the scene that an item was modified + //!insures that the groupview and data always has a "new group" in first position. + void check_first_group(); void group_added(); + // Notify the scene that an item was modified void itemChanged(); // slots called by items themself void itemChanged(int i); void itemChanged(Scene_item*); @@ -173,6 +174,7 @@ private Q_SLOTS: private: void draw_aux(bool with_names, Viewer_interface*); + void organize_items(Scene_item* item, QStandardItem *root, int loop); //Temp member, used only for dev purpose for now. QStandardItem* viewItem; typedef QList Entries; @@ -184,6 +186,7 @@ private: int item_B; static GlSplat::SplatRenderer* ms_splatting; static int ms_splattingCounter; + public: static GlSplat::SplatRenderer* splatting(); diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index f40083a01aa..97bc816f03c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -69,4 +69,44 @@ QString Scene_group_item::toolTip() const { void Scene_group_item::addChild(Scene_item* new_item) { children.append(new_item); + add_group_number(new_item); + } + +void Scene_group_item::add_group_number(Scene_item * new_item) +{ + + Scene_group_item* group = + qobject_cast(new_item); + if(group) + Q_FOREACH(Scene_item* child, group->getChildren()) + add_group_number(child); + new_item->has_group++; +} +void Scene_group_item::setColor(QColor c) +{ + Q_FOREACH(Scene_item* child, children) + { + child->setColor(c); + } +} + +void Scene_group_item::setRenderingMode(RenderingMode m) +{ + Scene_item::setRenderingMode(m); + Q_FOREACH(Scene_item* child, children) + { + child->setRenderingMode(m); + Q_EMIT child->renderingModeChanged(); + } +} + +void Scene_group_item::setVisible(bool b) +{ + Scene_item::setVisible(b); + Q_FOREACH(Scene_item* child, children) + { + child->setVisible(b); + } +} + diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h index 077562cb84e..8c4b40d219f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -24,9 +24,60 @@ public : void addChild(Scene_item* new_item); + void setColor(QColor c); + + void setRenderingMode(RenderingMode m); + + void setVisible(bool b); + + void setPointsMode() { + setRenderingMode(Points); + } + + void setWireframeMode() { + setRenderingMode(Wireframe); + } + void setWireframe() { + setRenderingMode(Wireframe); + } + + void setFlat() { + setRenderingMode(Flat); + } + void setFlatMode() { + setRenderingMode(Flat); + } + + void setFlatPlusEdgesMode() { + setRenderingMode(FlatPlusEdges); + } + + void setGouraudMode() { + setRenderingMode(Gouraud); + } + + void setPointsPlusNormalsMode(){ + setRenderingMode(PointsPlusNormals); + } + + void setSplattingMode(){ + setRenderingMode(Splatting); + } + QList getChildren() const {return children;} + + void removeChild( Scene_item* child) + { + child->has_group--; + children.removeOne(child); + } + +Q_SIGNALS: + void updated(int row, int column); + private: QList children; + void add_group_number(Scene_item*new_item); }; //end of class Scene_group_item diff --git a/Polyhedron/demo/Polyhedron/Scene_item.h b/Polyhedron/demo/Polyhedron/Scene_item.h index 96bfba2e0c9..79bd341bdf3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_item.h @@ -64,7 +64,7 @@ public: buffers.push_back(n_buf); buffers[i].create(); } - has_group = false; + has_group = 0; } Scene_item(int buffers_size, int vaos_size) : name_("unamed"), @@ -89,7 +89,7 @@ public: buffers.push_back(n_buf); buffers[i].create(); } - has_group = false; + has_group = 0; } virtual ~Scene_item(); virtual Scene_item* clone() const = 0; @@ -137,7 +137,7 @@ public: // Event handling virtual bool keyPressEvent(QKeyEvent*){return false;} - bool has_group; + int has_group; public Q_SLOTS: // Call that once you have finished changing something in the item // (either the properties or internal data) From 372865722b42ec8117451a8f75d9b95228cb2b52 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 2 Oct 2015 11:43:17 +0200 Subject: [PATCH 09/22] Merged in master --- Polyhedron/demo/Polyhedron/Scene_group_item.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 97bc816f03c..b7b28e2e640 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -1,3 +1,4 @@ + #include "Scene_group_item.h" #include From 77a6f4af46ab31dfe93af88ddb6b1ab82e93f751 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 5 Oct 2015 15:58:38 +0200 Subject: [PATCH 10/22] Remove item fix + group selection - Removing an item does not kill the hirarchy anymore, thanks to recursivity in several functions. - Selecting a group now adds all its children to the selected_items_list. --- Polyhedron/demo/Polyhedron/Scene.cpp | 67 +++++++++---------- Polyhedron/demo/Polyhedron/Scene.h | 23 +++++-- .../demo/Polyhedron/Scene_group_item.cpp | 1 + Polyhedron/demo/Polyhedron/Scene_group_item.h | 11 ++- .../Scene_polyhedron_transform_item.cpp | 6 +- 5 files changed, 62 insertions(+), 46 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index fe88d3f35f5..0c7f7cecf6d 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -138,6 +138,23 @@ Scene::erase(int index) return -1; } +void Scene::check_empty_group(Scene_item* item) +{ + Q_FOREACH(Scene_group_item* group, m_group_entries) + { + if(group->getChildren().contains(item)) + { + group->removeChild(item); + if (group->getChildren().isEmpty()) + { + check_empty_group(group); + m_group_entries.removeOne(group); + m_entries.removeOne(group); + } + } + } + check_first_group(); +} int Scene::erase(QList indices) @@ -157,48 +174,26 @@ Scene::erase(QList indices) to_be_removed.push_back(item); } - Q_FOREACH(Scene_item* item, to_be_removed) { + Q_FOREACH(Scene_item* item, to_be_removed) { Scene_group_item* group = qobject_cast(item); - if(group) - { - QList to_erase; - Q_FOREACH(Scene_item* child, group->getChildren()) - to_erase<getChildren().contains(item)) - { - group->removeChild(item); - if (group->getChildren().isEmpty()) - { - m_group_entries.removeOne(group); - m_entries.removeOne(group); - check_first_group(); - } - } - - } + if(group) + { + QList to_erase; + Q_FOREACH(Scene_item* child, group->getChildren()) + to_erase< list; - for(int i=0; i<5; i++) - { - list<setEditable(false); - } - viewItem->appendRow(list); - for(int i=0; i<5; i++){ - index_map[list.at(i)->index()] = j; - } + organize_items(item, viewItem, 0); } QStandardItemModel::beginResetModel(); Q_EMIT updated(); @@ -340,7 +335,7 @@ Scene::draw_aux(bool with_names, Viewer_interface* viewer) viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); viewer->glPointSize(2.f); viewer->glLineWidth(1.0f); - if(index == selected_item) + if(index == selected_item || selected_items_list.contains(index)) { item.selection_changed(true); } @@ -382,7 +377,7 @@ glDepthFunc(GL_LEQUAL); viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); viewer->glPointSize(2.f); viewer->glLineWidth(1.0f); - if(index == selected_item) + if(index == selected_item || selected_items_list.contains(index)) { item.selection_changed(true); } @@ -404,7 +399,7 @@ glDepthFunc(GL_LEQUAL); viewer->glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); viewer->glPointSize(2.f); viewer->glLineWidth(1.0f); - if(index == selected_item) + if(index == selected_item || selected_items_list.contains(index)) { item.selection_changed(true); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index de3c8a6fc7c..9440a9053ff 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -116,6 +116,7 @@ public: public Q_SLOTS: //!insures that the groupview and data always has a "new group" in first position. void check_first_group(); + void check_empty_group(Scene_item* item); void group_added(); // Notify the scene that an item was modified void itemChanged(); // slots called by items themself @@ -131,7 +132,7 @@ public Q_SLOTS: { selected_item = i; Q_EMIT selectionChanged(i); - }; + } void setSelectedItem(Scene_item* item_to_select) { @@ -145,12 +146,26 @@ public Q_SLOTS: } ++i; } - }; + } - void setSelectedItemsList(QList l ) + QList setSelectedItemsList(QList l ) { + Q_FOREACH(int i,l) + { + Scene_group_item* group = + qobject_cast(item(i)); + if(group) + { + QList list; + Q_FOREACH(Scene_item* child, group->getChildren()) + list<setColor(c); diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h index 8c4b40d219f..70375d90fb7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -66,10 +66,15 @@ public : QList getChildren() const {return children;} - void removeChild( Scene_item* child) + void removeChild( Scene_item* item) { - child->has_group--; - children.removeOne(child); + Scene_group_item* group = + qobject_cast(item); + if(group) + Q_FOREACH(Scene_item* child, group->getChildren()) + removeChild(child); + item->has_group--; + children.removeOne(item); } Q_SIGNALS: diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp index 77de6a687e1..5918348277d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_transform_item.cpp @@ -13,6 +13,7 @@ Scene_polyhedron_transform_item::Scene_polyhedron_transform_item(const qglviewer { frame->setPosition(pos); nb_lines = 0; + invalidate_buffers(); } void Scene_polyhedron_transform_item::initialize_buffers(Viewer_interface *viewer =0) const @@ -30,8 +31,6 @@ void Scene_polyhedron_transform_item::initialize_buffers(Viewer_interface *viewe program->setAttributeBuffer("vertex",GL_FLOAT,0,3); buffers[0].release(); - QColor color = this->color(); - program->setAttributeValue("colors",color); vaos[0]->release(); program->release(); } @@ -64,7 +63,6 @@ void Scene_polyhedron_transform_item::compute_elements() positions_lines.push_back(b.z()-center_.z); } - } void Scene_polyhedron_transform_item::draw_edges(Viewer_interface* viewer) const @@ -79,6 +77,8 @@ void Scene_polyhedron_transform_item::draw_edges(Viewer_interface* viewer) const for (int i=0; i<16; ++i){ f_matrix.data()[i] = (float)frame->matrix()[i]; } + QColor color = this->color(); + program->setAttributeValue("colors",color); program->setUniformValue("f_matrix", f_matrix); viewer->glDrawArrays(GL_LINES, 0, static_cast(nb_lines/3)); vaos[0]->release(); From 2f4660fd7fd58ae34d43b0b8033da29b966d3865 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 8 Oct 2015 09:48:36 +0200 Subject: [PATCH 11/22] Addition of a drag&drop feature --- Polyhedron/demo/Polyhedron/MainWindow.ui | 4 +- .../Polyhedron/Polyhedron_demo_group_plugin.h | 5 +- Polyhedron/demo/Polyhedron/Scene.cpp | 59 ++++++++++++++++++- Polyhedron/demo/Polyhedron/Scene.h | 4 +- .../demo/Polyhedron/Scene_group_item.cpp | 3 + .../demo/Polyhedron/Scene_polyhedron_item.cpp | 2 +- Polyhedron/demo/Polyhedron/Viewer.cpp | 6 +- 7 files changed, 74 insertions(+), 9 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui index fecab26a57a..00e79516e34 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.ui +++ b/Polyhedron/demo/Polyhedron/MainWindow.ui @@ -81,7 +81,6 @@ - @@ -200,6 +199,9 @@ QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + + QAbstractItemView::InternalMove + true diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index b936462c152..4040cea56c5 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -96,11 +96,10 @@ public : selected_group->removeChild(item); else if(selected_group == item) print_message("A group cannot contain itself."); - else if(item->has_group !=0) - print_message("An item can have only one group."); else { - selected_group->addChild(item); + //selected_group->addChild(item); + trueScene->changeGroup(item, selected_group); } } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 0c7f7cecf6d..b77a78f3586 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -17,7 +17,7 @@ #include #include #include - +#include @@ -655,6 +655,46 @@ Scene::setData(const QModelIndex &index, return false; } +bool Scene::dropMimeData(const QMimeData *data, + Qt::DropAction action, + int row, + int column, + const QModelIndex &parent) +{ + //gets the moving item + Scene_item* item = this->item(mainSelectionIndex()); + //Gets the group at the drop position + Scene_group_item* group = + qobject_cast(this->item(index_map[parent])); + //if the drop item is not a group_item, then the drop action + //must be ignored + if(!group) + { + //unless the drop zone is empty, which means the item should be removed from all groups. + if(!parent.isValid()) + { + while(item->has_group!=0) + { + Q_FOREACH(Scene_group_item* group_item, m_group_entries) + if(group_item->getChildren().contains(item)) + { + group_item->removeChild(item); + break; + } + } + + group_added(); + return true; + } + return false; + } + changeGroup(item, group); + //group->addChild(item(mainSelectionIndex())); + group_added(); + return true; + + +} Scene::Item_id Scene::mainSelectionIndex() const { return selected_item; @@ -938,6 +978,23 @@ void Scene::group_added() organize_items(item, viewItem, 0); } } +//TO DO gerer les has_group +void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) +{ + //remove item from the containing group if any + if(item->has_group!=0) + Q_FOREACH(Scene_group_item* group, m_group_entries) + { + if(group->getChildren().contains(item)) + { + group->removeChild(item); + break; + } + } + //add the item to the target group + target_group->addChild(item); + item->has_group = target_group->has_group +1; +} void Scene::setGroupName(QString name) { m_group_entries[0]->setName(name); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 9440a9053ff..25e74bc5660 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -48,6 +48,7 @@ public: ~Scene(); int addItem(Scene_item* item); + void changeGroup(Scene_item* item, Scene_group_item* target_group); Scene_item* replaceItem(int index, Scene_item* item, bool emit_item_about_to_be_destroyed = false); Q_INVOKABLE int erase(int); @@ -101,7 +102,7 @@ public: } // QStandardItemModel functions - + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; ::Qt::ItemFlags flags ( const QModelIndex & index ) const; @@ -205,6 +206,7 @@ private: public: static GlSplat::SplatRenderer* splatting(); + }; // end class Scene class QAbstractProxyModel; class SCENE_EXPORT SceneDelegate : public QItemDelegate diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 5d13e6baaa2..9465c1ff08b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -69,8 +69,11 @@ QString Scene_group_item::toolTip() const { void Scene_group_item::addChild(Scene_item* new_item) { + if(!children.contains(new_item)) + { children.append(new_item); add_group_number(new_item); + } } diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 7cf727de38f..868a4fb6d43 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -964,7 +964,7 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { compute_normals_and_vertices(); initialize_buffers(viewer); } - +qDebug()<<"draw"; if(!is_selected && renderingMode() == Flat) vaos[0]->bind(); diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index fee167b5b4c..a17db5c3bdb 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -187,6 +187,7 @@ void Viewer::turnCameraBy180Degres() { void Viewer_impl::draw_aux(bool with_names, Viewer* viewer) { + qDebug()<<"draw"; if(scene == 0) return; @@ -233,7 +234,8 @@ void Viewer::drawWithNames() void Viewer::postSelection(const QPoint& pixel) { - bool found = false; + qDebug()<<"postSelection"; + /* bool found = false; qglviewer::Vec point = camera()->pointUnderPixel(pixel, found); if(found) { Q_EMIT selectedPoint(point.x, @@ -244,7 +246,7 @@ void Viewer::postSelection(const QPoint& pixel) const qglviewer::Vec dir = point - orig; Q_EMIT selectionRay(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); - } + }*/ } bool Viewer_interface::readFrame(QString s, qglviewer::Frame& frame) { From ab4237cf8eea05af7ebaf3c23ee6240e7d2d5a23 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 9 Oct 2015 14:32:10 +0200 Subject: [PATCH 12/22] Multiple selection handling implementation - the drag and drop now supports multiple selection --- Polyhedron/demo/Polyhedron/Scene.cpp | 26 ++++++++++--------- .../demo/Polyhedron/Scene_polyhedron_item.cpp | 1 - Polyhedron/demo/Polyhedron/Viewer.cpp | 1 - 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index b77a78f3586..250a0803b5c 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -661,33 +661,35 @@ bool Scene::dropMimeData(const QMimeData *data, int column, const QModelIndex &parent) { - //gets the moving item - Scene_item* item = this->item(mainSelectionIndex()); + //gets the moving items + QList items; + Q_FOREACH(int i, selected_items_list) + items << item(i); //Gets the group at the drop position Scene_group_item* group = qobject_cast(this->item(index_map[parent])); - //if the drop item is not a group_item, then the drop action - //must be ignored + //if the drop item is not a group_item, then the drop action must be ignored if(!group) { //unless the drop zone is empty, which means the item should be removed from all groups. if(!parent.isValid()) { - while(item->has_group!=0) - { - Q_FOREACH(Scene_group_item* group_item, m_group_entries) - if(group_item->getChildren().contains(item)) - { + Q_FOREACH(Scene_item* item, items) + while(item->has_group!=0) + { + Q_FOREACH(Scene_group_item* group_item, m_group_entries) + if(group_item->getChildren().contains(item)) + { group_item->removeChild(item); break; - } - } - + } + } group_added(); return true; } return false; } + Q_FOREACH(Scene_item* item, items) changeGroup(item, group); //group->addChild(item(mainSelectionIndex())); group_added(); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index 868a4fb6d43..64e8e3546ac 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -964,7 +964,6 @@ void Scene_polyhedron_item::draw(Viewer_interface* viewer) const { compute_normals_and_vertices(); initialize_buffers(viewer); } -qDebug()<<"draw"; if(!is_selected && renderingMode() == Flat) vaos[0]->bind(); diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index a17db5c3bdb..264b00ff1d9 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -187,7 +187,6 @@ void Viewer::turnCameraBy180Degres() { void Viewer_impl::draw_aux(bool with_names, Viewer* viewer) { - qDebug()<<"draw"; if(scene == 0) return; From 0015b40e9d075219d9bcc17fe7eec6b323275326 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Thu, 12 Nov 2015 10:30:30 +0100 Subject: [PATCH 13/22] Bugs fix - Manipulating items in sub_groups should work properly - moving groups into other groups seems to work now --- .../Polyhedron/Polyhedron_demo_group_plugin.h | 16 ++++++++------ Polyhedron/demo/Polyhedron/Scene.cpp | 21 ++++++++++++++++--- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 4040cea56c5..2c9137811d0 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -82,7 +82,7 @@ public : bool applicable(QAction*) const { - return true; + return scene->numberOfEntries() > 0; } QList actions() const { return QList() << actionAddToGroup; @@ -93,19 +93,23 @@ public : Q_FOREACH(Scene_item* item, selected_items) { if(selected_group->getChildren().contains(item)) - selected_group->removeChild(item); + { + //selected_group->removeChild(item); + trueScene->check_empty_group(item); + item->has_group = 0; + + } else if(selected_group == item) print_message("A group cannot contain itself."); else { - //selected_group->addChild(item); trueScene->changeGroup(item, selected_group); - } + if(!trueScene->item_entries().contains(selected_group)) + scene->addItem(selected_group); + } } selected_items.clear(); - if(!trueScene->item_entries().contains(selected_group)) - scene->addItem(selected_group); } QList selected_items; Scene_group_item* selected_group; diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 250a0803b5c..43253c39893 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -663,8 +663,23 @@ bool Scene::dropMimeData(const QMimeData *data, { //gets the moving items QList items; + QList groups_children; + + //get IDs of all children of selected groups Q_FOREACH(int i, selected_items_list) - items << item(i); + { + Scene_group_item* group = + qobject_cast(item(i)); + if(group) + Q_FOREACH(Scene_item* child, group->getChildren()) + groups_children << item_id(child); + } + // Insure thhat children of selected groups will not be added twice + Q_FOREACH(int i, selected_items_list) + { + if(!groups_children.contains(i)) + items << item(i); + } //Gets the group at the drop position Scene_group_item* group = qobject_cast(this->item(index_map[parent])); @@ -980,7 +995,6 @@ void Scene::group_added() organize_items(item, viewItem, 0); } } -//TO DO gerer les has_group void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) { //remove item from the containing group if any @@ -989,7 +1003,8 @@ void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) { if(group->getChildren().contains(item)) { - group->removeChild(item); + //group->removeChild(item); + check_empty_group(item); break; } } From 5a45c419ae8f4d69707ba4894618aa5fb60d2372 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 13 Nov 2015 10:46:44 +0100 Subject: [PATCH 14/22] Saving the expanded state of the groups when modifying the view. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 25 ++++++++++++++++++ Polyhedron/demo/Polyhedron/MainWindow.h | 1 + Polyhedron/demo/Polyhedron/Scene.cpp | 26 ++++++++++++++++--- Polyhedron/demo/Polyhedron/Scene.h | 4 ++- .../demo/Polyhedron/Scene_group_item.cpp | 10 +++++++ Polyhedron/demo/Polyhedron/Scene_group_item.h | 5 ++++ 6 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 1d12ef3ed14..f0bbf30e086 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -213,6 +213,15 @@ MainWindow::MainWindow(QWidget* parent) connect(sceneView, SIGNAL(customContextMenuRequested(const QPoint & )), this, SLOT(showSceneContextMenu(const QPoint &))); + connect(sceneView, SIGNAL(expanded(QModelIndex)), + scene, SLOT(setExpanded(QModelIndex))); + + connect(sceneView, SIGNAL(collapsed(QModelIndex)), + scene, SLOT(setCollapsed(QModelIndex))); + + connect(scene, SIGNAL(restoreCollapsedState()), + this, SLOT(restoreCollapseState())); + connect(viewer, SIGNAL(selected(int)), this, SLOT(selectSceneItem(int))); connect(viewer, SIGNAL(selectedPoint(double, double, double)), @@ -1622,3 +1631,19 @@ void MainWindow::on_actionRecenterScene_triggered() updateViewerBBox(); viewer->camera()->interpolateToFitScene(); } + +void MainWindow::restoreCollapseState() +{ + QModelIndex modelIndex = sceneView->indexAt(sceneView->rect().topLeft()); + + while (modelIndex.isValid()) + { + Scene_group_item* group = + qobject_cast(scene->item(scene->index_map.value(scene->index(0, 0, modelIndex.parent())))); + if(group && group->isExpanded()) + { + sceneView->setExpanded(modelIndex, true); + } + modelIndex = sceneView->indexBelow(modelIndex); + } +} diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index db6e7c73ca9..641f2848925 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -56,6 +56,7 @@ public Q_SLOTS: void updateViewerBBox(); void open(QString); + void restoreCollapseState(); /// given a file extension file, returns true if `filename` matches the filter bool file_matches_filter(const QString& filters, const QString& filename); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 43253c39893..53b43e66fa3 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -71,11 +71,11 @@ Scene::addItem(Scene_item* item) for(int i=0; i<5; i++){ index_map[list.at(i)->index()] = m_entries.size() -1; } - + Q_EMIT restoreCollapsedState(); Q_EMIT updated(); QStandardItemModel::endResetModel(); Item_id id = m_entries.size() - 1; - Q_EMIT newItem(id); + Q_EMIT newItem(id); return id; } @@ -100,7 +100,7 @@ Scene::replaceItem(Scene::Item_id index, Scene_item* item, bool emit_item_about_ } Q_EMIT updated(); itemChanged(index); - // QStandardItemModel::reset(); + Q_EMIT restoreCollapsedState(); return item; } @@ -154,6 +154,7 @@ void Scene::check_empty_group(Scene_item* item) } } check_first_group(); + Q_EMIT restoreCollapsedState(); } int @@ -755,6 +756,7 @@ void Scene::itemChanged(Item_id i) Q_EMIT dataChanged(this->createIndex(i, 0), this->createIndex(i, LastColumn)); + Q_EMIT restoreCollapsedState(); } void Scene::itemChanged(Scene_item* /* item */) @@ -1042,6 +1044,24 @@ void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop) } } } + Q_EMIT restoreCollapsedState(); +} + +void Scene::setExpanded(QModelIndex id) +{ + Scene_group_item* group = + qobject_cast(item(index_map.value(index(0, 0, id.parent())))); + if(group) + { + group->setExpanded(true); + } +} +void Scene::setCollapsed(QModelIndex id) +{ + Scene_group_item* group = + qobject_cast(item(index_map.value(index(0, 0, id.parent())))); + if(group) + group->setExpanded(false); } namespace scene { namespace details { diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 25e74bc5660..df428249869 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -180,8 +180,10 @@ Q_SIGNALS: void itemAboutToBeDestroyed(Scene_item*); void selectionRay(double, double, double, double, double, double); void selectionChanged(int i); - + void restoreCollapsedState(); private Q_SLOTS: + void setExpanded(QModelIndex); + void setCollapsed(QModelIndex); void test_rows() { } diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 9465c1ff08b..e845f752382 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -7,6 +7,7 @@ Scene_group_item::Scene_group_item(QString name) : Scene_item(0,0) { this->name_ = name; + expanded = false; } bool Scene_group_item::isFinite() const @@ -115,3 +116,12 @@ void Scene_group_item::setVisible(bool b) } } +bool Scene_group_item::isExpanded() const +{ + return expanded; +} + +void Scene_group_item::setExpanded(bool b) +{ + expanded = b; +} diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h index 70375d90fb7..ec8fae2a28b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -14,6 +14,10 @@ public : bool isEmpty() const ; + bool isExpanded() const; + + void setExpanded(bool); + Bbox bbox() const; Scene_group_item* clone() const {return 0;} @@ -83,6 +87,7 @@ Q_SIGNALS: private: QList children; void add_group_number(Scene_item*new_item); + bool expanded; }; //end of class Scene_group_item From 836e9c5d65b1a0a366d6185de5c999abb32514c6 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 16 Nov 2015 09:49:22 +0100 Subject: [PATCH 15/22] Segfault Fix and clean-up --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 36 +++-- Polyhedron/demo/Polyhedron/MainWindow.h | 2 + Polyhedron/demo/Polyhedron/Scene.cpp | 140 ++++++++++-------- Polyhedron/demo/Polyhedron/Scene.h | 14 +- .../demo/Polyhedron/Scene_group_item.cpp | 2 +- 5 files changed, 105 insertions(+), 89 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index f0bbf30e086..dccd431e811 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1077,6 +1077,7 @@ void MainWindow::selectSceneItem(int i) sceneView->selectionModel()->select(s, QItemSelectionModel::ClearAndSelect); } + restoreCollapseState(); } @@ -1133,7 +1134,7 @@ int MainWindow::getSelectedSceneItemIndex() const return -1; else { QModelIndex i = proxyModel->mapToSource(selectedRows.first()); - return scene->index_map[i]; + return scene->getIdFromModelIndex(i); } } @@ -1143,7 +1144,7 @@ QList MainWindow::getSelectedSceneItemIndices() const QModelIndexList selectedIndices = sceneView->selectionModel()->selectedIndexes(); QList result; Q_FOREACH(QModelIndex index, selectedIndices) { - int temp = scene->index_map[proxyModel->mapToSource(index)];; + int temp = scene->getIdFromModelIndex(proxyModel->mapToSource(index)); if(!result.contains(temp)) result<item(scene->index_map.value(scene->index(selectedItemIndex,0)));//scene->item(selectedItemIndex); + Scene_item* item = scene->item(scene->getIdFromModelIndex(scene->index(selectedItemIndex,0))); if(!item) return; const char* prop_name = "Menu modified by MainWindow."; @@ -1632,18 +1633,25 @@ void MainWindow::on_actionRecenterScene_triggered() viewer->camera()->interpolateToFitScene(); } +QModelIndex MainWindow::recurseExpand(QModelIndex index) +{ + if(index.child(0,0).isValid()) + recurseExpand(index.child(0,0)); + int row = index.row(); + int column = index.column(); + QModelIndex id = scene->index(index.row(),0,index.sibling(row+1, column)); + Scene_group_item* group = + qobject_cast(scene->item(scene->getIdFromModelIndex(id))); + if(group && group->isExpanded()) + { + sceneView->setExpanded(index, true); + } + if( index.sibling(index.row()+1,0).isValid()) + recurseExpand(index.sibling(index.row()+1,0)); + +} void MainWindow::restoreCollapseState() { QModelIndex modelIndex = sceneView->indexAt(sceneView->rect().topLeft()); - - while (modelIndex.isValid()) - { - Scene_group_item* group = - qobject_cast(scene->item(scene->index_map.value(scene->index(0, 0, modelIndex.parent())))); - if(group && group->isExpanded()) - { - sceneView->setExpanded(modelIndex, true); - } - modelIndex = sceneView->indexBelow(modelIndex); - } + recurseExpand(modelIndex); } diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index 641f2848925..c0ef621d866 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -22,6 +22,7 @@ class Polyhedron_demo_io_plugin_interface; class Polyhedron_demo_plugin_interface; class Scene_item; class QSortFilterProxyModel; +class QModelIndex; namespace Ui { class MainWindow; @@ -170,6 +171,7 @@ protected: QList getSelectedSceneItemIndices() const; private: + QModelIndex recurseExpand(QModelIndex index); QString strippedName(const QString &fullFileName); void setMenus(QString, QString, QAction *a); /// plugin black-list diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 53b43e66fa3..5ea561b13d2 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -44,7 +44,6 @@ Scene::Scene(QObject* parent) if(ms_splatting==0) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; - viewItem = invisibleRootItem(); m_group_entries.append(new Scene_group_item("new group")); @@ -67,7 +66,7 @@ Scene::addItem(Scene_item* item) list<setEditable(false); } - viewItem->appendRow(list); + invisibleRootItem()->appendRow(list); for(int i=0; i<5; i++){ index_map[list.at(i)->index()] = m_entries.size() -1; } @@ -138,6 +137,60 @@ Scene::erase(int index) return -1; } + +int +Scene::erase(QList indices) +{ + clear(); + index_map.clear(); + QList to_be_removed; + int max_index = -1; + Q_FOREACH(int index, indices) { + if(index < 0 || index >= m_entries.size()) + continue; + + max_index = (std::max)(max_index, index); + + Scene_item* item = m_entries[index]; + to_be_removed.push_back(item); + } + + Q_FOREACH(Scene_item* item, to_be_removed) { + Scene_group_item* group = + qobject_cast(item); + if(group) + { + m_group_entries.removeAll(group); + } + Q_FOREACH(Scene_group_item* group_item, m_group_entries) + if(group_item->getChildren().contains(item)) + group_item->removeChild(item); + Q_EMIT itemAboutToBeDestroyed(item); + delete item; + m_entries.removeAll(item); + } + check_first_group(); + selected_item = -1; + Q_FOREACH(Scene_item* item, m_entries) + { + organize_items(item, invisibleRootItem(), 0); + } + QStandardItemModel::beginResetModel(); + Q_EMIT updated(); + QStandardItemModel::endResetModel(); + + int index = max_index + 1 - indices.size(); + if(index >= m_entries.size()) { + index = m_entries.size() - 1; + } + if(index >= 0) + return index; + if(!m_entries.isEmpty()) + return 0; + return -1; + +} + void Scene::check_empty_group(Scene_item* item) { Q_FOREACH(Scene_group_item* group, m_group_entries) @@ -156,62 +209,6 @@ void Scene::check_empty_group(Scene_item* item) check_first_group(); Q_EMIT restoreCollapsedState(); } - -int -Scene::erase(QList indices) -{ - clear(); - index_map.clear(); - QList to_be_removed; - viewItem = invisibleRootItem(); - int max_index = -1; - Q_FOREACH(int index, indices) { - if(index < 0 || index >= m_entries.size()) - continue; - - max_index = (std::max)(max_index, index); - - Scene_item* item = m_entries[index]; - to_be_removed.push_back(item); - } - - Q_FOREACH(Scene_item* item, to_be_removed) { - Scene_group_item* group = - qobject_cast(item); - if(group) - { - QList to_erase; - Q_FOREACH(Scene_item* child, group->getChildren()) - to_erase<= m_entries.size()) { - index = m_entries.size() - 1; - } - if(index >= 0) - return index; - if(!m_entries.isEmpty()) - return 0; - return -1; - -} - Scene::~Scene() { Q_FOREACH(Scene_item* item_ptr, m_entries) @@ -675,7 +672,7 @@ bool Scene::dropMimeData(const QMimeData *data, Q_FOREACH(Scene_item* child, group->getChildren()) groups_children << item_id(child); } - // Insure thhat children of selected groups will not be added twice + // Insure that children of selected groups will not be added twice Q_FOREACH(int i, selected_items_list) { if(!groups_children.contains(i)) @@ -684,8 +681,16 @@ bool Scene::dropMimeData(const QMimeData *data, //Gets the group at the drop position Scene_group_item* group = qobject_cast(this->item(index_map[parent])); - //if the drop item is not a group_item, then the drop action must be ignored - if(!group) + bool one_contained = false; + Q_FOREACH(int id, selected_items_list) + if(group->getChildren().contains(item(id))) + { + one_contained = true; + break; + } + + //if the drop item is not a group_item or if it already con, then the drop action must be ignored + if(!group ||one_contained) { //unless the drop zone is empty, which means the item should be removed from all groups. if(!parent.isValid()) @@ -990,11 +995,10 @@ void Scene::group_added() //clears the model clear(); index_map.clear(); - viewItem = invisibleRootItem(); //fills the model Q_FOREACH(Scene_item* item, m_entries) { - organize_items(item, viewItem, 0); + organize_items(item, invisibleRootItem(), 0); } } void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) @@ -1063,6 +1067,16 @@ void Scene::setCollapsed(QModelIndex id) if(group) group->setExpanded(false); } + +int Scene::getIdFromModelIndex(QModelIndex modelId)const +{ + return index_map.value(modelId); +} + +QList Scene::getModelIndexFromId(int id) const +{ + return index_map.keys(id); +} namespace scene { namespace details { Q_DECL_EXPORT diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index df428249869..a22c6bbf023 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -35,7 +35,8 @@ class SCENE_EXPORT Scene : friend class SceneDelegate; public: - QMap index_map; + QList getModelIndexFromId(int id) const; + int getIdFromModelIndex(QModelIndex modelId) const; enum Columns { NameColumn = 0, ColorColumn, RenderingModeColumn, @@ -184,17 +185,12 @@ Q_SIGNALS: private Q_SLOTS: void setExpanded(QModelIndex); void setCollapsed(QModelIndex); - void test_rows() - { - } void setSelectionRay(double, double, double, double, double, double); void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} private: void draw_aux(bool with_names, Viewer_interface*); void organize_items(Scene_item* item, QStandardItem *root, int loop); - //Temp member, used only for dev purpose for now. - QStandardItem* viewItem; typedef QList Entries; Entries m_entries; QList m_group_entries; @@ -204,6 +200,7 @@ private: int item_B; static GlSplat::SplatRenderer* ms_splatting; static int ms_splattingCounter; + QMap index_map; public: static GlSplat::SplatRenderer* splatting(); @@ -244,8 +241,3 @@ private: #endif // SCENE_H -/*TO DO -virer viewItem -arranger les choses pour remettre index_map en private. -virer test_rows - */ diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index e845f752382..c2ea71f333f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -7,7 +7,7 @@ Scene_group_item::Scene_group_item(QString name) : Scene_item(0,0) { this->name_ = name; - expanded = false; + expanded = true; } bool Scene_group_item::isFinite() const From f1c3a3f51d94ac00f48d7d1c92d80bf89d42c22c Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 16 Nov 2015 11:20:02 +0100 Subject: [PATCH 16/22] collapsing problems fix + clean-up --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 1 - .../Polyhedron/Polyhedron_demo_group_plugin.h | 2 +- Polyhedron/demo/Polyhedron/Scene.cpp | 21 ++++++------------- Polyhedron/demo/Polyhedron/Scene.h | 2 +- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index dccd431e811..5c302479983 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1077,7 +1077,6 @@ void MainWindow::selectSceneItem(int i) sceneView->selectionModel()->select(s, QItemSelectionModel::ClearAndSelect); } - restoreCollapseState(); } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 2c9137811d0..12c70049654 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -95,7 +95,7 @@ public : if(selected_group->getChildren().contains(item)) { //selected_group->removeChild(item); - trueScene->check_empty_group(item); + trueScene->remove_item_from_groups(item); item->has_group = 0; } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 5ea561b13d2..61d0ebbedcc 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -59,7 +59,6 @@ Scene::addItem(Scene_item* item) this, SLOT(callDraw())); if(bbox_before + item->bbox() != bbox_before) { Q_EMIT updated_bbox(); } - QStandardItemModel::beginResetModel(); QList list; for(int i=0; i<5; i++) { @@ -70,9 +69,8 @@ Scene::addItem(Scene_item* item) for(int i=0; i<5; i++){ index_map[list.at(i)->index()] = m_entries.size() -1; } - Q_EMIT restoreCollapsedState(); Q_EMIT updated(); - QStandardItemModel::endResetModel(); + Q_EMIT restoreCollapsedState(); Item_id id = m_entries.size() - 1; Q_EMIT newItem(id); return id; @@ -130,6 +128,7 @@ Scene::erase(int index) QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); + Q_EMIT restoreCollapsedState(); if(--index >= 0) return index; if(!m_entries.isEmpty()) @@ -178,6 +177,7 @@ Scene::erase(QList indices) QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); + Q_EMIT restoreCollapsedState(); int index = max_index + 1 - indices.size(); if(index >= m_entries.size()) { @@ -191,19 +191,13 @@ Scene::erase(QList indices) } -void Scene::check_empty_group(Scene_item* item) +void Scene::remove_item_from_groups(Scene_item* item) { Q_FOREACH(Scene_group_item* group, m_group_entries) { if(group->getChildren().contains(item)) { group->removeChild(item); - if (group->getChildren().isEmpty()) - { - check_empty_group(group); - m_group_entries.removeOne(group); - m_entries.removeOne(group); - } } } check_first_group(); @@ -496,7 +490,7 @@ Scene::data(const QModelIndex &index, int role) const return QVariant(); } - int id = index_map[index];\ + int id = index_map[index]; if(id < 0 || id >= m_entries.size()) return QVariant(); if(role == ::Qt::ToolTipRole) @@ -972,8 +966,6 @@ QList Scene::item_entries() const void Scene::check_first_group() { - - if(m_group_entries.isEmpty() || m_group_entries.first()->name() != "new group") { m_group_entries.prepend(new Scene_group_item("new group")); @@ -1009,8 +1001,7 @@ void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) { if(group->getChildren().contains(item)) { - //group->removeChild(item); - check_empty_group(item); + remove_item_from_groups(item); break; } } diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index a22c6bbf023..4cba0c0a307 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -118,7 +118,7 @@ public: public Q_SLOTS: //!insures that the groupview and data always has a "new group" in first position. void check_first_group(); - void check_empty_group(Scene_item* item); + void remove_item_from_groups(Scene_item* item); void group_added(); // Notify the scene that an item was modified void itemChanged(); // slots called by items themself From 2722c76b3b725325550ef274cece5e48d45f94f1 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 16 Nov 2015 11:52:43 +0100 Subject: [PATCH 17/22] Segfault fix --- .../Polyhedron_demo_group_plugin.cpp | 98 +---------------- .../Polyhedron/Polyhedron_demo_group_plugin.h | 101 +----------------- Polyhedron/demo/Polyhedron/Scene.cpp | 38 ++----- Polyhedron/demo/Polyhedron/Scene.h | 3 - 4 files changed, 16 insertions(+), 224 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp index 8da6ae76d5f..d18390ae4ae 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp @@ -2,63 +2,6 @@ #include "Polyhedron_demo_group_plugin.moc" #include "Scene.h" -/********** - * Models * - **********/ - -QVariant GroupModel::data(const QModelIndex &index, int role) const -{ - if(index.row()<0 ) - return QVariant(); - - if(role != Qt::DisplayRole ) - return QVariant(); - - return groups()[index.row()]->name(); -} -Qt::ItemFlags -GroupModel::flags ( const QModelIndex & index ) const -{ - if (index.isValid() && index.row() == 0) { - return QAbstractListModel::flags(index) | ::Qt::ItemIsEditable; - } - else { - return QAbstractListModel::flags(index); - } - return 0; -} - -bool -GroupModel::setData(const QModelIndex &index, - const QVariant &value, - int role) -{ - - if( role != ::Qt::EditRole || !index.isValid() ) - return false; - - if(index.row() != 0) - return false; - - Scene_group_item* item = groups()[0]; - if(!item) return false; - data_pool->setGroupName(value.toString()); - Q_EMIT dataChanged(index, index); - return true; -} - -QVariant ItemsModel::data(const QModelIndex &index, int role) const -{ - - if(index.row()<0 || index.row() > items().size()) - return QVariant(); - - if(role != Qt::DisplayRole) - return QVariant(); - - return items()[index.row()]->name(); -} - /**************** * Group Plugin * ****************/ @@ -70,47 +13,10 @@ void Polyhedron_demo_group_plugin::init(QMainWindow* mainWindow, this->scene = scene_interface; this->mw = mainWindow; messages = m; - group_model = new GroupModel(trueScene); - items_model = new ItemsModel(trueScene); //creates and link the actions - actionAddToGroup= new QAction("Add to group", mw); + actionAddToGroup= new QAction("Add new group", mw); if(actionAddToGroup) { connect(actionAddToGroup, SIGNAL(triggered()), - this, SLOT(GroupChoice())); + this, SLOT(add_group())); } } - -void Polyhedron_demo_group_plugin::GroupChoice() -{ - Polyhedron_demo_group_plugin_dialog *dialog = new Polyhedron_demo_group_plugin_dialog(this); - dialog->show(); - -} -/**************** - * Dialog Class * - ****************/ - -Polyhedron_demo_group_plugin_dialog::Polyhedron_demo_group_plugin_dialog( Polyhedron_demo_group_plugin *p_plugin) -{ - m_plugin= p_plugin; - setupUi(this); - itemsView->setModel(m_plugin->items_model); - itemsView->setSelectionMode(QAbstractItemView::ExtendedSelection); - groupsView->setModel(m_plugin->group_model); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(selected_scene_items())); - connect(buttonBox, SIGNAL(accepted()), m_plugin->trueScene, SLOT(group_added())); - -} - -void Polyhedron_demo_group_plugin_dialog::selected_scene_items() -{ - QModelIndexList selectedRows = itemsView->selectionModel()->selectedIndexes(); - QModelIndex selectedGroup= groupsView->selectionModel()->selectedIndexes().first(); - Q_FOREACH(QModelIndex index, selectedRows) - { - m_plugin->selected_items << m_plugin->items_model->items()[index.row()]; - } - m_plugin->selected_group = m_plugin->group_model->groups()[selectedGroup.row()]; - m_plugin->add_to_group(); - -} diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 12c70049654..e5504ea7cb8 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -4,67 +4,11 @@ #include #include #include -#include #include "Scene_group_item.h" #include "CGAL_demo/Scene_interface.h" -#include "ui_Polyhedron_demo_group_plugin.h" #include "Scene.h" class Scene_interface; - -class GroupModel : public QAbstractListModel -{ - -public: - GroupModel(Scene* scene) - { - data_pool = scene; - } - - QVariant data(const QModelIndex &index, int role) const; - int rowCount(const QModelIndex &parent) const - { - Q_UNUSED (parent); - return data_pool->group_entries().size(); - } - QList groups() const - { - return data_pool->group_entries(); - } - - Qt::ItemFlags flags (const QModelIndex &index) const; - bool setData(const QModelIndex &index, const QVariant &value, int role); - -private: - Scene* data_pool; -}; - -class ItemsModel : public QAbstractListModel -{ -public: - ItemsModel(Scene* scene) - { - data_pool = scene; - } - - QVariant data(const QModelIndex &index, int role) const; - - int rowCount(const QModelIndex &parent = QModelIndex()) const - { - Q_UNUSED(parent); - return data_pool->item_entries().size(); - } - - QList items() const - { - return data_pool->item_entries(); - } -private: - Scene* data_pool; - -}; - - #include "Polyhedron_demo_plugin_helper.h" class Polyhedron_demo_group_plugin : public QObject, @@ -82,40 +26,17 @@ public : bool applicable(QAction*) const { - return scene->numberOfEntries() > 0; + return true; } QList actions() const { return QList() << actionAddToGroup; } - GroupModel *group_model; - ItemsModel *items_model; - void add_to_group() { - Q_FOREACH(Scene_item* item, selected_items) - { - if(selected_group->getChildren().contains(item)) - { - //selected_group->removeChild(item); - trueScene->remove_item_from_groups(item); - item->has_group = 0; - - } - else if(selected_group == item) - print_message("A group cannot contain itself."); - else - { - trueScene->changeGroup(item, selected_group); - - if(!trueScene->item_entries().contains(selected_group)) - scene->addItem(selected_group); - } - } - selected_items.clear(); - } - QList selected_items; - Scene_group_item* selected_group; Scene* trueScene; public Q_SLOTS: - void GroupChoice(); + void add_group() { + scene->addItem(new Scene_group_item("new group")); + trueScene->group_added(); + } private: @@ -124,16 +45,4 @@ private: Messages_interface* messages; }; //end of class Polyhedron_demo_group_plugin - -class Polyhedron_demo_group_plugin_dialog : public QDialog, private Ui::GroupDialog -{ - Q_OBJECT -public: - Polyhedron_demo_group_plugin_dialog(Polyhedron_demo_group_plugin *p_plugin); - -public Q_SLOTS: - void selected_scene_items(); -private : - Polyhedron_demo_group_plugin * m_plugin; -}; #endif diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 61d0ebbedcc..8c30c267c07 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -45,12 +45,14 @@ Scene::Scene(QObject* parent) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; - m_group_entries.append(new Scene_group_item("new group")); - } Scene::Item_id Scene::addItem(Scene_item* item) { + Scene_group_item* group = + qobject_cast(item); + if(group) + m_group_entries.prepend(group); Bbox bbox_before = bbox(); m_entries.push_back(item); connect(item, SIGNAL(itemChanged()), @@ -116,7 +118,6 @@ Scene::erase(int index) { m_group_entries.removeOne(group); m_entries.removeOne(group); - check_first_group(); } } @@ -168,7 +169,6 @@ Scene::erase(QList indices) delete item; m_entries.removeAll(item); } - check_first_group(); selected_item = -1; Q_FOREACH(Scene_item* item, m_entries) { @@ -200,7 +200,6 @@ void Scene::remove_item_from_groups(Scene_item* item) group->removeChild(item); } } - check_first_group(); Q_EMIT restoreCollapsedState(); } Scene::~Scene() @@ -612,7 +611,6 @@ Scene::setData(const QModelIndex &index, { case NameColumn: item->setName(value.toString()); - check_first_group(); Q_EMIT dataChanged(index, index); return true; break; @@ -676,13 +674,15 @@ bool Scene::dropMimeData(const QMimeData *data, Scene_group_item* group = qobject_cast(this->item(index_map[parent])); bool one_contained = false; + if(group) + { Q_FOREACH(int id, selected_items_list) if(group->getChildren().contains(item(id))) { one_contained = true; break; } - + } //if the drop item is not a group_item or if it already con, then the drop action must be ignored if(!group ||one_contained) { @@ -963,25 +963,8 @@ QList Scene::item_entries() const { return m_entries; } - -void Scene::check_first_group() -{ - if(m_group_entries.isEmpty() || m_group_entries.first()->name() != "new group") - { - m_group_entries.prepend(new Scene_group_item("new group")); - } -} void Scene::group_added() { - Q_FOREACH(Scene_group_item *group, m_group_entries) - { - if (group->getChildren().isEmpty()) - { - m_group_entries.removeOne(group); - m_entries.removeOne(group); - } - } - check_first_group(); //makes the hierarchy in the tree //clears the model @@ -990,7 +973,7 @@ void Scene::group_added() //fills the model Q_FOREACH(Scene_item* item, m_entries) { - organize_items(item, invisibleRootItem(), 0); + organize_items(item, invisibleRootItem(), 0); } } void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) @@ -1009,10 +992,7 @@ void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) target_group->addChild(item); item->has_group = target_group->has_group +1; } -void Scene::setGroupName(QString name) -{ - m_group_entries[0]->setName(name); -} + #include "Scene_find_items.h" void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop) diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 4cba0c0a307..3853a2ea643 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -113,11 +113,8 @@ public: // auxiliary public function for QMainWindow QItemSelection createSelection(int i); QItemSelection createSelectionAll(); - void setGroupName(QString name); public Q_SLOTS: - //!insures that the groupview and data always has a "new group" in first position. - void check_first_group(); void remove_item_from_groups(Scene_item* item); void group_added(); // Notify the scene that an item was modified From 62489af1b126c1f01cea50d79d9c1bbc22cb69ee Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 17 Nov 2015 11:45:23 +0100 Subject: [PATCH 18/22] Addition of a new feature - If one or several items are selected when a new group is created, they are automatically added to the group. - If all the selected items are in the same group at this time, the new group is created as a sub-group of this container group. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 +- Polyhedron/demo/Polyhedron/MainWindow.h | 2 +- .../Polyhedron/Polyhedron_demo_group_plugin.h | 55 ++++++++++++++++++- Polyhedron/demo/Polyhedron/Scene.cpp | 11 ++-- Polyhedron/demo/Polyhedron/Scene.h | 2 +- Polyhedron/demo/Polyhedron/Viewer.cpp | 5 +- 6 files changed, 64 insertions(+), 13 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 3b8c43be578..1e8295d2c12 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1550,7 +1550,7 @@ void MainWindow::on_actionRecenterScene_triggered() viewer->camera()->interpolateToFitScene(); } -QModelIndex MainWindow::recurseExpand(QModelIndex index) +void MainWindow::recurseExpand(QModelIndex index) { if(index.child(0,0).isValid()) recurseExpand(index.child(0,0)); diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h index a8749576b6a..78e81540c15 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.h +++ b/Polyhedron/demo/Polyhedron/MainWindow.h @@ -328,7 +328,7 @@ protected: QList getSelectedSceneItemIndices() const; private: - QModelIndex recurseExpand(QModelIndex index); + void recurseExpand(QModelIndex index); QString strippedName(const QString &fullFileName); void setMenus(QString, QString, QAction *a); /// plugin black-list diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 3b76c6a5960..1fd18927303 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -34,8 +34,59 @@ public : Scene* trueScene; public Q_SLOTS: void add_group() { - scene->addItem(new Scene_group_item("new group")); - trueScene->group_added(); + //checks if all the selected items are in the same group + bool all_in_one = true; + if(trueScene->selectionIndices().isEmpty()) + all_in_one = false; + // new group to create + Scene_group_item * group = new Scene_group_item("new group"); + //group containing the selected item + Scene_group_item * existing_group = 0; + //for each selected item + Q_FOREACH(int id, trueScene->selectionIndices()){ + //if the selected item is in a group + if(trueScene->item(id)->has_group!=0){ + //for each group + Q_FOREACH(Scene_group_item *item, trueScene->group_entries()) + { + //if the group contains the selected item + if(item->getChildren().contains(trueScene->item(id))){ + //if it is the first one, we initialize existing_group + if(existing_group == 0) + existing_group = item; + //else we check if it is the same group as before. + //If not, all selected items are not in the same group + else if(existing_group != item) + all_in_one = false; + break; + } + }//end for each group + } + //else it is impossible that all the selected items are in the same group + else{ + all_in_one = false; + break; + } + }//end foreach selected item + + //If all the selected items are in the same group, we put them in a sub_group of this group + if(all_in_one) + { + Q_FOREACH(int id, trueScene->selectionIndices()) + trueScene->changeGroup(trueScene->item(id),group); + trueScene->changeGroup(group, existing_group); + scene->addItem(group); + trueScene->group_added(); + } + //else wer create a new group + else + { + Q_FOREACH(int id, trueScene->selectionIndices()) + trueScene->changeGroup(trueScene->item(id),group); + scene->addItem(group); + trueScene->group_added(); + } + } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 0aacbdd4f9e..27c877abe07 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -158,7 +158,8 @@ Scene::erase(QList indices) max_index = (std::max)(max_index, index); Scene_item* item = m_entries[index]; - to_be_removed.push_back(item); + if(!to_be_removed.contains(item)) + to_be_removed.push_back(item); } Q_FOREACH(Scene_item* item, to_be_removed) { @@ -651,10 +652,10 @@ Scene::setData(const QModelIndex &index, return false; } -bool Scene::dropMimeData(const QMimeData *data, - Qt::DropAction action, - int row, - int column, +bool Scene::dropMimeData(const QMimeData */*data*/, + Qt::DropAction /*action*/, + int /*row*/, + int /*column*/, const QModelIndex &parent) { //gets the moving items diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 38d79cd2a3e..c46338b2791 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -137,7 +137,7 @@ public: // QStandardItemModel functions - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); + bool dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &parent); QVariant data ( const QModelIndex & index, int role = ::Qt::DisplayRole ) const; //!@returns the type of data correspondind to the role. QVariant headerData ( int section, ::Qt::Orientation orientation, int role = ::Qt::DisplayRole ) const; diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index 8e818f7f2e4..6785ea1b03a 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -335,8 +335,7 @@ void Viewer::drawWithNames() void Viewer::postSelection(const QPoint& pixel) { - qDebug()<<"postSelection"; - /* bool found = false; + bool found = false; qglviewer::Vec point = camera()->pointUnderPixel(pixel, found); if(found) { Q_EMIT selectedPoint(point.x, @@ -347,7 +346,7 @@ void Viewer::postSelection(const QPoint& pixel) const qglviewer::Vec dir = point - orig; Q_EMIT selectionRay(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); - }*/ + } } bool CGAL::Three::Viewer_interface::readFrame(QString s, qglviewer::Frame& frame) { From 08db015daf7095c14e607d992cc32e5d58276cda Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Tue, 17 Nov 2015 15:27:57 +0100 Subject: [PATCH 19/22] un-comment a function that shounldn't be commented. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 30 +++++++++++++--- .../Polyhedron_demo_group_plugin.cpp | 34 +++++++++++++++++-- .../Polyhedron/Polyhedron_demo_group_plugin.h | 25 ++++++++++---- Polyhedron/demo/Polyhedron/Scene.cpp | 2 +- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 1e8295d2c12..483d47e5f47 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1135,10 +1135,24 @@ void MainWindow::showSceneContextMenu(const QPoint& p) { int index = -1; if(sender == sceneView) { - QModelIndex modelIndex = sceneView->indexAt(p); - if(!modelIndex.isValid()) return; + QModelIndex modelIndex = sceneView->indexAt(p); + if(!modelIndex.isValid()) + { + const char* prop_name = "Menu modified by MainWindow."; - index = proxyModel->mapToSource(modelIndex).row(); + QMenu* menu = ui->menuFile; + if(menu) { + bool menuChanged = menu->property(prop_name).toBool(); + if(!menuChanged) { + menu->setProperty(prop_name, true); + } + } + if(menu) + menu->exec(sender->mapToGlobal(p)); + return; + } + else + index = proxyModel->mapToSource(modelIndex).row(); } else { index = scene->mainSelectionIndex(); @@ -1552,17 +1566,23 @@ void MainWindow::on_actionRecenterScene_triggered() void MainWindow::recurseExpand(QModelIndex index) { - if(index.child(0,0).isValid()) - recurseExpand(index.child(0,0)); + //qDebug()<index(index.row(),0,index.sibling(row+1, column)); Scene_group_item* group = qobject_cast(scene->item(scene->getIdFromModelIndex(id))); + if(group && group->isExpanded()) { + // qDebug()<name(); sceneView->setExpanded(index, true); } + else if (group && !group->isExpanded()){ + sceneView->setExpanded(index, false); + } if( index.sibling(index.row()+1,0).isValid()) recurseExpand(index.sibling(index.row()+1,0)); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp index aa6b0d85760..b21178da2ed 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.cpp @@ -1,7 +1,7 @@ #include "Polyhedron_demo_group_plugin.h" #include "Polyhedron_demo_group_plugin.moc" #include "Scene.h" - +#include /**************** * Group Plugin * ****************/ @@ -15,8 +15,36 @@ void Polyhedron_demo_group_plugin::init(QMainWindow* mainWindow, messages = m; //creates and link the actions actionAddToGroup= new QAction("Add new group", mw); + if(actionAddToGroup) { - connect(actionAddToGroup, SIGNAL(triggered()), - this, SLOT(add_group())); + connect(actionAddToGroup, SIGNAL(triggered()), + this, SLOT(add_group())); + } + + QMenu* menuFile = mw->findChild("menuFile"); + if ( NULL != menuFile ) + { + QList menuFileActions = menuFile->actions(); + + // Look for action just after "Load..." action + QAction* actionAfterLoad = NULL; + for ( QList::iterator it_action = menuFileActions.begin(), + end = menuFileActions.end() ; it_action != end ; ++ it_action ) //Q_FOREACH( QAction* action, menuFileActions) + { + if ( NULL != *it_action && (*it_action)->text().contains("Load") ) + { + ++it_action; + if ( it_action != end && NULL != *it_action ) + { + actionAfterLoad = *it_action; + } + } + } + + // Insert "Load implicit function" action + if ( NULL != actionAfterLoad ) + { + menuFile->insertAction(actionAfterLoad,actionAddToGroup); + } } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h index 1fd18927303..6feb8e22ca4 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_group_plugin.h @@ -28,22 +28,33 @@ public : { return true; } - QList actions() const { - return QList() << actionAddToGroup; - } + Scene* trueScene; public Q_SLOTS: void add_group() { + //Find the indices of the selected items + QList indices; + QList blacklist; + Q_FOREACH(int id, scene->selectionIndices()){ + Scene_group_item* group = + qobject_cast(trueScene->item(id)); + if(group) + Q_FOREACH(Scene_item *item, group->getChildren()) + blacklist<item_id(item); + + if(!indices.contains(id) && !blacklist.contains(id)) + indices<selectionIndices().isEmpty()) + if(indices.isEmpty()) all_in_one = false; // new group to create Scene_group_item * group = new Scene_group_item("new group"); //group containing the selected item Scene_group_item * existing_group = 0; //for each selected item - Q_FOREACH(int id, trueScene->selectionIndices()){ + Q_FOREACH(int id, indices){ //if the selected item is in a group if(trueScene->item(id)->has_group!=0){ //for each group @@ -72,7 +83,7 @@ public Q_SLOTS: //If all the selected items are in the same group, we put them in a sub_group of this group if(all_in_one) { - Q_FOREACH(int id, trueScene->selectionIndices()) + Q_FOREACH(int id, indices) trueScene->changeGroup(trueScene->item(id),group); trueScene->changeGroup(group, existing_group); scene->addItem(group); @@ -81,7 +92,7 @@ public Q_SLOTS: //else wer create a new group else { - Q_FOREACH(int id, trueScene->selectionIndices()) + Q_FOREACH(int id, indices) trueScene->changeGroup(trueScene->item(id),group); scene->addItem(group); trueScene->group_added(); diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 27c877abe07..9107596c7dc 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -690,7 +690,7 @@ bool Scene::dropMimeData(const QMimeData */*data*/, break; } } - //if the drop item is not a group_item or if it already con, then the drop action must be ignored + //if the drop item is not a group_item or if it already contains the item, then the drop action must be ignored if(!group ||one_contained) { //unless the drop zone is empty, which means the item should be removed from all groups. From 0af72ecf93e941ff16728f465288ef82d874ce39 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Nov 2015 14:50:34 +0100 Subject: [PATCH 20/22] Inopportune collapsing fix - The model used by scene view is proxyModel and not scene, so all the indexes I used were invalid. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 26 ++++++++++++----------- Polyhedron/demo/Polyhedron/Scene.cpp | 13 ++++++------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 483d47e5f47..fed809d8c65 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1096,7 +1096,7 @@ void MainWindow::contextMenuRequested(const QPoint& global_pos) { void MainWindow::showSceneContextMenu(int selectedItemIndex, const QPoint& global_pos) { - Scene_item* item = scene->item(scene->getIdFromModelIndex(scene->index(selectedItemIndex,0))); + Scene_item* item = scene->item(scene->getIdFromModelIndex(scene->index(selectedItemIndex,0,QModelIndex()))); if(!item) return; const char* prop_name = "Menu modified by MainWindow."; @@ -1566,29 +1566,31 @@ void MainWindow::on_actionRecenterScene_triggered() void MainWindow::recurseExpand(QModelIndex index) { - //qDebug()<index(index.row(),0,index.sibling(row+1, column)); + } + + QString name = scene->item(scene->getIdFromModelIndex(index))->name(); Scene_group_item* group = - qobject_cast(scene->item(scene->getIdFromModelIndex(id))); + qobject_cast(scene->item(scene->getIdFromModelIndex(index))); if(group && group->isExpanded()) { - // qDebug()<name(); - sceneView->setExpanded(index, true); + sceneView->setExpanded(proxyModel->mapFromSource(index), true); } else if (group && !group->isExpanded()){ - sceneView->setExpanded(index, false); + sceneView->setExpanded(proxyModel->mapFromSource(index), false); } - if( index.sibling(index.row()+1,0).isValid()) - recurseExpand(index.sibling(index.row()+1,0)); + + if( index.sibling(row+1,0).isValid()) + recurseExpand(index.sibling(row+1,0)); } void MainWindow::restoreCollapseState() { - QModelIndex modelIndex = sceneView->indexAt(sceneView->rect().topLeft()); - recurseExpand(modelIndex); + QModelIndex modelIndex = scene->index(0,0,scene->invisibleRootItem()->index()); + if(modelIndex.isValid()) + recurseExpand(modelIndex); } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 9107596c7dc..3c8b89f405e 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -45,11 +45,11 @@ Scene::Scene(QObject* parent) ms_splatting = new GlSplat::SplatRenderer(); ms_splattingCounter++; + } Scene::Item_id Scene::addItem(Scene_item* item) { - Scene_group_item* group = qobject_cast(item); if(group) @@ -78,7 +78,6 @@ Scene::addItem(Scene_item* item) index_map[list.at(i)->index()] = m_entries.size() -1; } Q_EMIT updated(); - Q_EMIT restoreCollapsedState(); Item_id id = m_entries.size() - 1; Q_EMIT newItem(id); return id; @@ -135,7 +134,6 @@ Scene::erase(int index) QStandardItemModel::beginResetModel(); Q_EMIT updated(); QStandardItemModel::endResetModel(); - Q_EMIT restoreCollapsedState(); if(--index >= 0) return index; if(!m_entries.isEmpty()) @@ -207,7 +205,6 @@ void Scene::remove_item_from_groups(Scene_item* item) group->removeChild(item); } } - Q_EMIT restoreCollapsedState(); } Scene::~Scene() { @@ -762,7 +759,7 @@ void Scene::itemChanged(Item_id i) Q_EMIT dataChanged(this->createIndex(i, 0), this->createIndex(i, LastColumn)); - Q_EMIT restoreCollapsedState(); + // Q_EMIT restoreCollapsedState(); } void Scene::itemChanged(Scene_item* /* item */) @@ -973,7 +970,7 @@ QList Scene::item_entries() const void Scene::group_added() { -//makes the hierarchy in the tree + //makes the hierarchy in the tree //clears the model clear(); index_map.clear(); @@ -982,6 +979,7 @@ void Scene::group_added() { organize_items(item, invisibleRootItem(), 0); } + Q_EMIT restoreCollapsedState(); } void Scene::changeGroup(Scene_item *item, Scene_group_item *target_group) { @@ -1017,6 +1015,7 @@ void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop) { list<setEditable(false); + } root->appendRow(list); for(int i=0; i<5; i++){ @@ -1032,7 +1031,6 @@ void Scene::organize_items(Scene_item* item, QStandardItem* root, int loop) } } } - Q_EMIT restoreCollapsedState(); } void Scene::setExpanded(QModelIndex id) @@ -1061,6 +1059,7 @@ QList Scene::getModelIndexFromId(int id) const { return index_map.keys(id); } + namespace scene { namespace details { Q_DECL_EXPORT From e8ad03047452ee7527d11cdec1d41d80526e4504 Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Fri, 20 Nov 2015 16:00:01 +0100 Subject: [PATCH 21/22] Freeze fix - The BBox calculation of a group was taking forever because it had to compute it for each of it children, which made everything freeze if there was a lot of sub-groups. Now a group has an empty BBox(). --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 4 ++-- Polyhedron/demo/Polyhedron/Scene.cpp | 2 -- Polyhedron/demo/Polyhedron/Scene.h | 4 ++-- Polyhedron/demo/Polyhedron/Scene_group_item.cpp | 17 ++--------------- Polyhedron/demo/Polyhedron/Scene_group_item.h | 2 +- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index fed809d8c65..5d0d8e5e4a8 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -116,7 +116,6 @@ MainWindow::~MainWindow() { delete ui; } - MainWindow::MainWindow(QWidget* parent) : CGAL::Qt::DemosMainWindow(parent) { @@ -1171,6 +1170,7 @@ void MainWindow::removeManipulatedFrame(Scene_item* item) void MainWindow::updateInfo() { Scene_item* item = scene->item(getSelectedSceneItemIndex()); + if(item) { QString item_text = item->toolTip(); QString item_filename = item->property("source filename").toString(); @@ -1188,7 +1188,7 @@ void MainWindow::updateInfo() { } ui->infoLabel->setText(item_text); } - else + else ui->infoLabel->clear(); } diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp index 3c8b89f405e..3b1b396b2de 100644 --- a/Polyhedron/demo/Polyhedron/Scene.cpp +++ b/Polyhedron/demo/Polyhedron/Scene.cpp @@ -20,7 +20,6 @@ #include - GlSplat::SplatRenderer* Scene::ms_splatting = 0; int Scene::ms_splattingCounter = 0; GlSplat::SplatRenderer* Scene::splatting() @@ -969,7 +968,6 @@ QList Scene::item_entries() const } void Scene::group_added() { - //makes the hierarchy in the tree //clears the model clear(); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index c46338b2791..08a06c16b05 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -201,7 +201,7 @@ public Q_SLOTS: //! Sets the target list of indices as the selected indices. QList setSelectedItemsList(QList l ) { - Q_FOREACH(int i,l) + /*Q_FOREACH(int i,l) { Scene_group_item* group = qobject_cast(item(i)); @@ -213,7 +213,7 @@ public Q_SLOTS: l << setSelectedItemsList(list); } - } + }*/ selected_items_list = l; return l; } diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp index 07a85e3e87c..5c54247a5c5 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.cpp @@ -22,27 +22,14 @@ bool Scene_group_item::isFinite() const bool Scene_group_item::isEmpty() const { Q_FOREACH(Scene_item *item, children) if(!item->isEmpty()){ - return false; + return true; } return true; } Scene_group_item::Bbox Scene_group_item::bbox() const { - double xmax=0, ymax=0, zmax=0; - double xmin=0, ymin=0, zmin=0; - if(!children.isEmpty()) - { - xmax = children.first()->bbox().xmax; ymax = children.first()->bbox().ymax; zmax = children.first()->bbox().zmax; - xmin = children.first()->bbox().xmin; ymin = children.first()->bbox().ymin; zmin = children.first()->bbox().zmin; - } - - Q_FOREACH(Scene_item* item, children) - { - xmax = std::max(xmax,item->bbox().xmax); ymax = std::max(ymax, item->bbox().ymax); zmax = std::max(zmax, item->bbox().zmax); - xmin = std::min(xmin, item->bbox().xmin); ymin = std::min(ymin,item->bbox().ymin); zmin = std::min(zmin,item->bbox().zmin); - } - return Bbox(xmin, ymin, zmin, xmax, ymax, zmax); + return Bbox(0, 0, 0, 0, 0,0); } diff --git a/Polyhedron/demo/Polyhedron/Scene_group_item.h b/Polyhedron/demo/Polyhedron/Scene_group_item.h index ec8fae2a28b..59b40719066 100644 --- a/Polyhedron/demo/Polyhedron/Scene_group_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_group_item.h @@ -77,7 +77,7 @@ public : if(group) Q_FOREACH(Scene_item* child, group->getChildren()) removeChild(child); - item->has_group--; + item->has_group=0; children.removeOne(item); } From ce3b4985b088b91329e489a51bc67c700cd44eee Mon Sep 17 00:00:00 2001 From: Maxime Gimeno Date: Mon, 23 Nov 2015 09:10:50 +0100 Subject: [PATCH 22/22] Segfault fix - The group selection has been restored. --- Polyhedron/demo/Polyhedron/MainWindow.cpp | 2 -- Polyhedron/demo/Polyhedron/Scene.h | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 5d0d8e5e4a8..f608382466e 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -237,8 +237,6 @@ MainWindow::MainWindow(QWidget* parent) // connect(ui->infoLabel, SIGNAL(customContextMenuRequested(const QPoint & )), // this, SLOT(showSceneContextMenu(const QPoint &))); - connect(scene, SIGNAL(updated()), - scene, SLOT(test_rows())); connect(ui->actionRecenterScene, SIGNAL(triggered()), viewer, SLOT(update())); diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 08a06c16b05..c46338b2791 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -201,7 +201,7 @@ public Q_SLOTS: //! Sets the target list of indices as the selected indices. QList setSelectedItemsList(QList l ) { - /*Q_FOREACH(int i,l) + Q_FOREACH(int i,l) { Scene_group_item* group = qobject_cast(item(i)); @@ -213,7 +213,7 @@ public Q_SLOTS: l << setSelectedItemsList(list); } - }*/ + } selected_items_list = l; return l; }