From d2d2467101076bef512bacfff8fab01d38ebcd58 Mon Sep 17 00:00:00 2001 From: mfreiholz Date: Mon, 14 Mar 2016 15:12:34 +0100 Subject: [PATCH] Adds possibility to remove section contents. --- .astylerc | 14 +++ .../include/ads/ContainerWidget.h | 13 +++ .../include/ads/SectionContent.h | 3 + AdvancedDockingSystem/src/ContainerWidget.cpp | 56 ++++++++++++ .../src/SectionContentWidget.cpp | 1 + .../src/SectionTitleWidget.cpp | 1 + .../AdvancedDockingSystemDemo.pro | 11 ++- .../src/dialogs/SectionContentListModel.cpp | 85 +++++++++++++++++++ .../src/dialogs/SectionContentListModel.h | 47 ++++++++++ .../src/dialogs/SectionContentListWidget.cpp | 38 +++++++++ .../src/dialogs/SectionContentListWidget.h | 33 +++++++ .../src/dialogs/SectionContentListWidget.ui | 61 +++++++++++++ AdvancedDockingSystemDemo/src/mainwindow.cpp | 15 ++++ AdvancedDockingSystemDemo/src/mainwindow.h | 3 + AdvancedDockingSystemDemo/src/mainwindow.ui | 6 +- 15 files changed, 381 insertions(+), 6 deletions(-) create mode 100644 .astylerc create mode 100644 AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.cpp create mode 100644 AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.h create mode 100644 AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.cpp create mode 100644 AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.h create mode 100644 AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.ui diff --git a/.astylerc b/.astylerc new file mode 100644 index 0000000..6fb629c --- /dev/null +++ b/.astylerc @@ -0,0 +1,14 @@ +--style=allman + +--indent=force-tab=4 + +--align-pointer=type +--align-reference=type + +--pad-oper +--pad-header +--unpad-paren + +--remove-comment-prefix + +--mode=c diff --git a/AdvancedDockingSystem/include/ads/ContainerWidget.h b/AdvancedDockingSystem/include/ads/ContainerWidget.h index 36c0b56..da6852a 100644 --- a/AdvancedDockingSystem/include/ads/ContainerWidget.h +++ b/AdvancedDockingSystem/include/ads/ContainerWidget.h @@ -54,6 +54,13 @@ public: */ SectionWidget* addSectionContent(const SectionContent::RefPtr& sc, SectionWidget* sw = NULL, DropArea area = CenterDropArea); + /*! + * Completely removes the sc from this ContainerWidget. + * This container will no longer hold a reference to the content. + * The content can be safely deleted. + */ + bool removeSectionContent(const SectionContent::RefPtr& sc); + /*! * Shows the specific SectionContent in UI. * Independed of the current state, whether it is used inside a section or is floating. @@ -101,6 +108,12 @@ public: QRect outerBottomDropRect() const; QRect outerLeftDropRect() const; + /*! + * \brief contents + * \return List of known SectionContent for this ContainerWidget. + */ + QList contents() const; + private: // // Internal Stuff Begins Here diff --git a/AdvancedDockingSystem/include/ads/SectionContent.h b/AdvancedDockingSystem/include/ads/SectionContent.h index f101f71..8ae0bd0 100644 --- a/AdvancedDockingSystem/include/ads/SectionContent.h +++ b/AdvancedDockingSystem/include/ads/SectionContent.h @@ -57,6 +57,9 @@ private: // Optional attributes QString _title; + /* Note: This method could be a problem in static build environment + * since it may begin with 0 for every module which uses ADS. + */ static int GetNextUid(); }; diff --git a/AdvancedDockingSystem/src/ContainerWidget.cpp b/AdvancedDockingSystem/src/ContainerWidget.cpp index 7f232e9..db59160 100644 --- a/AdvancedDockingSystem/src/ContainerWidget.cpp +++ b/AdvancedDockingSystem/src/ContainerWidget.cpp @@ -106,6 +106,49 @@ SectionWidget* ContainerWidget::addSectionContent(const SectionContent::RefPtr& return dropContent(data, sw, area, false); } +bool ContainerWidget::removeSectionContent(const SectionContent::RefPtr& sc) +{ + // Hide the content. + // The hideSectionContent() automatically deletes no longer required SectionWidget objects. + if (!hideSectionContent(sc)) + return false; + + // Begin of ugly work arround. + // TODO The hideSectionContent() method should take care of deleting FloatingWidgets and SectionWidgets, + // but only cares about SectionWidgets right now. So we need to check whether it was a FloatingWidget + // and delete it. + bool found = false; + for (int i = 0; i < _floatings.count(); ++i) + { + FloatingWidget* fw = _floatings.at(i); + InternalContentData data; + if (!(found = fw->takeContent(data))) + continue; + _floatings.removeAll(fw); + delete fw; + delete data.titleWidget; + delete data.contentWidget; + break; + } // End of ugly work arround. + + // Get from hidden contents and delete associated internal stuff. + if (!_hiddenSectionContents.contains(sc->uid())) + { + qFatal("Something went wrong... The content should have been there :-/"); + return false; + } + + // Delete internal objects. + HiddenSectionItem hsi = _hiddenSectionContents.take(sc->uid()); + delete hsi.data.titleWidget; + delete hsi.data.contentWidget; + + // Hide the custom widgets of SectionContent. + // ... should we? ... + + return true; +} + bool ContainerWidget::showSectionContent(const SectionContent::RefPtr& sc) { // Search SC in floatings @@ -603,6 +646,19 @@ QRect ContainerWidget::outerLeftDropRect() const return QRect(r.left(), r.top(), w, r.height()); } +QList ContainerWidget::contents() const +{ + QList wl = _scLookupMapById.values(); + QList sl; + for (int i = 0; i < wl.count(); ++i) + { + const SectionContent::RefPtr sc = wl.at(i).toStrongRef(); + if (sc) + sl.append(sc); + } + return sl; +} + /////////////////////////////////////////////////////////////////////// // PRIVATE API BEGINS HERE /////////////////////////////////////////////////////////////////////// diff --git a/AdvancedDockingSystem/src/SectionContentWidget.cpp b/AdvancedDockingSystem/src/SectionContentWidget.cpp index 2f44849..6847906 100644 --- a/AdvancedDockingSystem/src/SectionContentWidget.cpp +++ b/AdvancedDockingSystem/src/SectionContentWidget.cpp @@ -21,6 +21,7 @@ SectionContentWidget::SectionContentWidget(SectionContent::RefPtr c, QWidget* pa SectionContentWidget::~SectionContentWidget() { qDebug() << Q_FUNC_INFO; + layout()->removeWidget(_content->contentWidget()); } ADS_NAMESPACE_END diff --git a/AdvancedDockingSystem/src/SectionTitleWidget.cpp b/AdvancedDockingSystem/src/SectionTitleWidget.cpp index 6753beb..69feef5 100644 --- a/AdvancedDockingSystem/src/SectionTitleWidget.cpp +++ b/AdvancedDockingSystem/src/SectionTitleWidget.cpp @@ -43,6 +43,7 @@ SectionTitleWidget::SectionTitleWidget(SectionContent::RefPtr content, QWidget* SectionTitleWidget::~SectionTitleWidget() { qDebug() << Q_FUNC_INFO; + layout()->removeWidget(_content->titleWidget()); } bool SectionTitleWidget::isActiveTab() const diff --git a/AdvancedDockingSystemDemo/AdvancedDockingSystemDemo.pro b/AdvancedDockingSystemDemo/AdvancedDockingSystemDemo.pro index 57ccba1..5493eeb 100644 --- a/AdvancedDockingSystemDemo/AdvancedDockingSystemDemo.pro +++ b/AdvancedDockingSystemDemo/AdvancedDockingSystemDemo.pro @@ -22,14 +22,19 @@ windows { SOURCES += \ src/main.cpp \ src/mainwindow.cpp \ - src/icontitlewidget.cpp + src/icontitlewidget.cpp \ + src/dialogs/SectionContentListModel.cpp \ + src/dialogs/SectionContentListWidget.cpp HEADERS += \ src/mainwindow.h \ - src/icontitlewidget.h + src/icontitlewidget.h \ + src/dialogs/SectionContentListModel.h \ + src/dialogs/SectionContentListWidget.h FORMS += \ - src/mainwindow.ui + src/mainwindow.ui \ + src/dialogs/SectionContentListWidget.ui # Dependency: AdvancedDockingSystem (staticlib) diff --git a/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.cpp b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.cpp new file mode 100644 index 0000000..7eeeb30 --- /dev/null +++ b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.cpp @@ -0,0 +1,85 @@ +#include "SectionContentListModel.h" + +SectionContentListModel::SectionContentListModel(QObject* parent) : + QAbstractTableModel(parent) +{ + _headers.insert(UidColumn, "UID"); + _headers.insert(UniqueNameColumn, "Unique Name"); + _headers.insert(TitleColumn, "Title"); +} + +SectionContentListModel::~SectionContentListModel() +{ +} + +void SectionContentListModel::init(ADS_NS::ContainerWidget* cw) +{ + beginResetModel(); + _cw = cw; + _contents = _cw->contents(); + endResetModel(); +} + +int SectionContentListModel::columnCount(const QModelIndex& parent) const +{ + return _headers.count(); +} + +QVariant SectionContentListModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + return _headers.value(section); + return QVariant(); +} + +int SectionContentListModel::rowCount(const QModelIndex& parent) const +{ + return _contents.count(); +} + +QVariant SectionContentListModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid() || index.row() > rowCount(index) - 1) + return QVariant(); + + const ADS_NS::SectionContent::RefPtr sc = _contents.at(index.row()); + if (sc.isNull()) + return QVariant(); + + switch (role) + { + case Qt::DisplayRole: + { + switch (index.column()) + { + case UidColumn: + return sc->uid(); + case UniqueNameColumn: + return sc->uniqueName(); + case TitleColumn: + return sc->title(); + } + } + } + return QVariant(); +} + +bool SectionContentListModel::removeRows(int row, int count, const QModelIndex& parent) +{ + if (row > rowCount(parent) - 1) + return false; + + const int first = row; + const int last = row + count - 1; + beginRemoveRows(parent, first, last); + + for (int i = last; i >= first; --i) + { + const ADS_NS::SectionContent::RefPtr sc = _contents.at(i); + _cw->removeSectionContent(sc); + _contents.removeAt(i); + } + + endRemoveRows(); + return true; +} diff --git a/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.h b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.h new file mode 100644 index 0000000..95a6c60 --- /dev/null +++ b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListModel.h @@ -0,0 +1,47 @@ +#ifndef ADS_SECTIONCONTENTMODEL_H +#define ADS_SECTIONCONTENTMODEL_H + +#include +#include +#include +#include + +#include "ads/API.h" +#include "ads/ContainerWidget.h" +#include "ads/SectionContent.h" +ADS_NAMESPACE_BEGIN +class ContainerWidget; +ADS_NAMESPACE_END + +class SectionContentListModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + enum Column + { + UidColumn, + UniqueNameColumn, + TitleColumn, + }; + + SectionContentListModel(QObject* parent); + virtual ~SectionContentListModel(); + void init(ADS_NS::ContainerWidget* cw); + + virtual int columnCount(const QModelIndex &parent) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; + + virtual int rowCount(const QModelIndex &parent) const; + virtual QVariant data(const QModelIndex &index, int role) const; + + virtual bool removeRows(int row, int count, const QModelIndex &parent); + +private: + QHash _headers; + + ADS_NS::ContainerWidget* _cw; + QList _contents; +}; + +#endif diff --git a/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.cpp b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.cpp new file mode 100644 index 0000000..26a3b46 --- /dev/null +++ b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.cpp @@ -0,0 +1,38 @@ +#include "SectionContentListWidget.h" +#include "SectionContentListModel.h" + + +SectionContentListWidget::SectionContentListWidget(QWidget* parent) : + QDialog(parent) +{ + _ui.setupUi(this); + connect(_ui.deleteButton, SIGNAL(clicked(bool)), this, SLOT(onDeleteButtonClicked())); +} + +void SectionContentListWidget::setValues(const SectionContentListWidget::Values& v) +{ + _v = v; + + // Reset + QAbstractItemModel* m = _ui.tableView->model(); + if (m) + { + _ui.tableView->setModel(NULL); + delete m; + m = NULL; + } + + // Fill. + SectionContentListModel* sclm = new SectionContentListModel(this); + sclm->init(_v.cw); + _ui.tableView->setModel(sclm); +} + +void SectionContentListWidget::onDeleteButtonClicked() +{ + const QModelIndex mi = _ui.tableView->currentIndex(); + if (!mi.isValid()) + return; + + _ui.tableView->model()->removeRows(mi.row(), 1, mi.parent()); +} diff --git a/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.h b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.h new file mode 100644 index 0000000..92a29d9 --- /dev/null +++ b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.h @@ -0,0 +1,33 @@ +#ifndef SECTIONCONTENTLISTWIDGET +#define SECTIONCONTENTLISTWIDGET + +#include +#include "ui_sectioncontentlistwidget.h" + +#include "ads/API.h" +#include "ads/ContainerWidget.h" +#include "ads/SectionContent.h" + +class SectionContentListWidget : public QDialog +{ + Q_OBJECT + +public: + class Values + { + public: + ADS_NS::ContainerWidget* cw; + }; + + SectionContentListWidget(QWidget* parent); + void setValues(const Values& v); + +private slots: + void onDeleteButtonClicked(); + +private: + Ui::SectionContentListWidgetForm _ui; + Values _v; +}; + +#endif diff --git a/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.ui b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.ui new file mode 100644 index 0000000..1f25ed3 --- /dev/null +++ b/AdvancedDockingSystemDemo/src/dialogs/SectionContentListWidget.ui @@ -0,0 +1,61 @@ + + + SectionContentListWidgetForm + + + + 0 + 0 + 522 + 258 + + + + Form + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + + + + + + Delete + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/AdvancedDockingSystemDemo/src/mainwindow.cpp b/AdvancedDockingSystemDemo/src/mainwindow.cpp index 2164af4..b1e1d93 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.cpp +++ b/AdvancedDockingSystemDemo/src/mainwindow.cpp @@ -12,6 +12,8 @@ #include "ads/SectionWidget.h" +#include "dialogs/SectionContentListWidget.h" + #include "icontitlewidget.h" /////////////////////////////////////////////////////////////////////// @@ -86,6 +88,9 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); + // Setup actions. + QObject::connect(ui->actionContentList, SIGNAL(triggered()), this, SLOT(showSectionContentListDialog())); + // ADS - Create main container (ContainerWidget). _container = new ADS_NS::ContainerWidget(); _container->setOrientation(Qt::Vertical); @@ -126,6 +131,16 @@ MainWindow::~MainWindow() delete ui; } +void MainWindow::showSectionContentListDialog() +{ + SectionContentListWidget::Values v; + v.cw = _container; + + SectionContentListWidget w(this); + w.setValues(v); + w.exec(); +} + void MainWindow::onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active) { Q_UNUSED(active); diff --git a/AdvancedDockingSystemDemo/src/mainwindow.h b/AdvancedDockingSystemDemo/src/mainwindow.h index 5a0a933..2515dd1 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.h +++ b/AdvancedDockingSystemDemo/src/mainwindow.h @@ -18,6 +18,9 @@ public: explicit MainWindow(QWidget *parent = 0); virtual ~MainWindow(); +public slots: + void showSectionContentListDialog(); + private slots: #if QT_VERSION >= 0x050000 void onActiveTabChanged(const ADS_NS::SectionContent::RefPtr& sc, bool active); diff --git a/AdvancedDockingSystemDemo/src/mainwindow.ui b/AdvancedDockingSystemDemo/src/mainwindow.ui index cc65f8b..cce9b48 100644 --- a/AdvancedDockingSystemDemo/src/mainwindow.ui +++ b/AdvancedDockingSystemDemo/src/mainwindow.ui @@ -34,7 +34,7 @@ View - + @@ -52,9 +52,9 @@ Add SectionContent - + - Demo 1 + Contents...