]> sigrok.org Git - pulseview.git/commitdiff
MainWindow: Use a QTabWidget to display the QDockWidgets
authorSoeren Apel <redacted>
Thu, 29 Sep 2016 17:36:48 +0000 (19:36 +0200)
committerSoeren Apel <redacted>
Sun, 4 Dec 2016 13:37:36 +0000 (14:37 +0100)
pv/mainwindow.cpp
pv/mainwindow.hpp

index f64345cc532f9d33af4684ad1d7da43046aee7ce..2f82cb19ca2c2fbea2ef67acf9e051e47cd6c51e 100644 (file)
@@ -69,6 +69,7 @@ MainWindow::MainWindow(DeviceManager &device_manager,
        QWidget *parent) :
        QMainWindow(parent),
        device_manager_(device_manager),
+       session_selector_(this),
        action_view_sticky_scrolling_(new QAction(this)),
        action_view_coloured_bg_(new QAction(this)),
        action_about_(new QAction(this))
@@ -107,23 +108,8 @@ MainWindow::MainWindow(DeviceManager &device_manager,
 
 MainWindow::~MainWindow()
 {
-       for (auto entry : view_docks_) {
-
-               const std::shared_ptr<QDockWidget> dock = entry.first;
-
-               // Remove view from the dock widget's QMainWindow
-               QMainWindow *dock_main = dynamic_cast<QMainWindow*>(dock->widget());
-               dock_main->setCentralWidget(0);
-
-               // Remove the QMainWindow
-               dock->setWidget(0);
-
-               const std::shared_ptr<views::ViewBase> view = entry.second;
-
-               for (shared_ptr<Session> session : sessions_)
-                       if (session->has_view(view))
-                               session->deregister_view(view);
-       }
+       while (!sessions_.empty())
+               remove_session(sessions_.front());
 }
 
 QAction* MainWindow::action_view_sticky_scrolling() const
@@ -169,10 +155,17 @@ shared_ptr<views::ViewBase> MainWindow::get_active_view() const
 shared_ptr<views::ViewBase> MainWindow::add_view(const QString &title,
        views::ViewType type, Session &session)
 {
+       QMainWindow *main_window;
+       for (auto entry : session_windows_)
+               if (entry.first.get() == &session)
+                       main_window = entry.second;
+
+       assert(main_window);
+
        if (type == views::ViewTypeTrace) {
-               shared_ptr<QDockWidget> dock = make_shared<QDockWidget>(title, this);
+               shared_ptr<QDockWidget> dock = make_shared<QDockWidget>(title, main_window);
                dock->setObjectName(title);
-               addDockWidget(Qt::TopDockWidgetArea, dock.get());
+               main_window->addDockWidget(Qt::TopDockWidgetArea, dock.get());
 
                // Insert a QMainWindow into the dock widget to allow for a tool bar
                QMainWindow *dock_main = new QMainWindow(dock.get());
@@ -241,6 +234,11 @@ shared_ptr<Session> MainWindow::add_session()
 
        sessions_.push_back(session);
 
+       QMainWindow *window = new QMainWindow();
+       window->setWindowFlags(Qt::Widget);  // Remove Qt::Window flag
+       session_windows_[session] = window;
+       session_selector_.addTab(window, name);
+
        shared_ptr<views::ViewBase> main_view =
                add_view(name, views::ViewTypeTrace, *session);
 
@@ -250,12 +248,28 @@ shared_ptr<Session> MainWindow::add_session()
 void MainWindow::remove_session(shared_ptr<Session> session)
 {
        for (shared_ptr<views::ViewBase> view : session->views()) {
-               // Find the dock the view is contained in and close it
+               // Find the dock the view is contained in and remove it
                for (auto entry : view_docks_)
-                       if (entry.second == view)
-                               entry.first->close();
+                       if (entry.second == view) {
+                               // Remove the view from the session
+                               session->deregister_view(view);
+
+                               // Remove the view from its parent; otherwise, Qt will
+                               // call deleteLater() on it, which causes a double free
+                               // since the shared_ptr in view_docks_ doesn't know
+                               // that Qt keeps a pointer to the view around
+                               entry.second->setParent(0);
+
+                               // Remove this entry from the container
+                               view_docks_.erase(entry.first);
+                       }
        }
 
+       QMainWindow *window = session_windows_.at(session);
+       session_selector_.removeTab(session_selector_.indexOf(window));
+
+       session_windows_.erase(session);
+
        sessions_.remove_if([&](shared_ptr<Session> s) {
                return s == session; });
 
@@ -269,6 +283,8 @@ void MainWindow::setup_ui()
 {
        setObjectName(QString::fromUtf8("MainWindow"));
 
+       setCentralWidget(&session_selector_);
+
        // Set the window icon
        QIcon icon;
        icon.addFile(QString(":/icons/sigrok-logo-notext.png"));
index ddad67050f03a5a78317ae00fd00d17750ad53c0..e9cecfb1deab73c4fcf3cb81578b3d5829c71c65 100644 (file)
@@ -26,6 +26,7 @@
 #include <memory>
 
 #include <QMainWindow>
+#include <QTabWidget>
 
 #include "session.hpp"
 #include "views/viewbase.hpp"
@@ -120,6 +121,10 @@ private:
        std::map< std::shared_ptr<QDockWidget>,
                std::shared_ptr<views::ViewBase> > view_docks_;
 
+       std::map< std::shared_ptr<Session>, QMainWindow*> session_windows_;
+
+       QTabWidget session_selector_;
+
        QAction *const action_view_sticky_scrolling_;
        QAction *const action_view_coloured_bg_;
        QAction *const action_about_;