- // Setup the central widget
- _central_widget = new QWidget(this);
- _vertical_layout = new QVBoxLayout(_central_widget);
- _vertical_layout->setSpacing(6);
- _vertical_layout->setContentsMargins(0, 0, 0, 0);
- setCentralWidget(_central_widget);
-
- _view = new pv::view::View(_session, this);
-
- _vertical_layout->addWidget(_view);
-
- // Setup the menu bar
- _menu_bar = new QMenuBar(this);
- _menu_bar->setGeometry(QRect(0, 0, 400, 25));
-
- // File Menu
- _menu_file = new QMenu(_menu_bar);
- _menu_file->setTitle(QApplication::translate(
- "MainWindow", "&File", 0, QApplication::UnicodeUTF8));
-
- _action_open = new QAction(this);
- _action_open->setText(QApplication::translate(
- "MainWindow", "&Open...", 0, QApplication::UnicodeUTF8));
- _action_open->setIcon(QIcon::fromTheme("document-open",
- QIcon(":/icons/document-open.png")));
- _action_open->setObjectName(QString::fromUtf8("actionOpen"));
- _menu_file->addAction(_action_open);
-
- _menu_file->addSeparator();
-
- _action_connect = new QAction(this);
- _action_connect->setText(QApplication::translate(
- "MainWindow", "&Connect to Device...", 0,
- QApplication::UnicodeUTF8));
- _action_connect->setObjectName(QString::fromUtf8("actionConnect"));
- _menu_file->addAction(_action_connect);
-
- _menu_file->addSeparator();
-
- _action_quit = new QAction(this);
- _action_quit->setText(QApplication::translate(
- "MainWindow", "&Quit", 0, QApplication::UnicodeUTF8));
- _action_quit->setIcon(QIcon::fromTheme("application-exit",
- QIcon(":/icons/application-exit.png")));
- _action_quit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
- _action_quit->setObjectName(QString::fromUtf8("actionQuit"));
- _menu_file->addAction(_action_quit);
-
- // View Menu
- _menu_view = new QMenu(_menu_bar);
- _menu_view->setTitle(QApplication::translate(
- "MainWindow", "&View", 0, QApplication::UnicodeUTF8));
-
- _action_view_zoom_in = new QAction(this);
- _action_view_zoom_in->setText(QApplication::translate(
- "MainWindow", "Zoom &In", 0, QApplication::UnicodeUTF8));
- _action_view_zoom_in->setIcon(QIcon::fromTheme("zoom-in",
- QIcon(":/icons/zoom-in.png")));
- _action_view_zoom_in->setObjectName(
- QString::fromUtf8("actionViewZoomIn"));
- _menu_view->addAction(_action_view_zoom_in);
-
- _action_view_zoom_out = new QAction(this);
- _action_view_zoom_out->setText(QApplication::translate(
- "MainWindow", "Zoom &Out", 0, QApplication::UnicodeUTF8));
- _action_view_zoom_out->setIcon(QIcon::fromTheme("zoom-out",
- QIcon(":/icons/zoom-out.png")));
- _action_view_zoom_out->setObjectName(
- QString::fromUtf8("actionViewZoomOut"));
- _menu_view->addAction(_action_view_zoom_out);
-
- _menu_view->addSeparator();
-
- _action_view_show_cursors = new QAction(this);
- _action_view_show_cursors->setCheckable(true);
- _action_view_show_cursors->setChecked(_view->cursors_shown());
- _action_view_show_cursors->setShortcut(QKeySequence(Qt::Key_C));
- _action_view_show_cursors->setObjectName(
- QString::fromUtf8("actionViewShowCursors"));
- _action_view_show_cursors->setText(QApplication::translate(
- "MainWindow", "Show &Cursors", 0, QApplication::UnicodeUTF8));
- _menu_view->addAction(_action_view_show_cursors);
-
- // Decoders Menu
- _menu_decoders = new QMenu(_menu_bar);
- _menu_decoders->setTitle(QApplication::translate(
- "MainWindow", "&Decoders", 0, QApplication::UnicodeUTF8));
-
- _menu_decoders_add = new QMenu(_menu_decoders);
- _menu_decoders_add->setTitle(QApplication::translate(
- "MainWindow", "&Add", 0, QApplication::UnicodeUTF8));
- setup_add_decoders(_menu_decoders_add);
-
- _menu_decoders->addMenu(_menu_decoders_add);
- connect(&_decoders_add_mapper, SIGNAL(mapped(QObject*)),
- this, SLOT(add_decoder(QObject*)));
-
- // Help Menu
- _menu_help = new QMenu(_menu_bar);
- _menu_help->setTitle(QApplication::translate(
- "MainWindow", "&Help", 0, QApplication::UnicodeUTF8));
-
- _action_about = new QAction(this);
- _action_about->setObjectName(QString::fromUtf8("actionAbout"));
- _action_about->setText(QApplication::translate(
- "MainWindow", "&About...", 0, QApplication::UnicodeUTF8));
- _menu_help->addAction(_action_about);
-
- _menu_bar->addAction(_menu_file->menuAction());
- _menu_bar->addAction(_menu_view->menuAction());
- _menu_bar->addAction(_menu_decoders->menuAction());
- _menu_bar->addAction(_menu_help->menuAction());
-
- setMenuBar(_menu_bar);
- QMetaObject::connectSlotsByName(this);
-
- // Setup the toolbar
- _toolbar = new QToolBar(tr("Main Toolbar"), this);
- _toolbar->addAction(_action_open);
- _toolbar->addSeparator();
- _toolbar->addAction(_action_view_zoom_in);
- _toolbar->addAction(_action_view_zoom_out);
- addToolBar(_toolbar);
-
- // Setup the sampling bar
- _sampling_bar = new toolbars::SamplingBar(_session, this);
-
- // Populate the device list and select the initially selected device
- update_device_list();
-
- connect(_sampling_bar, SIGNAL(run_stop()), this,
- SLOT(run_stop()));
- addToolBar(_sampling_bar);
-
- // Set the title
- setWindowTitle(QApplication::translate("MainWindow", "PulseView", 0,
- QApplication::UnicodeUTF8));
-
- // Setup _session events
- connect(&_session, SIGNAL(capture_state_changed(int)), this,
- SLOT(capture_state_changed(int)));
-
-}
-
-void MainWindow::session_error(
- const QString text, const QString info_text)
-{
- QMetaObject::invokeMethod(this, "show_session_error",
- Qt::QueuedConnection, Q_ARG(QString, text),
- Q_ARG(QString, info_text));
-}
-
-void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
-{
- assert(_sampling_bar);
-
- const list<sr_dev_inst*> &devices = _device_manager.devices();
- _sampling_bar->set_device_list(devices);
-
- if (!selected_device && !devices.empty()) {
- // Fall back to the first device in the list.
- selected_device = devices.front();
-
- // Try and find the demo device and select that by default
- BOOST_FOREACH (struct sr_dev_inst *sdi, devices)
- if (strcmp(sdi->driver->name, "demo") == 0) {
- selected_device = sdi;
+ /* For the main view we need to prevent the dock widget from
+ * closing itself when its close button is clicked. This is
+ * so we can confirm with the user first. Regular views don't
+ * need this */
+ close_btn->disconnect(SIGNAL(clicked()), dock, SLOT(close()));
+ } else {
+ /* Additional view, create a standard bar */
+ pv::views::trace::StandardBar *standard_bar =
+ new pv::views::trace::StandardBar(session, this, tv);
+ dock_main->addToolBar(standard_bar);
+
+ standard_bar->action_view_show_cursors()->setChecked(tv->cursors_shown());
+ }
+ }
+
+ return v;
+}
+
+void MainWindow::remove_view(shared_ptr<views::ViewBase> view)
+{
+ for (shared_ptr<Session> session : sessions_) {
+ if (!session->has_view(view))
+ continue;
+
+ // Find the dock the view is contained in and remove it
+ for (auto entry : view_docks_)
+ 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
+ view->setParent(nullptr);
+
+ // Delete the view's dock widget and all widgets inside it
+ entry.first->deleteLater();
+
+ // Remove the dock widget from the list and stop iterating
+ view_docks_.erase(entry.first);
+ break;