diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index 0d425d929..acfdea4e6 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -55,9 +55,42 @@ windowDimensionToPixels( const Calamares::Branding::WindowDimension& u ) return 0; } +/** @brief Expected orientation of the panels, based on their side + * + * Panels on the left and right are expected to be "vertical" style, + * top and bottom should be "horizontal bars". This function maps + * the sides to expected orientation. + */ +static inline Qt::Orientation +orientation( const Calamares::Branding::PanelSide s ) +{ + using Side = Calamares::Branding::PanelSide; + return ( s == Side::Left || s == Side::Right ) ? Qt::Orientation::Vertical : Qt::Orientation::Horizontal; +} -QWidget* -CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth ) +/** @brief Get a button-sized icon. */ +static inline QPixmap +getButtonIcon( const QString& name ) +{ + return Calamares::Branding::instance()->image( name, QSize( 22, 22 ) ); +} + +static inline void +setButtonIcon( QPushButton* button, const QString& name ) +{ + auto icon = getButtonIcon( name ); + if ( button && !icon.isNull() ) + { + button->setIcon( icon ); + } +} + +static QWidget* +getWidgetSidebar( CalamaresWindow* window, + Calamares::ViewManager* viewManager, + QWidget* parent, + Qt::Orientation, + int desiredWidth ) { const Calamares::Branding* const branding = Calamares::Branding::instance(); @@ -91,7 +124,7 @@ CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth ) logoLayout->addStretch(); ProgressTreeView* tv = new ProgressTreeView( sideBox ); - tv->setModel( Calamares::ViewManager::instance() ); + tv->setModel( viewManager ); tv->setFocusPolicy( Qt::NoFocus ); sideLayout->addWidget( tv ); @@ -99,53 +132,22 @@ CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth ) { QPushButton* debugWindowBtn = new QPushButton; debugWindowBtn->setObjectName( "debugButton" ); - CALAMARES_RETRANSLATE( debugWindowBtn->setText( tr( "Show debug information" ) ); ) + CALAMARES_RETRANSLATE_WIDGET( debugWindowBtn, + debugWindowBtn->setText( QCoreApplication::translate( + CalamaresWindow::staticMetaObject.className(), "Show debug information" ) ); ) sideLayout->addWidget( debugWindowBtn ); debugWindowBtn->setFlat( true ); debugWindowBtn->setCheckable( true ); - connect( debugWindowBtn, &QPushButton::clicked, this, [=]( bool checked ) { - if ( checked ) - { - m_debugWindow = new Calamares::DebugWindow(); - m_debugWindow->show(); - connect( m_debugWindow.data(), &Calamares::DebugWindow::closed, this, [=]() { - m_debugWindow->deleteLater(); - debugWindowBtn->setChecked( false ); - } ); - } - else - { - if ( m_debugWindow ) - { - m_debugWindow->deleteLater(); - } - } - } ); + QObject::connect( debugWindowBtn, &QPushButton::clicked, window, &CalamaresWindow::showDebugWindow ); + QObject::connect( window, &CalamaresWindow::debugWindowShown, debugWindowBtn, &QPushButton::setChecked ); } CalamaresUtils::unmarginLayout( sideLayout ); return sideBox; } -/** @brief Get a button-sized icon. */ -static inline QPixmap -getButtonIcon( const QString& name ) -{ - return Calamares::Branding::instance()->image( name, QSize( 22, 22 ) ); -} - -static inline void -setButtonIcon( QPushButton* button, const QString& name ) -{ - auto icon = getButtonIcon( name ); - if ( button && !icon.isNull() ) - { - button->setIcon( icon ); - } -} - -QWidget* -CalamaresWindow::getWidgetNavigation( QWidget* parent ) +static QWidget* +getWidgetNavigation( CalamaresWindow*, Calamares::ViewManager* viewManager, QWidget* parent, Qt::Orientation, int ) { QWidget* navigation = new QWidget( parent ); QBoxLayout* bottomLayout = new QHBoxLayout; @@ -153,43 +155,51 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) // Create buttons and sets an initial icon; the icons may change { - auto* back = new QPushButton( getButtonIcon( QStringLiteral( "go-previous" ) ), tr( "&Back" ), navigation ); + auto* back + = new QPushButton( getButtonIcon( QStringLiteral( "go-previous" ) ), + QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(), "&Back" ), + navigation ); back->setObjectName( "view-button-back" ); - back->setEnabled( m_viewManager->backEnabled() ); - connect( back, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::back ); - connect( m_viewManager, &Calamares::ViewManager::backEnabledChanged, back, &QPushButton::setEnabled ); - connect( m_viewManager, &Calamares::ViewManager::backLabelChanged, back, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::backIconChanged, this, [=]( QString n ) { - setButtonIcon( back, n ); - } ); - connect( m_viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, back, &QPushButton::setVisible ); + back->setEnabled( viewManager->backEnabled() ); + QObject::connect( back, &QPushButton::clicked, viewManager, &Calamares::ViewManager::back ); + QObject::connect( viewManager, &Calamares::ViewManager::backEnabledChanged, back, &QPushButton::setEnabled ); + QObject::connect( viewManager, &Calamares::ViewManager::backLabelChanged, back, &QPushButton::setText ); + QObject::connect( + viewManager, &Calamares::ViewManager::backIconChanged, [=]( QString n ) { setButtonIcon( back, n ); } ); + QObject::connect( + viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, back, &QPushButton::setVisible ); bottomLayout->addWidget( back ); } { - auto* next = new QPushButton( getButtonIcon( QStringLiteral( "go-next" ) ), tr( "&Next" ), navigation ); + auto* next + = new QPushButton( getButtonIcon( QStringLiteral( "go-next" ) ), + QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(), "&Next" ), + navigation ); next->setObjectName( "view-button-next" ); - next->setEnabled( m_viewManager->nextEnabled() ); - connect( next, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::next ); - connect( m_viewManager, &Calamares::ViewManager::nextEnabledChanged, next, &QPushButton::setEnabled ); - connect( m_viewManager, &Calamares::ViewManager::nextLabelChanged, next, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::nextIconChanged, this, [=]( QString n ) { - setButtonIcon( next, n ); - } ); - connect( m_viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, next, &QPushButton::setVisible ); + next->setEnabled( viewManager->nextEnabled() ); + QObject::connect( next, &QPushButton::clicked, viewManager, &Calamares::ViewManager::next ); + QObject::connect( viewManager, &Calamares::ViewManager::nextEnabledChanged, next, &QPushButton::setEnabled ); + QObject::connect( viewManager, &Calamares::ViewManager::nextLabelChanged, next, &QPushButton::setText ); + QObject::connect( + viewManager, &Calamares::ViewManager::nextIconChanged, [=]( QString n ) { setButtonIcon( next, n ); } ); + QObject::connect( + viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, next, &QPushButton::setVisible ); bottomLayout->addWidget( next ); } bottomLayout->addSpacing( 12 ); { - auto* quit = new QPushButton( getButtonIcon( QStringLiteral( "dialog-cancel" ) ), tr( "&Cancel" ), navigation ); + auto* quit + = new QPushButton( getButtonIcon( QStringLiteral( "dialog-cancel" ) ), + QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(), "&Cancel" ), + navigation ); quit->setObjectName( "view-button-cancel" ); - connect( quit, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::quit ); - connect( m_viewManager, &Calamares::ViewManager::quitEnabledChanged, quit, &QPushButton::setEnabled ); - connect( m_viewManager, &Calamares::ViewManager::quitLabelChanged, quit, &QPushButton::setText ); - connect( m_viewManager, &Calamares::ViewManager::quitIconChanged, this, [=]( QString n ) { - setButtonIcon( quit, n ); - } ); - connect( m_viewManager, &Calamares::ViewManager::quitTooltipChanged, quit, &QPushButton::setToolTip ); - connect( m_viewManager, &Calamares::ViewManager::quitVisibleChanged, quit, &QPushButton::setVisible ); + QObject::connect( quit, &QPushButton::clicked, viewManager, &Calamares::ViewManager::quit ); + QObject::connect( viewManager, &Calamares::ViewManager::quitEnabledChanged, quit, &QPushButton::setEnabled ); + QObject::connect( viewManager, &Calamares::ViewManager::quitLabelChanged, quit, &QPushButton::setText ); + QObject::connect( + viewManager, &Calamares::ViewManager::quitIconChanged, [=]( QString n ) { setButtonIcon( quit, n ); } ); + QObject::connect( viewManager, &Calamares::ViewManager::quitTooltipChanged, quit, &QPushButton::setToolTip ); + QObject::connect( viewManager, &Calamares::ViewManager::quitVisibleChanged, quit, &QPushButton::setVisible ); bottomLayout->addWidget( quit ); } @@ -199,50 +209,67 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent ) } #ifdef WITH_QML -QWidget* -CalamaresWindow::getQmlSidebar( QWidget* parent, int ) + +static inline void +setDimension( QQuickWidget* w, Qt::Orientation o, int desiredWidth ) +{ + w->setSizePolicy( o == Qt::Orientation::Vertical ? QSizePolicy::MinimumExpanding : QSizePolicy::Expanding, + o == Qt::Orientation::Horizontal ? QSizePolicy::MinimumExpanding : QSizePolicy::Expanding ); + if ( o == Qt::Orientation::Vertical ) + { + w->setFixedWidth( desiredWidth ); + } + else + { + // If the QML itself sets a height, use that, otherwise go to 48 pixels + // which seems to match what the widget navigation would use for height + // (with *my* specific screen, style, etc. so YMMV). + // + // Bound between (16, 64) with a default of 48. + qreal minimumHeight = qBound( qreal( 16 ), w->rootObject() ? w->rootObject()->height() : 48, qreal( 64 ) ); + w->setMinimumHeight( int( minimumHeight ) ); + w->setFixedHeight( int( minimumHeight ) ); + } + w->setResizeMode( QQuickWidget::SizeRootObjectToView ); +} + + +static QWidget* +getQmlSidebar( CalamaresWindow*, Calamares::ViewManager*, QWidget* parent, Qt::Orientation o, int desiredWidth ) { CalamaresUtils::registerQmlModels(); QQuickWidget* w = new QQuickWidget( parent ); - w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - w->setResizeMode( QQuickWidget::SizeRootObjectToView ); w->setSource( QUrl( CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) ); + setDimension( w, o, desiredWidth ); return w; } -QWidget* -CalamaresWindow::getQmlNavigation( QWidget* parent ) +static QWidget* +getQmlNavigation( CalamaresWindow*, Calamares::ViewManager*, QWidget* parent, Qt::Orientation o, int desiredWidth ) { CalamaresUtils::registerQmlModels(); QQuickWidget* w = new QQuickWidget( parent ); - w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - w->setResizeMode( QQuickWidget::SizeRootObjectToView ); w->setSource( QUrl( CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-navigation" ) ) ) ); - - // If the QML itself sets a height, use that, otherwise go to 48 pixels - // which seems to match what the widget navigation would use for height - // (with *my* specific screen, style, etc. so YMMV). - qreal minimumHeight = qBound( qreal( 16 ), w->rootObject() ? w->rootObject()->height() : 48, qreal( 64 ) ); - w->setMinimumHeight( int( minimumHeight ) ); - + setDimension( w, o, desiredWidth ); return w; } #else // Bogus to keep the linker happy -QWidget* -CalamaresWindow::getQmlSidebar( QWidget*, int ) +// +// Calls to flavoredWidget() still refer to these *names* +// even if they are subsequently not used. +static QWidget* +getQmlSidebar( CalamaresWindow*, Calamares::ViewManager*, QWidget* parent, Qt::Orientation, int desiredWidth ) { return nullptr; } -QWidget* -CalamaresWindow::getQmlNavigation( QWidget* ) +static QWidget* +getQmlNavigation( CalamaresWindow*, Calamares::ViewManager*, QWidget* parent, Qt::Orientation, int desiredWidth ) { return nullptr; } - - #endif /**@brief Picks one of two methods to call @@ -253,6 +280,7 @@ CalamaresWindow::getQmlNavigation( QWidget* ) template < typename widgetMaker, typename... args > QWidget* flavoredWidget( Calamares::Branding::PanelFlavor flavor, + Qt::Orientation o, CalamaresWindow* w, QWidget* parent, widgetMaker widget, @@ -262,14 +290,14 @@ flavoredWidget( Calamares::Branding::PanelFlavor flavor, #ifndef WITH_QML Q_UNUSED( qml ) #endif - // Member-function calling syntax is (object.*member)(args) + auto* viewManager = Calamares::ViewManager::instance(); switch ( flavor ) { case Calamares::Branding::PanelFlavor::Widget: - return ( w->*widget )( parent, a... ); + return widget( w, viewManager, parent, o, a... ); #ifdef WITH_QML case Calamares::Branding::PanelFlavor::Qml: - return ( w->*qml )( parent, a... ); + return qml( w, viewManager, parent, o, a... ); #endif case Calamares::Branding::PanelFlavor::None: return nullptr; @@ -371,16 +399,19 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) QWidget* sideBox = flavoredWidget( branding->sidebarFlavor(), + ::orientation( branding->sidebarSide() ), this, baseWidget, - &CalamaresWindow::getWidgetSidebar, - &CalamaresWindow::getQmlSidebar, + ::getWidgetSidebar, + ::getQmlSidebar, qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) ); QWidget* navigation = flavoredWidget( branding->navigationFlavor(), + ::orientation( branding->sidebarSide() ), this, baseWidget, - &CalamaresWindow::getWidgetNavigation, - &CalamaresWindow::getQmlNavigation ); + ::getWidgetNavigation, + ::getQmlNavigation, + 64 ); // Build up the contentsLayout (a VBox) top-to-bottom // .. note that the bottom is mirrored wrt. the top @@ -430,6 +461,29 @@ CalamaresWindow::ensureSize( QSize size ) resize( w, h ); } +void +CalamaresWindow::showDebugWindow( bool show ) +{ + if ( show ) + { + m_debugWindow = new Calamares::DebugWindow(); + m_debugWindow->show(); + connect( m_debugWindow.data(), &Calamares::DebugWindow::closed, this, [=]() { + m_debugWindow->deleteLater(); + emit debugWindowShown( false ); + } ); + emit debugWindowShown( true ); + } + else + { + if ( m_debugWindow ) + { + m_debugWindow->deleteLater(); + } + emit debugWindowShown( false ); + } +} + void CalamaresWindow::closeEvent( QCloseEvent* event ) { diff --git a/src/calamares/CalamaresWindow.h b/src/calamares/CalamaresWindow.h index 009425aae..713094ebe 100644 --- a/src/calamares/CalamaresWindow.h +++ b/src/calamares/CalamaresWindow.h @@ -30,7 +30,7 @@ public: CalamaresWindow( QWidget* parent = nullptr ); ~CalamaresWindow() override {} -public slots: +public Q_SLOTS: /** * This asks the main window to grow to accomodate @p size pixels, to accomodate * larger-than-expected window contents. The enlargement may be silently @@ -38,18 +38,21 @@ public slots: */ void ensureSize( QSize size ); + /** @brief Set visibility of debug window + * + * Shows or hides the debug window, depending on @p show. + * If Calamares is not in debug mode, nothing happens and the debug + * window remains hidden. + */ + void showDebugWindow( bool show ); + +Q_SIGNALS: + void debugWindowShown( bool show ); + protected: virtual void closeEvent( QCloseEvent* e ) override; private: - // Two variations on sidebar (the progress view) - QWidget* getWidgetSidebar( QWidget* parent, int desiredWidth ); - QWidget* getQmlSidebar( QWidget* parent, int desiredWidth ); - - // Two variations on navigation (buttons at bottom) - QWidget* getWidgetNavigation( QWidget* parent ); - QWidget* getQmlNavigation( QWidget* parent ); - QPointer< Calamares::DebugWindow > m_debugWindow; // Managed by self Calamares::ViewManager* m_viewManager; };