diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc index af1d39ca4..c3c0796cd 100644 --- a/src/branding/default/branding.desc +++ b/src/branding/default/branding.desc @@ -41,6 +41,12 @@ windowSize: 800px,520px # *windowExpanding* set to "fullscreen"). windowPlacement: center +# Kind of sidebar (panel on the left, showing progress). +# - "widget" or unset, use traditional sidebar (logo, items) +# - "none", hide it entirely +# - "qml", use sidebar.qml from branding folder +sidebar: none + # These are strings shown to the user in the user interface. # There is no provision for translating them -- since they # are names, the string is included as-is. diff --git a/src/calamares/CMakeLists.txt b/src/calamares/CMakeLists.txt index 9327af8e3..78245f614 100644 --- a/src/calamares/CMakeLists.txt +++ b/src/calamares/CMakeLists.txt @@ -7,10 +7,7 @@ set( calamaresSources VariantModel.cpp progresstree/ProgressTreeDelegate.cpp - progresstree/ProgressTreeItem.cpp - progresstree/ProgressTreeModel.cpp progresstree/ProgressTreeView.cpp - progresstree/ViewStepItem.cpp ) include_directories( diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 234d5d45c..2d36f5a49 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -21,7 +21,6 @@ #include "CalamaresConfig.h" #include "CalamaresVersion.h" #include "CalamaresWindow.h" -#include "progresstree/ProgressTreeModel.h" #include "progresstree/ProgressTreeView.h" #include "Branding.h" @@ -339,8 +338,8 @@ CalamaresApplication::initViewSteps() m_mainwindow->show(); } - ProgressTreeModel* m = new ProgressTreeModel( nullptr ); - ProgressTreeView::instance()->setModel( m ); + // ProgressTreeModel* m = new ProgressTreeModel( nullptr ); + // ProgressTreeView::instance()->setModel( m ); cDebug() << "STARTUP: Window now visible and ProgressTreeView populated"; const auto steps = Calamares::ViewManager::instance()->viewSteps(); diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp index 1c7ecf813..f65e0acdf 100644 --- a/src/calamares/CalamaresWindow.cpp +++ b/src/calamares/CalamaresWindow.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include static inline int @@ -57,58 +58,19 @@ windowDimensionToPixels( const Calamares::Branding::WindowDimension& u ) return 0; } -CalamaresWindow::CalamaresWindow( QWidget* parent ) - : QWidget( parent ) - , m_debugWindow( nullptr ) - , m_viewManager( nullptr ) -{ - // If we can never cancel, don't show the window-close button - if ( Calamares::Settings::instance()->disableCancel() ) - { - setWindowFlag( Qt::WindowCloseButtonHint, false ); - } - - CALAMARES_RETRANSLATE( setWindowTitle( Calamares::Settings::instance()->isSetupMode() - ? tr( "%1 Setup Program" ).arg( *Calamares::Branding::ProductName ) - : tr( "%1 Installer" ).arg( *Calamares::Branding::ProductName ) ); ) +QWidget* +CalamaresWindow::getWidgetSidebar( int desiredWidth ) +{ const Calamares::Branding* const branding = Calamares::Branding::instance(); - using CalamaresUtils::windowMinimumHeight; - using CalamaresUtils::windowMinimumWidth; - using CalamaresUtils::windowPreferredHeight; - using CalamaresUtils::windowPreferredWidth; - - // Needs to match what's checked in DebugWindow - this->setObjectName( "mainApp" ); - - QSize availableSize = qApp->desktop()->availableGeometry( this ).size(); - QSize minimumSize( qBound( windowMinimumWidth, availableSize.width(), windowPreferredWidth ), - qBound( windowMinimumHeight, availableSize.height(), windowPreferredHeight ) ); - setMinimumSize( minimumSize ); - - cDebug() << "Available desktop" << availableSize << "minimum size" << minimumSize; - - auto brandingSizes = branding->windowSize(); - - int w = qBound( minimumSize.width(), windowDimensionToPixels( brandingSizes.first ), availableSize.width() ); - int h = qBound( minimumSize.height(), windowDimensionToPixels( brandingSizes.second ), availableSize.height() ); - - cDebug() << Logger::SubEntry << "Proposed window size:" << w << h; - resize( w, h ); - - QBoxLayout* mainLayout = new QHBoxLayout; - setLayout( mainLayout ); - QWidget* sideBox = new QWidget( this ); sideBox->setObjectName( "sidebarApp" ); - mainLayout->addWidget( sideBox ); QBoxLayout* sideLayout = new QVBoxLayout; sideBox->setLayout( sideLayout ); // Set this attribute into qss file - sideBox->setFixedWidth( - qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) ); + sideBox->setFixedWidth( desiredWidth ); sideBox->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); QHBoxLayout* logoLayout = new QHBoxLayout; @@ -132,8 +94,9 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) logoLayout->addStretch(); ProgressTreeView* tv = new ProgressTreeView( sideBox ); - sideLayout->addWidget( tv ); + tv->setModel( Calamares::ViewManager::instance() ); tv->setFocusPolicy( Qt::NoFocus ); + sideLayout->addWidget( tv ); if ( Calamares::Settings::instance()->debugMode() || ( Logger::logLevel() >= Logger::LOGVERBOSE ) ) { @@ -164,9 +127,81 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) } CalamaresUtils::unmarginLayout( sideLayout ); - CalamaresUtils::unmarginLayout( mainLayout ); + return sideBox; +} + +QWidget* +CalamaresWindow::getQmlSidebar( int desiredWidth ) +{ + QQuickWidget* w = new QQuickWidget( this ); + w->setSource( QUrl( ":/sidebar.qml" ) ); + return w; +} + +CalamaresWindow::CalamaresWindow( QWidget* parent ) + : QWidget( parent ) + , m_debugWindow( nullptr ) + , m_viewManager( nullptr ) +{ + // If we can never cancel, don't show the window-close button + if ( Calamares::Settings::instance()->disableCancel() ) + { + setWindowFlag( Qt::WindowCloseButtonHint, false ); + } + + CALAMARES_RETRANSLATE( setWindowTitle( Calamares::Settings::instance()->isSetupMode() + ? tr( "%1 Setup Program" ).arg( *Calamares::Branding::ProductName ) + : tr( "%1 Installer" ).arg( *Calamares::Branding::ProductName ) ); ) + + const Calamares::Branding* const branding = Calamares::Branding::instance(); + + using CalamaresUtils::windowMinimumHeight; + using CalamaresUtils::windowMinimumWidth; + using CalamaresUtils::windowPreferredHeight; + using CalamaresUtils::windowPreferredWidth; + + // Needs to match what's checked in DebugWindow + this->setObjectName( "mainApp" ); + + QSize availableSize = qApp->desktop()->availableGeometry( this ).size(); + QSize minimumSize( qBound( windowMinimumWidth, availableSize.width(), windowPreferredWidth ), + qBound( windowMinimumHeight, availableSize.height(), windowPreferredHeight ) ); + setMinimumSize( minimumSize ); + + cDebug() << "Available desktop" << availableSize << "minimum size" << minimumSize; + + auto brandingSizes = branding->windowSize(); + + int w = qBound( minimumSize.width(), windowDimensionToPixels( brandingSizes.first ), availableSize.width() ); + int h = qBound( minimumSize.height(), windowDimensionToPixels( brandingSizes.second ), availableSize.height() ); + + cDebug() << Logger::SubEntry << "Proposed window size:" << w << h; + resize( w, h ); m_viewManager = Calamares::ViewManager::instance( this ); + + QBoxLayout* mainLayout = new QHBoxLayout; + setLayout( mainLayout ); + + QWidget* sideBox = nullptr; + switch ( branding->sidebarFlavor() ) + { + case Calamares::Branding::SidebarFlavor::Widget: + sideBox = getWidgetSidebar( + qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) ); + break; + case Calamares::Branding::SidebarFlavor::Qml: + sideBox = getQmlSidebar( + qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) ); + break; + default: + sideBox = nullptr; + } + if ( sideBox ) + { + mainLayout->addWidget( sideBox ); + } + if ( branding->windowExpands() ) { connect( m_viewManager, &Calamares::ViewManager::enlarge, this, &CalamaresWindow::enlarge ); @@ -181,6 +216,7 @@ CalamaresWindow::CalamaresWindow( QWidget* parent ) // event, which is also the ViewManager's responsibility. mainLayout->addWidget( m_viewManager->centralWidget() ); + CalamaresUtils::unmarginLayout( mainLayout ); setStyleSheet( Calamares::Branding::instance()->stylesheet() ); } diff --git a/src/calamares/CalamaresWindow.h b/src/calamares/CalamaresWindow.h index 03ae560ec..5cbbdfca6 100644 --- a/src/calamares/CalamaresWindow.h +++ b/src/calamares/CalamaresWindow.h @@ -51,6 +51,9 @@ protected: virtual void closeEvent( QCloseEvent* e ) override; private: + QWidget* getWidgetSidebar( int desiredWidth ); + QWidget* getQmlSidebar( int desiredWidth ); + QPointer< Calamares::DebugWindow > m_debugWindow; // Managed by self Calamares::ViewManager* m_viewManager; }; diff --git a/src/calamares/progresstree/ProgressTreeDelegate.cpp b/src/calamares/progresstree/ProgressTreeDelegate.cpp index 9db508c6e..e7041d1b9 100644 --- a/src/calamares/progresstree/ProgressTreeDelegate.cpp +++ b/src/calamares/progresstree/ProgressTreeDelegate.cpp @@ -18,11 +18,10 @@ */ #include "ProgressTreeDelegate.h" -#include "ProgressTreeModel.h" #include "CalamaresApplication.h" #include "CalamaresWindow.h" - +#include "ViewManager.h" #include "Branding.h" #include "utils/CalamaresUtilsGui.h" @@ -87,7 +86,7 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter, painter->setFont( font ); bool isCurrent = false; - isCurrent = index.data( ProgressTreeModel::ProgressTreeItemCurrentRole ).toBool(); + isCurrent = index.data( Calamares::ViewManager::ProgressTreeItemCurrentRole ).toBool(); if ( isCurrent ) { diff --git a/src/calamares/progresstree/ProgressTreeItem.cpp b/src/calamares/progresstree/ProgressTreeItem.cpp deleted file mode 100644 index 4c5b5b0c3..000000000 --- a/src/calamares/progresstree/ProgressTreeItem.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#include "ProgressTreeItem.h" - -#include "ProgressTreeModel.h" - - -ProgressTreeItem::ProgressTreeItem( ProgressTreeItem* parent ) -{ - m_parentItem = parent; -} - - -ProgressTreeItem::~ProgressTreeItem() -{ - qDeleteAll( m_childItems ); -} - - -void -ProgressTreeItem::appendChild( ProgressTreeItem* item ) -{ - m_childItems.append( item ); -} - - -ProgressTreeItem* -ProgressTreeItem::child( int row ) -{ - return m_childItems.value( row ); -} - - -int -ProgressTreeItem::childCount() const -{ - return m_childItems.count(); -} - - -int -ProgressTreeItem::columnCount() const -{ - return 1; -} - - -int -ProgressTreeItem::row() const -{ - if ( m_parentItem ) - { - return m_parentItem->m_childItems.indexOf( const_cast< ProgressTreeItem* >( this ) ); - } - return 0; -} - - -ProgressTreeItem* -ProgressTreeItem::parent() -{ - return m_parentItem; -} - - -ProgressTreeRoot::ProgressTreeRoot() - : ProgressTreeItem() -{ -} - - -QVariant -ProgressTreeRoot::data( int ) const -{ - return QVariant(); -} diff --git a/src/calamares/progresstree/ProgressTreeItem.h b/src/calamares/progresstree/ProgressTreeItem.h deleted file mode 100644 index fd93ab0ef..000000000 --- a/src/calamares/progresstree/ProgressTreeItem.h +++ /dev/null @@ -1,60 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#ifndef PROGRESSTREEITEM_H -#define PROGRESSTREEITEM_H - -#include -#include - - -/** - * @brief The ProgressTreeItem class represents an item in the - * ProgressTreeModel/ProgressTreeView. - * Each item generally represents a ViewStep. - */ -class ProgressTreeItem -{ -public: - explicit ProgressTreeItem( ProgressTreeItem* parent = nullptr ); - - virtual ~ProgressTreeItem(); - - virtual void appendChild( ProgressTreeItem* item ); - - virtual ProgressTreeItem* child( int row ); - virtual int childCount() const; - virtual int columnCount() const; - virtual QVariant data( int role ) const = 0; - virtual int row() const; - virtual ProgressTreeItem* parent(); - -private: - QList< ProgressTreeItem* > m_childItems; - ProgressTreeItem* m_parentItem; -}; - -class ProgressTreeRoot : public ProgressTreeItem -{ -public: - explicit ProgressTreeRoot(); - - virtual QVariant data( int role ) const; -}; - -#endif // PROGRESSTREEITEM_H diff --git a/src/calamares/progresstree/ProgressTreeModel.cpp b/src/calamares/progresstree/ProgressTreeModel.cpp deleted file mode 100644 index d4b5a0321..000000000 --- a/src/calamares/progresstree/ProgressTreeModel.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014-2015, Teo Mrnjavac - * Copyright 2017, Adriaan de Groot - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#include "ProgressTreeModel.h" - -#include "ViewStepItem.h" - -#include "ViewManager.h" - -ProgressTreeModel::ProgressTreeModel( QObject* parent ) - : QAbstractItemModel( parent ) - , m_rootItem( nullptr ) -{ - setupModelData(); -} - - -ProgressTreeModel::~ProgressTreeModel() -{ - delete m_rootItem; -} - - -Qt::ItemFlags -ProgressTreeModel::flags( const QModelIndex& index ) const -{ - if ( !index.isValid() ) - { - return Qt::ItemFlags(); - } - - return Qt::ItemIsEnabled; -} - - -QModelIndex -ProgressTreeModel::index( int row, int column, const QModelIndex& parent ) const -{ - if ( !hasIndex( row, column, parent ) ) - { - return QModelIndex(); - } - - ProgressTreeItem* parentItem; - - if ( !parent.isValid() ) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast< ProgressTreeItem* >( parent.internalPointer() ); - } - - ProgressTreeItem* childItem = parentItem->child( row ); - if ( childItem ) - { - return createIndex( row, column, childItem ); - } - else - { - return QModelIndex(); - } -} - - -QModelIndex -ProgressTreeModel::parent( const QModelIndex& index ) const -{ - if ( !index.isValid() ) - { - return QModelIndex(); - } - - ProgressTreeItem* childItem = static_cast< ProgressTreeItem* >( index.internalPointer() ); - ProgressTreeItem* parentItem = childItem->parent(); - - if ( parentItem == m_rootItem ) - { - return QModelIndex(); - } - - return createIndex( parentItem->row(), 0, parentItem ); -} - - -QVariant -ProgressTreeModel::data( const QModelIndex& index, int role ) const -{ - if ( !index.isValid() ) - { - return QVariant(); - } - - ProgressTreeItem* item = static_cast< ProgressTreeItem* >( index.internalPointer() ); - - return item->data( role ); -} - - -QVariant -ProgressTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const -{ - Q_UNUSED( section ) - Q_UNUSED( orientation ) - Q_UNUSED( role ) - - return QVariant(); -} - - -int -ProgressTreeModel::rowCount( const QModelIndex& parent ) const -{ - ProgressTreeItem* parentItem; - if ( parent.column() > 0 ) - { - return 0; - } - - if ( !parent.isValid() ) - { - parentItem = m_rootItem; - } - else - { - parentItem = static_cast< ProgressTreeItem* >( parent.internalPointer() ); - } - - return parentItem->childCount(); -} - - -int -ProgressTreeModel::columnCount( const QModelIndex& parent ) const -{ - if ( parent.isValid() ) - { - return static_cast< ProgressTreeItem* >( parent.internalPointer() )->columnCount(); - } - else - { - return m_rootItem->columnCount(); - } -} - - -void -ProgressTreeModel::setupModelData() -{ - delete m_rootItem; - - m_rootItem = new ProgressTreeRoot(); - const Calamares::ViewManager* vm = Calamares::ViewManager::instance(); - - const auto steps = vm->viewSteps(); - for ( const Calamares::ViewStep* step : steps ) - { - m_rootItem->appendChild( new ViewStepItem( step, m_rootItem ) ); - } -} - - -QModelIndex -ProgressTreeModel::indexFromItem( ProgressTreeItem* item ) -{ - if ( !item || !item->parent() ) - { - return QModelIndex(); - } - - // Reconstructs a QModelIndex from a ProgressTreeItem that is somewhere in the tree. - // Traverses the item to the root node, then rebuilds the qmodelindices from there - // back down; each int is the row of that item in the parent. - /** - * In this diagram, if the item is G, childIndexList will contain [0, 2, 0] - * - * A - * D - * E - * F - * G - * H - * B - * C - * - **/ - QList< int > childIndexList; - ProgressTreeItem* curItem = item; - while ( curItem != m_rootItem ) - { - int row = curItem->row(); //relative to its parent - if ( row < 0 ) // something went wrong, bail - { - return QModelIndex(); - } - - childIndexList << row; - - curItem = curItem->parent(); - } - - // Now we rebuild the QModelIndex we need - QModelIndex idx; - for ( int i = childIndexList.size() - 1; i >= 0; i-- ) - { - idx = index( childIndexList[ i ], 0, idx ); - } - - return idx; -} diff --git a/src/calamares/progresstree/ProgressTreeModel.h b/src/calamares/progresstree/ProgressTreeModel.h deleted file mode 100644 index e424f9d8d..000000000 --- a/src/calamares/progresstree/ProgressTreeModel.h +++ /dev/null @@ -1,60 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014, Teo Mrnjavac - * Copyright 2017, Adriaan de Groot - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#ifndef PROGRESSTREEMODEL_H -#define PROGRESSTREEMODEL_H - -#include - -class ProgressTreeRoot; -class ProgressTreeItem; - - -/** - * @brief The ProgressTreeModel class implements a model for the ProgressTreeView. - */ -class ProgressTreeModel : public QAbstractItemModel -{ - Q_OBJECT -public: - enum Role - { - ProgressTreeItemCurrentRole = Qt::UserRole + 11 - }; - - explicit ProgressTreeModel( QObject* parent = nullptr ); - virtual ~ProgressTreeModel() override; - - // Reimplemented from QAbstractItemModel - Qt::ItemFlags flags( const QModelIndex& index ) const override; - QModelIndex index( int row, int column, const QModelIndex& parent = QModelIndex() ) const override; - QModelIndex parent( const QModelIndex& index ) const override; - QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; - QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - int rowCount( const QModelIndex& parent = QModelIndex() ) const override; - int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - -private: - void setupModelData(); - QModelIndex indexFromItem( ProgressTreeItem* item ); - - ProgressTreeRoot* m_rootItem; -}; - -#endif // PROGRESSTREEMODEL_H diff --git a/src/calamares/progresstree/ProgressTreeView.cpp b/src/calamares/progresstree/ProgressTreeView.cpp index d4f652363..22b11bfc6 100644 --- a/src/calamares/progresstree/ProgressTreeView.cpp +++ b/src/calamares/progresstree/ProgressTreeView.cpp @@ -23,37 +23,18 @@ #include "Branding.h" #include "ViewManager.h" -ProgressTreeView* ProgressTreeView::s_instance = nullptr; - -ProgressTreeView* -ProgressTreeView::instance() -{ - return s_instance; -} - ProgressTreeView::ProgressTreeView( QWidget* parent ) - : QTreeView( parent ) + : QListView( parent ) { - s_instance = this; //FIXME: should assert when s_instance gets written and it wasn't nullptr - this->setObjectName( "sidebarMenuApp" ); setFrameShape( QFrame::NoFrame ); setContentsMargins( 0, 0, 0, 0 ); - setHeaderHidden( true ); - setRootIsDecorated( true ); - setExpandsOnDoubleClick( true ); - setSelectionMode( QAbstractItemView::NoSelection ); setDragDropMode( QAbstractItemView::NoDragDrop ); setAcceptDrops( false ); - setUniformRowHeights( false ); - - setIndentation( 0 ); - setSortingEnabled( false ); - m_delegate = new ProgressTreeDelegate( this ); - setItemDelegate( m_delegate ); + setItemDelegate( new ProgressTreeDelegate( this ) ); QPalette plt = palette(); plt.setColor( QPalette::Base, @@ -73,8 +54,7 @@ ProgressTreeView::setModel( QAbstractItemModel* model ) return; } - QTreeView::setModel( model ); - expandAll(); + QListView::setModel( model ); connect( Calamares::ViewManager::instance(), diff --git a/src/calamares/progresstree/ProgressTreeView.h b/src/calamares/progresstree/ProgressTreeView.h index 0b48a5f2a..4a1bf9f2d 100644 --- a/src/calamares/progresstree/ProgressTreeView.h +++ b/src/calamares/progresstree/ProgressTreeView.h @@ -20,21 +20,16 @@ #ifndef PROGRESSTREEVIEW_H #define PROGRESSTREEVIEW_H -#include - -class ProgressTreeDelegate; +#include /** * @brief The ProgressTreeView class is a modified QTreeView which displays the * available view steps and the user's progress through them. - * @note singleton, only access through ProgressTreeView::instance(). */ -class ProgressTreeView : public QTreeView +class ProgressTreeView : public QListView { Q_OBJECT public: - static ProgressTreeView* instance(); - explicit ProgressTreeView( QWidget* parent = nullptr ); virtual ~ProgressTreeView() override; @@ -42,10 +37,6 @@ public: * @brief setModel assigns a model to this view. */ void setModel( QAbstractItemModel* model ) override; - -private: - static ProgressTreeView* s_instance; - ProgressTreeDelegate* m_delegate; }; #endif // PROGRESSTREEVIEW_H diff --git a/src/calamares/progresstree/ViewStepItem.cpp b/src/calamares/progresstree/ViewStepItem.cpp deleted file mode 100644 index bbb2846ce..000000000 --- a/src/calamares/progresstree/ViewStepItem.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014-2015, Teo Mrnjavac - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#include "ViewStepItem.h" - -#include "ProgressTreeModel.h" - -#include "Settings.h" -#include "ViewManager.h" -#include "viewpages/ViewStep.h" - - -ViewStepItem::ViewStepItem( std::function< QString() > prettyName, - std::function< const Calamares::ViewStep*() > accessor, - ProgressTreeItem* parent ) - : ProgressTreeItem( parent ) - , m_accessor( accessor ) - , m_prettyName( prettyName ) - , m_step( nullptr ) -{ -} - - -ViewStepItem::ViewStepItem( const Calamares::ViewStep* step, ProgressTreeItem* parent ) - : ProgressTreeItem( parent ) - , m_step( step ) -{ -} - -void -ViewStepItem::appendChild( ProgressTreeItem* item ) -{ - Q_ASSERT( false ); - Q_UNUSED( item ) -} - - -QVariant -ViewStepItem::data( int role ) const -{ - if ( role == Qt::DisplayRole ) - { - return m_step ? m_step->prettyName() : m_prettyName(); - } - if ( Calamares::Settings::instance()->debugMode() && role == Qt::ToolTipRole ) - { - QString toolTip( "Debug information" ); - if ( m_step ) - { - toolTip.append( "
Type:\tViewStep" ); - toolTip.append( QString( "
Pretty:\t%1" ).arg( m_step->prettyName() ) ); - toolTip.append( QString( "
Status:\t%1" ).arg( m_step->prettyStatus() ) ); - toolTip.append( QString( "
Source:\t%1" ) - .arg( m_step->moduleInstanceKey().isValid() ? m_step->moduleInstanceKey().toString() - : QStringLiteral( "built-in" ) ) ); - } - else - { - toolTip.append( "
Type:\tDelegate" ); - toolTip.append( QString( "
Pretty:\t%1" ).arg( m_prettyName() ) ); - } - return toolTip; - } - if ( role == ProgressTreeModel::ProgressTreeItemCurrentRole ) - { - return m_step ? ( Calamares::ViewManager::instance()->currentStep() == m_step ) - : ( Calamares::ViewManager::instance()->currentStep() == m_accessor() ); - } - return QVariant(); -} diff --git a/src/calamares/progresstree/ViewStepItem.h b/src/calamares/progresstree/ViewStepItem.h deleted file mode 100644 index 84b9e0e98..000000000 --- a/src/calamares/progresstree/ViewStepItem.h +++ /dev/null @@ -1,53 +0,0 @@ -/* === This file is part of Calamares - === - * - * Copyright 2014-2015, Teo Mrnjavac - * - * Calamares is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Calamares is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Calamares. If not, see . - */ - -#ifndef VIEWSTEPITEM_H -#define VIEWSTEPITEM_H - -#include "ProgressTreeItem.h" - -#include - -namespace Calamares -{ -class ViewStep; -} - -class ViewStepItem : public ProgressTreeItem -{ -public: - // We take a std::function< QString() > instead of a QString because the view asks for - // new strings on LanguageChange, and tr needs to be called again in that case. - explicit ViewStepItem( std::function< QString() > prettyName, - std::function< const Calamares::ViewStep*() > accessor, - ProgressTreeItem* parent = nullptr ); - - explicit ViewStepItem( const Calamares::ViewStep* step, ProgressTreeItem* parent = nullptr ); - - void appendChild( ProgressTreeItem* item ) override; - - QVariant data( int role ) const override; - -private: - const std::function< const Calamares::ViewStep*() > m_accessor; - const std::function< QString() > m_prettyName; - const Calamares::ViewStep* const m_step; -}; - - -#endif // VIEWSTEPITEM_H diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 9bdccfa51..34ba23436 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -89,6 +89,7 @@ const QStringList Branding::s_styleEntryStrings = // clang-format on // *INDENT-ON* + const NamedEnumTable< Branding::WindowDimensionUnit >& Branding::WindowDimension::suffixes() { @@ -407,14 +408,24 @@ getString( const YAML::Node& doc, const char* key ) void Branding::initSimpleSettings( const YAML::Node& doc ) { + // *INDENT-OFF* + // clang-format off static const NamedEnumTable< WindowExpansion > expansionNames { { QStringLiteral( "normal" ), WindowExpansion::Normal }, { QStringLiteral( "fullscreen" ), WindowExpansion::Fullscreen }, { QStringLiteral( "noexpand" ), WindowExpansion::Fixed } }; static const NamedEnumTable< WindowPlacement > placementNames { - { QStringLiteral( "free" ), WindowPlacement::Free }, { QStringLiteral( "center" ), WindowPlacement::Center } + { QStringLiteral( "free" ), WindowPlacement::Free }, + { QStringLiteral( "center" ), WindowPlacement::Center } }; + static const NamedEnumTable< SidebarFlavor > sidebarFlavorNames { + { QStringLiteral( "widget" ), SidebarFlavor::Widget }, + { QStringLiteral( "none" ), SidebarFlavor::None }, + { QStringLiteral( "qml" ), SidebarFlavor::Qml } + }; + // clang-format on + // *INDENT-ON* bool ok = false; m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( false ); @@ -431,6 +442,12 @@ Branding::initSimpleSettings( const YAML::Node& doc ) cWarning() << "Branding module-setting *windowPlacement* interpreted as" << placementNames.find( m_windowPlacement, ok ); } + m_sidebarFlavor = sidebarFlavorNames.find( getString( doc, "sidebar" ), ok ); + if ( !ok ) + { + cWarning() << "Branding module-setting *sidebar* interpreted as" + << sidebarFlavorNames.find( m_sidebarFlavor, ok ); + } QString windowSize = getString( doc, "windowSize" ); if ( !windowSize.isEmpty() ) diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 3dfcd0586..88f658473 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -122,6 +122,15 @@ public: Center, Free }; + Q_ENUM( WindowPlacement ) + ///@brief What kind of sidebar to use in the main window + enum class SidebarFlavor + { + None, + Widget, + Qml + }; + Q_ENUM( SidebarFlavor ) static Branding* instance(); @@ -175,6 +184,9 @@ public: } bool windowPlacementCentered() const { return m_windowPlacement == WindowPlacement::Center; } + ///@brief Which sidebar flavor is configured + SidebarFlavor sidebarFlavor() const { return m_sidebarFlavor; } + /** * Creates a map called "branding" in the global storage, and inserts an * entry for each of the branding strings. This makes the branding @@ -214,6 +226,8 @@ private: WindowExpansion m_windowExpansion; WindowDimension m_windowHeight, m_windowWidth; WindowPlacement m_windowPlacement; + + SidebarFlavor m_sidebarFlavor = SidebarFlavor::Widget; }; template < typename U > diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 7492f1f8b..96d4cc3a0 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -75,7 +75,7 @@ setButtonIcon( QPushButton* button, const QString& name ) } ViewManager::ViewManager( QObject* parent ) - : QObject( parent ) + : QAbstractListModel( parent ) , m_currentStep( 0 ) , m_widget( new QWidget() ) { @@ -157,6 +157,7 @@ ViewManager::addViewStep( ViewStep* step ) void ViewManager::insertViewStep( int before, ViewStep* step ) { + emit beginInsertRows( QModelIndex(), before, before ); m_steps.insert( before, step ); connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge ); connect( step, &ViewStep::nextStatusChanged, this, [this]( bool status ) { @@ -183,6 +184,7 @@ ViewManager::insertViewStep( int before, ViewStep* step ) m_stack->insertWidget( before, step->widget() ); m_stack->setCurrentIndex( 0 ); step->widget()->setFocus(); + emit endInsertRows(); } @@ -507,4 +509,85 @@ ViewManager::updateCancelEnabled( bool enabled ) emit cancelEnabled( enabled ); } +QVariant +ViewManager::data( const QModelIndex& index, int role ) const +{ + if ( !index.isValid() ) + { + return QVariant(); + } + + if ( ( index.row() < 0 ) || ( index.row() >= m_steps.length() ) ) + { + return QVariant(); + } + + const auto* step = m_steps.at( index.row() ); + if ( !step ) + { + return QVariant(); + } + + switch ( role ) + { + case Qt::DisplayRole: + return step->prettyName(); + case Qt::ToolTipRole: + if ( Calamares::Settings::instance()->debugMode() ) + { + auto key = step->moduleInstanceKey(); + QString toolTip( "Debug information" ); + toolTip.append( "
Type:\tViewStep" ); + toolTip.append( QString( "
Pretty:\t%1" ).arg( step->prettyName() ) ); + toolTip.append( QString( "
Status:\t%1" ).arg( step->prettyStatus() ) ); + toolTip.append( + QString( "
Source:\t%1" ).arg( key.isValid() ? key.toString() : QStringLiteral( "built-in" ) ) ); + return toolTip; + } + else + { + return QVariant(); + } + case ProgressTreeItemCurrentRole: + return currentStep() == step; + case ProgressTreeItemCompletedRole: + // Every step *before* the current step is considered "complete" + for ( const auto* otherstep : m_steps ) + { + if ( otherstep == currentStep() ) + { + break; + } + if ( otherstep == step ) + { + return true; + } + } + // .. and the others (including current) are not. + return false; + default: + return QVariant(); + } +} + + +int +ViewManager::rowCount( const QModelIndex& parent ) const +{ + if ( parent.column() > 0 ) + { + return 0; + } + return m_steps.length(); +} + +QHash< int, QByteArray > +ViewManager::roleNames() const +{ + auto h = QAbstractListModel::roleNames(); + h.insert( ProgressTreeItemCurrentRole, "current" ); + h.insert( ProgressTreeItemCompletedRole, "completed" ); + return h; +} + } // namespace Calamares diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 42fb9ad8f..7ca6eb377 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -23,6 +23,7 @@ #include "DllMacro.h" #include "viewpages/ViewStep.h" +#include #include #include #include @@ -33,7 +34,7 @@ namespace Calamares * @brief The ViewManager class handles progression through view pages. * @note Singleton object, only use through ViewManager::instance(). */ -class UIDLLEXPORT ViewManager : public QObject +class UIDLLEXPORT ViewManager : public QAbstractListModel { Q_OBJECT public: @@ -147,6 +148,23 @@ private: QPushButton* m_back; QPushButton* m_next; QPushButton* m_quit; + +public: + /** @section Model + * + * These are the methods and enums used for the as-a-model part + * of the ViewManager. + */ + enum Role + { + ProgressTreeItemCurrentRole = Qt::UserRole + 11, ///< Is this the *current* step? + ProgressTreeItemCompletedRole = Qt::UserRole + 12 ///< Are we past this one? + }; + + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; + + QHash< int, QByteArray > roleNames() const override; }; } // namespace Calamares