Implement adding different view types
authorSoeren Apel <soeren@apelpie.net>
Mon, 25 Nov 2019 20:46:27 +0000 (21:46 +0100)
committerSoeren Apel <soeren@apelpie.net>
Wed, 27 Nov 2019 12:26:04 +0000 (13:26 +0100)
pv/mainwindow.cpp
pv/mainwindow.hpp
pv/session.cpp
pv/session.hpp
pv/toolbars/mainbar.cpp
pv/toolbars/mainbar.hpp
pv/views/viewbase.cpp
pv/views/viewbase.hpp
test/CMakeLists.txt

index c652e3e861ac0fd31d40888b8e2e8fc064886273..51ebda8369a05be3ec1d3555cb9e0e5f1bb24015 100644 (file)
@@ -128,8 +128,8 @@ shared_ptr<views::ViewBase> MainWindow::get_active_view() const
        return nullptr;
 }
 
-shared_ptr<views::ViewBase> MainWindow::add_view(const QString &title,
-       views::ViewType type, Session &session)
+shared_ptr<views::ViewBase> MainWindow::add_view(views::ViewType type,
+       Session &session)
 {
        GlobalSettings settings;
        shared_ptr<views::ViewBase> v;
@@ -143,6 +143,13 @@ shared_ptr<views::ViewBase> MainWindow::add_view(const QString &title,
 
        shared_ptr<MainBar> main_bar = session.main_bar();
 
+       // Only use the view type in the name if it's not the main view
+       QString title;
+       if (main_bar)
+               title = QString("%1 (%2)").arg(session.name()).arg(views::ViewTypeNames[type]);
+       else
+               title = session.name();
+
        QDockWidget* dock = new QDockWidget(title, main_window);
        dock->setObjectName(title);
        main_window->addDockWidget(Qt::TopDockWidgetArea, dock);
@@ -153,8 +160,7 @@ shared_ptr<views::ViewBase> MainWindow::add_view(const QString &title,
 
        if (type == views::ViewTypeTrace)
                // This view will be the main view if there's no main bar yet
-               v = make_shared<views::trace::View>(session,
-                       (main_bar ? false : true), dock_main);
+               v = make_shared<views::trace::View>(session, (main_bar ? false : true), dock_main);
 #ifdef ENABLE_DECODE
        if (type == views::ViewTypeDecoderOutput)
                v = make_shared<views::decoder_output::View>(session, false, dock_main);
@@ -194,8 +200,8 @@ shared_ptr<views::ViewBase> MainWindow::add_view(const QString &title,
                        dock_main->addToolBar(main_bar.get());
                        session.set_main_bar(main_bar);
 
-                       connect(main_bar.get(), SIGNAL(new_view(Session*)),
-                               this, SLOT(on_new_view(Session*)));
+                       connect(main_bar.get(), SIGNAL(new_view(Session*, int)),
+                               this, SLOT(on_new_view(Session*, int)));
                        connect(main_bar.get(), SIGNAL(show_decoder_selector(Session*)),
                                this, SLOT(on_show_decoder_selector(Session*)));
 
@@ -319,8 +325,8 @@ shared_ptr<Session> MainWindow::add_session()
 
        shared_ptr<Session> session = make_shared<Session>(device_manager_, name);
 
-       connect(session.get(), SIGNAL(add_view(const QString&, views::ViewType, Session*)),
-               this, SLOT(on_add_view(const QString&, views::ViewType, Session*)));
+       connect(session.get(), SIGNAL(add_view(views::ViewType, Session*)),
+               this, SLOT(on_add_view(views::ViewType, Session*)));
        connect(session.get(), SIGNAL(name_changed()),
                this, SLOT(on_session_name_changed()));
        session_state_mapper_.setMapping(session.get(), session.get());
@@ -339,8 +345,7 @@ shared_ptr<Session> MainWindow::add_session()
 
        window->setDockNestingEnabled(true);
 
-       shared_ptr<views::ViewBase> main_view =
-               add_view(name, views::ViewTypeTrace, *session);
+       shared_ptr<views::ViewBase> main_view = add_view(views::ViewTypeTrace, *session);
 
        return session;
 }
@@ -628,13 +633,12 @@ bool MainWindow::restoreState(const QByteArray &state, int version)
        return false;
 }
 
-void MainWindow::on_add_view(const QString &title, views::ViewType type,
-       Session *session)
+void MainWindow::on_add_view(views::ViewType type, Session *session)
 {
        // We get a pointer and need a reference
        for (shared_ptr<Session>& s : sessions_)
                if (s.get() == session)
-                       add_view(title, type, *s);
+                       add_view(type, *s);
 }
 
 void MainWindow::on_focus_changed()
@@ -749,12 +753,12 @@ void MainWindow::on_capture_state_changed(QObject *obj)
                tr("Run") : tr("Stop"));
 }
 
-void MainWindow::on_new_view(Session *session)
+void MainWindow::on_new_view(Session *session, int view_type)
 {
        // We get a pointer and need a reference
        for (shared_ptr<Session>& s : sessions_)
                if (s.get() == session)
-                       add_view(session->name(), views::ViewTypeTrace, *s);
+                       add_view((views::ViewType)view_type, *s);
 }
 
 void MainWindow::on_view_close_clicked()
index 6f3676c214f24c7343ed62bde29fe1446d1d036f..06eba40ac212760373defba5fbdac8b7c46b9037 100644 (file)
@@ -79,8 +79,7 @@ public:
 
        shared_ptr<views::ViewBase> get_active_view() const;
 
-       shared_ptr<views::ViewBase> add_view(const QString &title,
-               views::ViewType type, Session &session);
+       shared_ptr<views::ViewBase> add_view(views::ViewType type, Session &session);
 
        void remove_view(shared_ptr<views::ViewBase> view);
 
@@ -114,8 +113,7 @@ private:
        virtual bool restoreState(const QByteArray &state, int version = 0);
 
 private Q_SLOTS:
-       void on_add_view(const QString &title, views::ViewType type,
-               Session *session);
+       void on_add_view(views::ViewType type, Session *session);
 
        void on_focus_changed();
        void on_focused_session_changed(shared_ptr<Session> session);
@@ -127,7 +125,7 @@ private Q_SLOTS:
        void on_session_name_changed();
        void on_capture_state_changed(QObject *obj);
 
-       void on_new_view(Session *session);
+       void on_new_view(Session *session, int view_type);
        void on_view_close_clicked();
 
        void on_tab_changed(int index);
index 6d9ce830bdaf19ef8ee33ba651f0844516904778..39b1fb354fff6d10f0320e3f47708af7154f2adb 100644 (file)
@@ -312,7 +312,7 @@ void Session::restore_setup(QSettings &settings)
 
                if (i > 0) {
                        views::ViewType type = (views::ViewType)settings.value("type").toInt();
-                       add_view(name_, type, this);
+                       add_view(type, this);
                        views_.back()->restore_settings(settings);
                } else
                        main_view_->restore_settings(settings);
index a4aaf6aabbcc8c94bf32e446375e8b9218a36b26..8d85996ec6ec05e9656ffa6519e9c86ee2f1d656 100644 (file)
@@ -264,8 +264,7 @@ Q_SIGNALS:
 
        void data_received();
 
-       void add_view(const QString &title, views::ViewType type,
-               Session *session);
+       void add_view(views::ViewType type, Session *session);
 
 public Q_SLOTS:
        void on_data_saved();
index 666c28d3049f7bd6b8a9ff7ccc35dc902b69814b..3836b09a78786516ce66514337f40e5e3517425f 100644 (file)
@@ -95,6 +95,7 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        action_restore_setup_(new QAction(this)),
        action_save_setup_(new QAction(this)),
        action_connect_(new QAction(this)),
+       new_view_button_(new QToolButton()),
        open_button_(new QToolButton()),
        save_button_(new QToolButton()),
        device_selector_(parent, session.device_manager(), action_connect_),
@@ -167,6 +168,20 @@ MainBar::MainBar(Session &session, QWidget *parent, pv::views::trace::View *view
        connect(action_connect_, SIGNAL(triggered(bool)),
                this, SLOT(on_actionConnect_triggered()));
 
+       // New view button
+       QMenu *menu_new_view = new QMenu();
+       connect(menu_new_view, SIGNAL(triggered(QAction*)),
+               this, SLOT(on_actionNewView_triggered(QAction*)));
+
+       for (int i = 0; i < views::ViewTypeCount; i++) {
+               QAction *const action = menu_new_view->addAction(tr(views::ViewTypeNames[i]));
+               action->setData(qVariantFromValue(i));
+       }
+
+       new_view_button_->setMenu(menu_new_view);
+       new_view_button_->setDefaultAction(action_new_view_);
+       new_view_button_->setPopupMode(QToolButton::MenuButtonPopup);
+
        // Open button
        vector<QAction*> open_actions;
        open_actions.push_back(action_open_);
@@ -754,9 +769,13 @@ void MainBar::on_config_changed()
        commit_sample_rate();
 }
 
-void MainBar::on_actionNewView_triggered()
+void MainBar::on_actionNewView_triggered(QAction* action)
 {
-       new_view(&session_);
+       if (action)
+               new_view(&session_, action->data().toInt());
+       else
+               // When the icon of the button is clicked, we create a trace view
+               new_view(&session_, views::ViewTypeTrace);
 }
 
 void MainBar::on_actionOpen_triggered()
@@ -844,7 +863,7 @@ void MainBar::on_add_decoder_clicked()
 
 void MainBar::add_toolbar_widgets()
 {
-       addAction(action_new_view_);
+       addWidget(new_view_button_);
        addSeparator();
        addWidget(open_button_);
        addWidget(save_button_);
index bc0c2dfdd528c11c6bfba37c499ae5078ab7cfeb..008ab628f701ca714cfca02391f07ed90d438335 100644 (file)
@@ -139,7 +139,7 @@ private Q_SLOTS:
 
        void on_config_changed();
 
-       void on_actionNewView_triggered();
+       void on_actionNewView_triggered(QAction* action = nullptr);
 
        void on_actionOpen_triggered();
        void on_actionSaveAs_triggered();
@@ -158,11 +158,11 @@ protected:
        bool eventFilter(QObject *watched, QEvent *event);
 
 Q_SIGNALS:
-       void new_view(Session *session);
+       void new_view(Session *session, int type);
        void show_decoder_selector(Session *session);
 
 private:
-       QToolButton *open_button_, *save_button_;
+       QToolButton *new_view_button_, *open_button_, *save_button_;
 
        pv::widgets::DeviceToolButton device_selector_;
 
index 4449d1905f921dbce64c087765fc4c7450a5c48c..a4dc5490bcd050e97c8ec24dc34898abc2f96946 100644 (file)
@@ -33,6 +33,13 @@ using std::shared_ptr;
 namespace pv {
 namespace views {
 
+const char* ViewTypeNames[ViewTypeCount] = {
+               "Trace View",
+#ifdef ENABLE_DECODE
+               "Decoder Output View"
+#endif
+};
+
 const int ViewBase::MaxViewAutoUpdateRate = 25; // No more than 25 Hz
 
 ViewBase::ViewBase(Session &session, bool is_main_view, QWidget *parent) :
index 09c5716ae1cb82443cd13a243a2f714c73c76198..0c7b0463661d3019943859883bff3b14987962e4 100644 (file)
@@ -50,12 +50,17 @@ class Signal;
 
 namespace views {
 
+// When adding an entry here, don't forget to update ViewTypeNames as well
 enum ViewType {
        ViewTypeTrace,
+#ifdef ENABLE_DECODE
        ViewTypeDecoderOutput,
-       ViewTypeTabularDecode
+#endif
+       ViewTypeCount  // Indicates how many view types there are, must always be last
 };
 
+extern const char* ViewTypeNames[ViewTypeCount];
+
 class ViewBase : public QWidget
 {
        Q_OBJECT
index 6d4472a3904a63d680a955b2bd7902b209ec763b..0f81a0e5131a9f96672a471d0c5b53659a779ace 100644 (file)
@@ -172,6 +172,7 @@ if(ENABLE_DECODE)
                ${PROJECT_SOURCE_DIR}/pv/subwindows/decoder_selector/item.cpp
                ${PROJECT_SOURCE_DIR}/pv/subwindows/decoder_selector/model.cpp
                ${PROJECT_SOURCE_DIR}/pv/subwindows/decoder_selector/subwindow.cpp
+               ${PROJECT_SOURCE_DIR}/pv/views/decoder_output/view.cpp
                ${PROJECT_SOURCE_DIR}/pv/views/trace/decodetrace.cpp
                ${PROJECT_SOURCE_DIR}/pv/widgets/decodergroupbox.cpp
                ${PROJECT_SOURCE_DIR}/pv/widgets/decodermenu.cpp
@@ -180,6 +181,7 @@ if(ENABLE_DECODE)
        list(APPEND pulseview_TEST_HEADERS
                ${PROJECT_SOURCE_DIR}/pv/data/decodesignal.hpp
                ${PROJECT_SOURCE_DIR}/pv/subwindows/decoder_selector/subwindow.hpp
+               ${PROJECT_SOURCE_DIR}/pv/views/decoder_output/view.hpp
                ${PROJECT_SOURCE_DIR}/pv/views/trace/decodetrace.hpp
                ${PROJECT_SOURCE_DIR}/pv/widgets/decodergroupbox.hpp
                ${PROJECT_SOURCE_DIR}/pv/widgets/decodermenu.hpp