#ifndef CVVISUAL_MULTIVIEW_CALL_TAB_HPP #define CVVISUAL_MULTIVIEW_CALL_TAB_HPP #include <vector> #include <memory> #include <QObject> #include <QString> #include <QMap> #include <QPushButton> #include <QComboBox> #include <QHBoxLayout> #include <QVBoxLayout> #include <QLabel> #include "call_tab.hpp" #include "../util/util.hpp" #include "../qtutil/registerhelper.hpp" #include "../qtutil/signalslot.hpp" #include "../qtutil/util.hpp" namespace cvv { namespace gui { /** Call Tab for multiple views. * @brief Inner part of a tab, contains a View. * The inner part of a tab or window * containing a View. * Allows to switch between different views and to access the help. * @tparam ViewType A type of View. * @tparam CallType A type of Call. */ template <class ViewType, class CallType> class MultiViewCallTab : public CallTab, public cvv::qtutil::RegisterHelper<ViewType, const CallType &, QWidget *> { public: /** * @brief Short constructor named after Call and using the default view. * Initializes the MultiViewCallTab with the default view and names it after * the associated Call. * @param call - the Call containing the information to be * visualized. * @param default_key - Key under which the default view is to be saved. * @param standard_default - Standard default view. */ MultiViewCallTab(const CallType &call, const QString& default_key, const QString& standard_default) : MultiViewCallTab{ call.description(), call, default_key, standard_default } { } /** * @brief Constructor using the default view. * Initializes the MultiViewCallTab with the default view. * @param name - Name to give the CallTab. * @param call - the Call containing the information to be * visualized. * @param default_key - Key under which the default view is to be saved. * @param standard_default - Standard default view. */ MultiViewCallTab(const QString &tabName, const CallType &call, const QString& default_key, const QString& standard_default) : call_{ call }, currentIndexChanged{ [&]() { vlayout_->removeWidget(view_); view_->setVisible(false); setView(); } }, helpButtonClicked{ [&]() { qtutil::openHelpBrowser(viewId_); } }, setAsDefaultButtonClicked{ [&]() { qtutil::setSetting(default_scope_, default_key_, viewId_); } } { setName(tabName); default_scope_ = QString{ "default_views" }; default_key_ = default_key; standard_default_ = standard_default; // Sets standard_default_ as default in case no other default is // set: qtutil::setDefaultSetting(default_scope_, default_key_, standard_default_); viewId_ = qtutil::getSetting(default_scope_, default_key_); createGui(); } /** * @brief Constructor with possibility to select view. * Note that the default view is still created first. * @param call - the Call containing the information to be * visualized. * @param viewId - ID of the View to be set up. If a view of this name does * not exist, the default view will be used. * @param default_key - Key under which the default view is to be saved. * @param standard_default - Standard default view. */ MultiViewCallTab(const CallType& call, const QString& viewId, const QString& default_key, const QString& standard_default) : MultiViewCallTab{call, default_key, standard_default} { this->select(viewId); } ~MultiViewCallTab() { } /** * @brief get ID. * @return the ID of the CallTab. * (ID is equal to the ID of the associated call). * Overrides CallTab's getId. */ size_t getId() const override { return call_->getId(); } /** * @brief Register the template class to the map of Views. * View needs to offer a constructor of the form View(const * cvv::impl::CallType&, QWidget*). * @param name to register the class under. * @tparam View - Class to register. * @return true when the view was registered and false when the name was * already taken. */ template <class View> static bool registerView(const QString &name) { return MultiViewCallTab<ViewType, CallType>::registerElement( name, [](const CallType &call, QWidget *parent) { return cvv::util::make_unique<View>(call, parent); }); } protected: /** * @brief Scope to search the default view in. */ QString default_scope_; /** * @brief Key under which the default view is saved. */ QString default_key_; /** * @brief standard default view. */ QString standard_default_; /** * @brief Sets up the visible parts. * Called by the constructors. */ void createGui() { if (!this->select(viewId_)) { this->select(standard_default_); viewId_ = this->selection(); setAsDefaultButtonClicked.slot(); // Set as default. /* If viewId_ does not name a valid View, it will be * attempted to set standard_default_. * If that was not registered either, the current * selection of the ComboBox will be used automatically. * Whichever was chosen will be set as the new default. */ } hlayout_ = new QHBoxLayout{}; hlayout_->setAlignment(Qt::AlignTop | Qt::AlignRight); hlayout_->addWidget(new QLabel{ "View:" }); hlayout_->addWidget(this->comboBox_); setAsDefaultButton_ = new QPushButton{ "Set as default", this }; hlayout_->addWidget(setAsDefaultButton_); helpButton_ = new QPushButton{ "Help", this }; hlayout_->addWidget(helpButton_); upperBar_ = new QWidget{ this }; upperBar_->setLayout(hlayout_); vlayout_ = new QVBoxLayout{}; vlayout_->addWidget(upperBar_); setView(); setLayout(vlayout_); QObject::connect(setAsDefaultButton_, SIGNAL(clicked()), &setAsDefaultButtonClicked, SLOT(slot())); QObject::connect(helpButton_, SIGNAL(clicked()), &helpButtonClicked, SLOT(slot())); QObject::connect(&this->signalElementSelected(), SIGNAL(signal(QString)), ¤tIndexChanged, SLOT(slot())); } /** * @brief sets up the View currently selected in the ComboBox inherited * from RegisterHelper. */ void setView() { viewId_ = this->selection(); if (viewHistory_.count(this->selection())) { view_ = viewHistory_.at(this->selection()); vlayout_->addWidget(view_); view_->setVisible(true); } else { viewHistory_.emplace( this->selection(), ((*this)()(*call_, this).release())); view_ = viewHistory_.at(this->selection()); vlayout_->addWidget(view_); } viewSet.emitSignal(); } util::Reference<const CallType> call_; QString viewId_; ViewType *view_; std::map<QString, ViewType *> viewHistory_; QPushButton *helpButton_; QPushButton *setAsDefaultButton_; QHBoxLayout *hlayout_; QVBoxLayout *vlayout_; QWidget *upperBar_; //signals: /** * @brief signal emitted whem view is completely set up. */ qtutil::Signal viewSet; // slots: /** * @brief View selection change. * Slot called when the index of the view selection changes. */ qtutil::Slot currentIndexChanged; /** * @brief Help Button clicked. * Called when the help button is clicked. */ const qtutil::Slot helpButtonClicked; /** * @brief setAsDefaultButton clicked. * Called when the setAsDefaultButton,which sets the current view as * default, is clicked. */ qtutil::Slot setAsDefaultButtonClicked; }; } } // namespaces #endif