Merge branch 'progress-model'

This commit is contained in:
Adriaan de Groot 2020-03-11 19:39:58 +01:00
commit c628192163
18 changed files with 251 additions and 685 deletions

View File

@ -41,6 +41,12 @@ windowSize: 800px,520px
# *windowExpanding* set to "fullscreen"). # *windowExpanding* set to "fullscreen").
windowPlacement: center 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. # These are strings shown to the user in the user interface.
# There is no provision for translating them -- since they # There is no provision for translating them -- since they
# are names, the string is included as-is. # are names, the string is included as-is.

View File

@ -7,10 +7,7 @@ set( calamaresSources
VariantModel.cpp VariantModel.cpp
progresstree/ProgressTreeDelegate.cpp progresstree/ProgressTreeDelegate.cpp
progresstree/ProgressTreeItem.cpp
progresstree/ProgressTreeModel.cpp
progresstree/ProgressTreeView.cpp progresstree/ProgressTreeView.cpp
progresstree/ViewStepItem.cpp
) )
include_directories( include_directories(

View File

@ -21,7 +21,6 @@
#include "CalamaresConfig.h" #include "CalamaresConfig.h"
#include "CalamaresVersion.h" #include "CalamaresVersion.h"
#include "CalamaresWindow.h" #include "CalamaresWindow.h"
#include "progresstree/ProgressTreeModel.h"
#include "progresstree/ProgressTreeView.h" #include "progresstree/ProgressTreeView.h"
#include "Branding.h" #include "Branding.h"
@ -339,8 +338,8 @@ CalamaresApplication::initViewSteps()
m_mainwindow->show(); m_mainwindow->show();
} }
ProgressTreeModel* m = new ProgressTreeModel( nullptr ); // ProgressTreeModel* m = new ProgressTreeModel( nullptr );
ProgressTreeView::instance()->setModel( m ); // ProgressTreeView::instance()->setModel( m );
cDebug() << "STARTUP: Window now visible and ProgressTreeView populated"; cDebug() << "STARTUP: Window now visible and ProgressTreeView populated";
const auto steps = Calamares::ViewManager::instance()->viewSteps(); const auto steps = Calamares::ViewManager::instance()->viewSteps();

View File

@ -37,6 +37,7 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QLabel> #include <QLabel>
#include <QQuickWidget>
#include <QTreeView> #include <QTreeView>
static inline int static inline int
@ -57,6 +58,86 @@ windowDimensionToPixels( const Calamares::Branding::WindowDimension& u )
return 0; return 0;
} }
QWidget*
CalamaresWindow::getWidgetSidebar( int desiredWidth )
{
const Calamares::Branding* const branding = Calamares::Branding::instance();
QWidget* sideBox = new QWidget( this );
sideBox->setObjectName( "sidebarApp" );
QBoxLayout* sideLayout = new QVBoxLayout;
sideBox->setLayout( sideLayout );
// Set this attribute into qss file
sideBox->setFixedWidth( desiredWidth );
sideBox->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
QHBoxLayout* logoLayout = new QHBoxLayout;
sideLayout->addLayout( logoLayout );
logoLayout->addStretch();
QLabel* logoLabel = new QLabel( sideBox );
logoLabel->setObjectName( "logoApp" );
//Define all values into qss file
{
QPalette plt = sideBox->palette();
sideBox->setAutoFillBackground( true );
plt.setColor( sideBox->backgroundRole(), branding->styleString( Calamares::Branding::SidebarBackground ) );
plt.setColor( sideBox->foregroundRole(), branding->styleString( Calamares::Branding::SidebarText ) );
sideBox->setPalette( plt );
logoLabel->setPalette( plt );
}
logoLabel->setAlignment( Qt::AlignCenter );
logoLabel->setFixedSize( 80, 80 );
logoLabel->setPixmap( branding->image( Calamares::Branding::ProductLogo, logoLabel->size() ) );
logoLayout->addWidget( logoLabel );
logoLayout->addStretch();
ProgressTreeView* tv = new ProgressTreeView( sideBox );
tv->setModel( Calamares::ViewManager::instance() );
tv->setFocusPolicy( Qt::NoFocus );
sideLayout->addWidget( tv );
if ( Calamares::Settings::instance()->debugMode() || ( Logger::logLevel() >= Logger::LOGVERBOSE ) )
{
QPushButton* debugWindowBtn = new QPushButton;
debugWindowBtn->setObjectName( "debugButton" );
CALAMARES_RETRANSLATE( debugWindowBtn->setText( tr( "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();
}
}
} );
}
CalamaresUtils::unmarginLayout( sideLayout );
return sideBox;
}
QWidget*
CalamaresWindow::getQmlSidebar( int desiredWidth )
{
QQuickWidget* w = new QQuickWidget( this );
w->setSource( QUrl( ":/sidebar.qml" ) );
return w;
}
CalamaresWindow::CalamaresWindow( QWidget* parent ) CalamaresWindow::CalamaresWindow( QWidget* parent )
: QWidget( parent ) : QWidget( parent )
, m_debugWindow( nullptr ) , m_debugWindow( nullptr )
@ -97,76 +178,30 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
cDebug() << Logger::SubEntry << "Proposed window size:" << w << h; cDebug() << Logger::SubEntry << "Proposed window size:" << w << h;
resize( w, h ); resize( w, h );
m_viewManager = Calamares::ViewManager::instance( this );
QBoxLayout* mainLayout = new QHBoxLayout; QBoxLayout* mainLayout = new QHBoxLayout;
setLayout( mainLayout ); setLayout( mainLayout );
QWidget* sideBox = new QWidget( this ); QWidget* sideBox = nullptr;
sideBox->setObjectName( "sidebarApp" ); switch ( branding->sidebarFlavor() )
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->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
QHBoxLayout* logoLayout = new QHBoxLayout;
sideLayout->addLayout( logoLayout );
logoLayout->addStretch();
QLabel* logoLabel = new QLabel( sideBox );
logoLabel->setObjectName( "logoApp" );
//Define all values into qss file
{ {
QPalette plt = sideBox->palette(); case Calamares::Branding::SidebarFlavor::Widget:
sideBox->setAutoFillBackground( true ); sideBox = getWidgetSidebar(
plt.setColor( sideBox->backgroundRole(), branding->styleString( Calamares::Branding::SidebarBackground ) ); qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
plt.setColor( sideBox->foregroundRole(), branding->styleString( Calamares::Branding::SidebarText ) ); break;
sideBox->setPalette( plt ); case Calamares::Branding::SidebarFlavor::Qml:
logoLabel->setPalette( plt ); sideBox = getQmlSidebar(
qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
break;
default:
sideBox = nullptr;
} }
logoLabel->setAlignment( Qt::AlignCenter ); if ( sideBox )
logoLabel->setFixedSize( 80, 80 );
logoLabel->setPixmap( branding->image( Calamares::Branding::ProductLogo, logoLabel->size() ) );
logoLayout->addWidget( logoLabel );
logoLayout->addStretch();
ProgressTreeView* tv = new ProgressTreeView( sideBox );
sideLayout->addWidget( tv );
tv->setFocusPolicy( Qt::NoFocus );
if ( Calamares::Settings::instance()->debugMode() || ( Logger::logLevel() >= Logger::LOGVERBOSE ) )
{ {
QPushButton* debugWindowBtn = new QPushButton; mainLayout->addWidget( sideBox );
debugWindowBtn->setObjectName( "debugButton" );
CALAMARES_RETRANSLATE( debugWindowBtn->setText( tr( "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();
}
}
} );
} }
CalamaresUtils::unmarginLayout( sideLayout );
CalamaresUtils::unmarginLayout( mainLayout );
m_viewManager = Calamares::ViewManager::instance( this );
if ( branding->windowExpands() ) if ( branding->windowExpands() )
{ {
connect( m_viewManager, &Calamares::ViewManager::enlarge, this, &CalamaresWindow::enlarge ); 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. // event, which is also the ViewManager's responsibility.
mainLayout->addWidget( m_viewManager->centralWidget() ); mainLayout->addWidget( m_viewManager->centralWidget() );
CalamaresUtils::unmarginLayout( mainLayout );
setStyleSheet( Calamares::Branding::instance()->stylesheet() ); setStyleSheet( Calamares::Branding::instance()->stylesheet() );
} }

View File

@ -51,6 +51,9 @@ protected:
virtual void closeEvent( QCloseEvent* e ) override; virtual void closeEvent( QCloseEvent* e ) override;
private: private:
QWidget* getWidgetSidebar( int desiredWidth );
QWidget* getQmlSidebar( int desiredWidth );
QPointer< Calamares::DebugWindow > m_debugWindow; // Managed by self QPointer< Calamares::DebugWindow > m_debugWindow; // Managed by self
Calamares::ViewManager* m_viewManager; Calamares::ViewManager* m_viewManager;
}; };

View File

@ -18,11 +18,10 @@
*/ */
#include "ProgressTreeDelegate.h" #include "ProgressTreeDelegate.h"
#include "ProgressTreeModel.h"
#include "CalamaresApplication.h" #include "CalamaresApplication.h"
#include "CalamaresWindow.h" #include "CalamaresWindow.h"
#include "ViewManager.h"
#include "Branding.h" #include "Branding.h"
#include "utils/CalamaresUtilsGui.h" #include "utils/CalamaresUtilsGui.h"
@ -87,7 +86,7 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter,
painter->setFont( font ); painter->setFont( font );
bool isCurrent = false; bool isCurrent = false;
isCurrent = index.data( ProgressTreeModel::ProgressTreeItemCurrentRole ).toBool(); isCurrent = index.data( Calamares::ViewManager::ProgressTreeItemCurrentRole ).toBool();
if ( isCurrent ) if ( isCurrent )
{ {

View File

@ -1,92 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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();
}

View File

@ -1,60 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef PROGRESSTREEITEM_H
#define PROGRESSTREEITEM_H
#include <QList>
#include <QVariant>
/**
* @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

View File

@ -1,227 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@ -1,60 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef PROGRESSTREEMODEL_H
#define PROGRESSTREEMODEL_H
#include <QAbstractItemModel>
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

View File

@ -23,37 +23,18 @@
#include "Branding.h" #include "Branding.h"
#include "ViewManager.h" #include "ViewManager.h"
ProgressTreeView* ProgressTreeView::s_instance = nullptr;
ProgressTreeView*
ProgressTreeView::instance()
{
return s_instance;
}
ProgressTreeView::ProgressTreeView( QWidget* parent ) 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" ); this->setObjectName( "sidebarMenuApp" );
setFrameShape( QFrame::NoFrame ); setFrameShape( QFrame::NoFrame );
setContentsMargins( 0, 0, 0, 0 ); setContentsMargins( 0, 0, 0, 0 );
setHeaderHidden( true );
setRootIsDecorated( true );
setExpandsOnDoubleClick( true );
setSelectionMode( QAbstractItemView::NoSelection ); setSelectionMode( QAbstractItemView::NoSelection );
setDragDropMode( QAbstractItemView::NoDragDrop ); setDragDropMode( QAbstractItemView::NoDragDrop );
setAcceptDrops( false ); setAcceptDrops( false );
setUniformRowHeights( false );
setIndentation( 0 ); setItemDelegate( new ProgressTreeDelegate( this ) );
setSortingEnabled( false );
m_delegate = new ProgressTreeDelegate( this );
setItemDelegate( m_delegate );
QPalette plt = palette(); QPalette plt = palette();
plt.setColor( QPalette::Base, plt.setColor( QPalette::Base,
@ -73,8 +54,7 @@ ProgressTreeView::setModel( QAbstractItemModel* model )
return; return;
} }
QTreeView::setModel( model ); QListView::setModel( model );
expandAll();
connect( connect(
Calamares::ViewManager::instance(), Calamares::ViewManager::instance(),

View File

@ -20,21 +20,16 @@
#ifndef PROGRESSTREEVIEW_H #ifndef PROGRESSTREEVIEW_H
#define PROGRESSTREEVIEW_H #define PROGRESSTREEVIEW_H
#include <QTreeView> #include <QListView>
class ProgressTreeDelegate;
/** /**
* @brief The ProgressTreeView class is a modified QTreeView which displays the * @brief The ProgressTreeView class is a modified QTreeView which displays the
* available view steps and the user's progress through them. * 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 Q_OBJECT
public: public:
static ProgressTreeView* instance();
explicit ProgressTreeView( QWidget* parent = nullptr ); explicit ProgressTreeView( QWidget* parent = nullptr );
virtual ~ProgressTreeView() override; virtual ~ProgressTreeView() override;
@ -42,10 +37,6 @@ public:
* @brief setModel assigns a model to this view. * @brief setModel assigns a model to this view.
*/ */
void setModel( QAbstractItemModel* model ) override; void setModel( QAbstractItemModel* model ) override;
private:
static ProgressTreeView* s_instance;
ProgressTreeDelegate* m_delegate;
}; };
#endif // PROGRESSTREEVIEW_H #endif // PROGRESSTREEVIEW_H

View File

@ -1,85 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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( "<b>Debug information</b>" );
if ( m_step )
{
toolTip.append( "<br/>Type:\tViewStep" );
toolTip.append( QString( "<br/>Pretty:\t%1" ).arg( m_step->prettyName() ) );
toolTip.append( QString( "<br/>Status:\t%1" ).arg( m_step->prettyStatus() ) );
toolTip.append( QString( "<br/>Source:\t%1" )
.arg( m_step->moduleInstanceKey().isValid() ? m_step->moduleInstanceKey().toString()
: QStringLiteral( "built-in" ) ) );
}
else
{
toolTip.append( "<br/>Type:\tDelegate" );
toolTip.append( QString( "<br/>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();
}

View File

@ -1,53 +0,0 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef VIEWSTEPITEM_H
#define VIEWSTEPITEM_H
#include "ProgressTreeItem.h"
#include <functional>
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

View File

@ -89,6 +89,7 @@ const QStringList Branding::s_styleEntryStrings =
// clang-format on // clang-format on
// *INDENT-ON* // *INDENT-ON*
const NamedEnumTable< Branding::WindowDimensionUnit >& const NamedEnumTable< Branding::WindowDimensionUnit >&
Branding::WindowDimension::suffixes() Branding::WindowDimension::suffixes()
{ {
@ -407,14 +408,24 @@ getString( const YAML::Node& doc, const char* key )
void void
Branding::initSimpleSettings( const YAML::Node& doc ) Branding::initSimpleSettings( const YAML::Node& doc )
{ {
// *INDENT-OFF*
// clang-format off
static const NamedEnumTable< WindowExpansion > expansionNames { static const NamedEnumTable< WindowExpansion > expansionNames {
{ QStringLiteral( "normal" ), WindowExpansion::Normal }, { QStringLiteral( "normal" ), WindowExpansion::Normal },
{ QStringLiteral( "fullscreen" ), WindowExpansion::Fullscreen }, { QStringLiteral( "fullscreen" ), WindowExpansion::Fullscreen },
{ QStringLiteral( "noexpand" ), WindowExpansion::Fixed } { QStringLiteral( "noexpand" ), WindowExpansion::Fixed }
}; };
static const NamedEnumTable< WindowPlacement > placementNames { 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; bool ok = false;
m_welcomeStyleCalamares = doc[ "welcomeStyleCalamares" ].as< bool >( 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" cWarning() << "Branding module-setting *windowPlacement* interpreted as"
<< placementNames.find( m_windowPlacement, ok ); << 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" ); QString windowSize = getString( doc, "windowSize" );
if ( !windowSize.isEmpty() ) if ( !windowSize.isEmpty() )

View File

@ -122,6 +122,15 @@ public:
Center, Center,
Free 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(); static Branding* instance();
@ -175,6 +184,9 @@ public:
} }
bool windowPlacementCentered() const { return m_windowPlacement == WindowPlacement::Center; } 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 * Creates a map called "branding" in the global storage, and inserts an
* entry for each of the branding strings. This makes the branding * entry for each of the branding strings. This makes the branding
@ -214,6 +226,8 @@ private:
WindowExpansion m_windowExpansion; WindowExpansion m_windowExpansion;
WindowDimension m_windowHeight, m_windowWidth; WindowDimension m_windowHeight, m_windowWidth;
WindowPlacement m_windowPlacement; WindowPlacement m_windowPlacement;
SidebarFlavor m_sidebarFlavor = SidebarFlavor::Widget;
}; };
template < typename U > template < typename U >

View File

@ -75,7 +75,7 @@ setButtonIcon( QPushButton* button, const QString& name )
} }
ViewManager::ViewManager( QObject* parent ) ViewManager::ViewManager( QObject* parent )
: QObject( parent ) : QAbstractListModel( parent )
, m_currentStep( 0 ) , m_currentStep( 0 )
, m_widget( new QWidget() ) , m_widget( new QWidget() )
{ {
@ -157,6 +157,7 @@ ViewManager::addViewStep( ViewStep* step )
void void
ViewManager::insertViewStep( int before, ViewStep* step ) ViewManager::insertViewStep( int before, ViewStep* step )
{ {
emit beginInsertRows( QModelIndex(), before, before );
m_steps.insert( before, step ); m_steps.insert( before, step );
connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge ); connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge );
connect( step, &ViewStep::nextStatusChanged, this, [this]( bool status ) { 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->insertWidget( before, step->widget() );
m_stack->setCurrentIndex( 0 ); m_stack->setCurrentIndex( 0 );
step->widget()->setFocus(); step->widget()->setFocus();
emit endInsertRows();
} }
@ -507,4 +509,85 @@ ViewManager::updateCancelEnabled( bool enabled )
emit cancelEnabled( 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( "<b>Debug information</b>" );
toolTip.append( "<br/>Type:\tViewStep" );
toolTip.append( QString( "<br/>Pretty:\t%1" ).arg( step->prettyName() ) );
toolTip.append( QString( "<br/>Status:\t%1" ).arg( step->prettyStatus() ) );
toolTip.append(
QString( "<br/>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 } // namespace Calamares

View File

@ -23,6 +23,7 @@
#include "DllMacro.h" #include "DllMacro.h"
#include "viewpages/ViewStep.h" #include "viewpages/ViewStep.h"
#include <QAbstractListModel>
#include <QList> #include <QList>
#include <QPushButton> #include <QPushButton>
#include <QStackedWidget> #include <QStackedWidget>
@ -33,7 +34,7 @@ namespace Calamares
* @brief The ViewManager class handles progression through view pages. * @brief The ViewManager class handles progression through view pages.
* @note Singleton object, only use through ViewManager::instance(). * @note Singleton object, only use through ViewManager::instance().
*/ */
class UIDLLEXPORT ViewManager : public QObject class UIDLLEXPORT ViewManager : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -147,6 +148,23 @@ private:
QPushButton* m_back; QPushButton* m_back;
QPushButton* m_next; QPushButton* m_next;
QPushButton* m_quit; 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 } // namespace Calamares