calamares/src/modules/partition/core/PartitionModel.cpp

298 lines
9.7 KiB
C++
Raw Normal View History

/* === This file is part of Calamares - <https://github.com/calamares> ===
2014-06-27 17:25:39 +02:00
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
2014-06-27 17:25:39 +02:00
*
* 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 "core/PartitionModel.h"
#include "core/ColorUtils.h"
#include "core/PartitionInfo.h"
#include "core/KPMHelpers.h"
#include "partition/FileSystem.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
2014-06-30 15:03:29 +02:00
2014-06-27 17:25:39 +02:00
// CalaPM
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h>
2014-06-27 17:25:39 +02:00
2014-07-02 17:25:59 +02:00
// KF5
#include <KFormat>
2014-07-29 13:36:48 +02:00
// Qt
#include <QColor>
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::isPartitionNew;
//- ResetHelper --------------------------------------------
PartitionModel::ResetHelper::ResetHelper( PartitionModel* model )
2014-08-05 09:54:30 +02:00
: m_model( model )
2014-06-27 17:25:39 +02:00
{
m_model->m_lock.lock();
m_model->beginResetModel();
2014-06-27 17:25:39 +02:00
}
PartitionModel::ResetHelper::~ResetHelper()
{
// We need to unlock the mutex before emitting the reset signal,
// because the reset will cause clients to start looking at the
// (new) data.
m_model->m_lock.unlock();
m_model->endResetModel();
}
//- PartitionModel -----------------------------------------
PartitionModel::PartitionModel( QObject* parent )
: QAbstractItemModel( parent )
, m_device( nullptr )
2014-06-27 17:25:39 +02:00
{
}
void
PartitionModel::init( Device* device , const OsproberEntryList& osproberEntries )
{
QMutexLocker lock(&m_lock);
beginResetModel();
m_device = device;
m_osproberEntries = osproberEntries;
2014-06-27 17:25:39 +02:00
endResetModel();
}
int
PartitionModel::columnCount( const QModelIndex& ) const
{
return ColumnCount;
}
2014-06-27 17:25:39 +02:00
int
PartitionModel::rowCount( const QModelIndex& parent ) const
{
Partition* parentPartition = partitionForIndex( parent );
if ( parentPartition )
return parentPartition->children().count();
PartitionTable* table = m_device->partitionTable();
return table ? table->children().count() : 0;
}
QModelIndex
PartitionModel::index( int row, int column, const QModelIndex& parent ) const
{
PartitionNode* parentPartition = parent.isValid()
2014-08-05 09:54:30 +02:00
? static_cast< PartitionNode* >( partitionForIndex( parent ) )
: static_cast< PartitionNode* >( m_device->partitionTable() );
if ( !parentPartition )
return QModelIndex();
auto lst = parentPartition->children();
if ( row < 0 || row >= lst.count() )
return QModelIndex();
if ( column < 0 || column >= ColumnCount )
return QModelIndex();
Partition* partition = parentPartition->children().at( row );
return createIndex( row, column, partition );
}
QModelIndex
PartitionModel::parent( const QModelIndex& child ) const
{
if ( !child.isValid() )
return QModelIndex();
Partition* partition = partitionForIndex( child );
2015-06-21 01:21:06 +02:00
if ( !partition )
return QModelIndex();
PartitionNode* parentNode = partition->parent();
if ( parentNode == m_device->partitionTable() )
return QModelIndex();
int row = 0;
for ( auto p : m_device->partitionTable()->children() )
{
if ( parentNode == p )
return createIndex( row, 0, parentNode );
++row;
}
cWarning() << "No parent found!";
return QModelIndex();
2014-06-27 17:25:39 +02:00
}
QVariant
PartitionModel::data( const QModelIndex& index, int role ) const
{
Partition* partition = partitionForIndex( index );
if ( !partition )
2014-06-27 17:25:39 +02:00
return QVariant();
switch ( role )
{
case Qt::DisplayRole:
{
int col = index.column();
if ( col == NameColumn )
2014-06-27 17:25:39 +02:00
{
if ( isPartitionFreeSpace( partition ) )
return tr( "Free Space" );
else
{
return isPartitionNew( partition )
? tr( "New partition" )
: partition->partitionPath();
}
}
if ( col == FileSystemColumn )
return CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
if ( col == MountPointColumn )
return PartitionInfo::mountPoint( partition );
if ( col == SizeColumn )
{
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
return KFormat().formatByteSize( size );
}
cDebug() << "Unknown column" << col;
return QVariant();
}
2014-07-29 13:36:48 +02:00
case Qt::DecorationRole:
if ( index.column() == NameColumn )
return ColorUtils::colorForPartition( partition );
2014-07-29 13:36:48 +02:00
else
return QVariant();
case Qt::ToolTipRole:
{
int col = index.column();
QString name;
if ( col == NameColumn )
{
if ( isPartitionFreeSpace( partition ) )
name = tr( "Free Space" );
else
{
name = isPartitionNew( partition )
? tr( "New partition" )
: partition->partitionPath();
}
}
QString prettyFileSystem = CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
QString prettySize = KFormat().formatByteSize( size );
return QVariant(name + " " + prettyFileSystem + " " + prettySize);
}
2014-07-29 13:37:12 +02:00
case SizeRole:
return ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
2014-07-29 15:56:00 +02:00
case IsFreeSpaceRole:
return isPartitionFreeSpace( partition );
case IsPartitionNewRole:
return isPartitionNew( partition );
2015-12-15 15:41:42 +01:00
case FileSystemLabelRole:
if ( partition->fileSystem().supportGetLabel() != FileSystem::cmdSupportNone &&
!partition->fileSystem().label().isEmpty() )
return partition->fileSystem().label();
return QVariant();
case FileSystemTypeRole:
return partition->fileSystem().type();
case PartitionPathRole:
2015-12-18 15:29:31 +01:00
return partition->partitionPath();
case PartitionPtrRole:
return qVariantFromValue( (void*)partition );
// Osprober roles:
case OsproberNameRole:
foreach ( const OsproberEntry& osproberEntry, m_osproberEntries )
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
!partition->fileSystem().uuid().isEmpty() &&
osproberEntry.uuid == partition->fileSystem().uuid() )
return osproberEntry.prettyName;
return QVariant();
case OsproberPathRole:
foreach ( const OsproberEntry& osproberEntry, m_osproberEntries )
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
!partition->fileSystem().uuid().isEmpty() &&
osproberEntry.uuid == partition->fileSystem().uuid() )
return osproberEntry.path;
return QVariant();
case OsproberCanBeResizedRole:
foreach ( const OsproberEntry& osproberEntry, m_osproberEntries )
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
!partition->fileSystem().uuid().isEmpty() &&
osproberEntry.uuid == partition->fileSystem().uuid() )
return osproberEntry.canBeResized;
return QVariant();
case OsproberRawLineRole:
foreach ( const OsproberEntry& osproberEntry, m_osproberEntries )
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
!partition->fileSystem().uuid().isEmpty() &&
osproberEntry.uuid == partition->fileSystem().uuid() )
return osproberEntry.line;
return QVariant();
case OsproberHomePartitionPathRole:
foreach ( const OsproberEntry& osproberEntry, m_osproberEntries )
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
!partition->fileSystem().uuid().isEmpty() &&
osproberEntry.uuid == partition->fileSystem().uuid() )
return osproberEntry.homePath;
return QVariant();
// end Osprober roles.
2014-06-27 17:25:39 +02:00
default:
return QVariant();
}
}
2014-07-25 13:13:04 +02:00
QVariant
PartitionModel::headerData( int section, Qt::Orientation, int role ) const
2014-07-25 13:13:04 +02:00
{
if ( role != Qt::DisplayRole )
return QVariant();
switch ( section )
{
case NameColumn:
return tr( "Name" );
case FileSystemColumn:
return tr( "File System" );
case MountPointColumn:
2014-07-28 15:00:30 +02:00
return tr( "Mount Point" );
2014-07-25 13:13:04 +02:00
case SizeColumn:
2014-07-28 15:00:30 +02:00
return tr( "Size" );
2014-07-25 13:13:04 +02:00
default:
cDebug() << "Unknown column" << section;
return QVariant();
}
}
Partition*
PartitionModel::partitionForIndex( const QModelIndex& index ) const
{
QMutexLocker lock(&m_lock);
if ( !index.isValid() )
return nullptr;
return reinterpret_cast< Partition* >( index.internalPointer() );
}
void
PartitionModel::update()
{
emit dataChanged( index( 0, 0 ), index( rowCount() - 1, columnCount() - 1 ) );
}