2008-09-24 20:32:01 +01:00
/***************************************************************************
2009-05-06 15:19:23 +01:00
* Copyright ( C ) 2008 , 2009 by Volker Lanz < vl @ fidra . de > *
2008-09-24 20:32:01 +01:00
* *
* This program 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 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program 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 this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "gui/partpropsdialog.h"
# include "gui/partpropswidget.h"
# include "core/partition.h"
# include "core/device.h"
# include "fs/filesystemfactory.h"
2009-05-05 20:33:55 +01:00
2008-09-24 20:32:01 +01:00
# include "util/capacity.h"
2009-05-05 20:33:55 +01:00
# include "util/helpers.h"
2008-09-24 20:32:01 +01:00
2014-05-13 23:53:37 +01:00
# include <QtAlgorithms>
2008-09-24 20:32:01 +01:00
# include <kmessagebox.h>
# include <kglobalsettings.h>
2014-05-13 23:53:37 +01:00
# include <KLocalizedString>
2008-09-24 20:32:01 +01:00
# include <kpushbutton.h>
# include <klineedit.h>
/** Creates a new PartPropsDialog
@ param parent pointer to the parent widget
@ param d the Device the Partition is on
@ param p the Partition to show properties for
*/
PartPropsDialog : : PartPropsDialog ( QWidget * parent , Device & d , Partition & p ) :
KDialog ( parent ) ,
m_Device ( d ) ,
m_Partition ( p ) ,
m_WarnFileSystemChange ( false ) ,
m_DialogWidget ( new PartPropsWidget ( this ) ) ,
2009-01-09 07:10:59 +00:00
m_ReadOnly ( partition ( ) . isMounted ( ) | | partition ( ) . state ( ) = = Partition : : StateCopy | | partition ( ) . state ( ) = = Partition : : StateRestore | | d . partitionTable ( ) - > isReadOnly ( ) ) ,
2008-09-24 20:32:01 +01:00
m_ForceRecreate ( false )
{
setMainWidget ( & dialogWidget ( ) ) ;
setCaption ( i18nc ( " @title:window " , " Partition properties: <filename>%1</filename> " , partition ( ) . deviceNode ( ) ) ) ;
setupDialog ( ) ;
setupConnections ( ) ;
restoreDialogSize ( KConfigGroup ( KGlobal : : config ( ) , " partPropsDialog " ) ) ;
}
/** Destroys a PartPropsDialog */
PartPropsDialog : : ~ PartPropsDialog ( )
{
KConfigGroup kcg ( KGlobal : : config ( ) , " partPropsDialog " ) ;
saveDialogSize ( kcg ) ;
}
/** @return the new label */
QString PartPropsDialog : : newLabel ( ) const
{
return dialogWidget ( ) . label ( ) . text ( ) ;
}
/** @return the new Partition flags */
PartitionTable : : Flags PartPropsDialog : : newFlags ( ) const
{
PartitionTable : : Flags flags ;
for ( int i = 0 ; i < dialogWidget ( ) . listFlags ( ) . count ( ) ; i + + )
if ( dialogWidget ( ) . listFlags ( ) . item ( i ) - > checkState ( ) = = Qt : : Checked )
flags | = static_cast < PartitionTable : : Flag > ( dialogWidget ( ) . listFlags ( ) . item ( i ) - > data ( Qt : : UserRole ) . toInt ( ) ) ;
return flags ;
}
/** @return the new FileSystem type */
FileSystem : : Type PartPropsDialog : : newFileSystemType ( ) const
{
return FileSystem : : typeForName ( dialogWidget ( ) . fileSystem ( ) . currentText ( ) ) ;
}
void PartPropsDialog : : setupDialog ( )
{
2008-11-02 19:21:36 +00:00
setDefaultButton ( KDialog : : Cancel ) ;
enableButtonOk ( false ) ;
button ( KDialog : : Cancel ) - > setFocus ( ) ;
2008-12-27 12:01:29 +00:00
2010-06-03 16:01:53 +01:00
dialogWidget ( ) . partWidget ( ) . init ( & partition ( ) ) ;
2008-09-24 20:32:01 +01:00
2010-05-17 16:17:15 +01:00
const QString mp = partition ( ) . mountPoint ( ) . isEmpty ( )
2010-05-16 13:19:04 +01:00
? i18nc ( " @item mountpoint " , " (none found) " )
2010-05-17 16:17:15 +01:00
: partition ( ) . mountPoint ( ) ;
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . mountPoint ( ) . setText ( mp ) ;
dialogWidget ( ) . role ( ) . setText ( partition ( ) . roles ( ) . toString ( ) ) ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
QString statusText = i18nc ( " @label partition state " , " idle " ) ;
if ( partition ( ) . isMounted ( ) )
{
if ( partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) )
statusText = i18nc ( " @label partition state " , " At least one logical partition is mounted. " ) ;
2010-05-17 16:17:15 +01:00
else if ( ! partition ( ) . mountPoint ( ) . isEmpty ( ) )
2008-09-24 20:32:01 +01:00
statusText = i18nc ( " @label partition state " , " mounted on <filename>%1</filename> " , mp ) ;
else
statusText = i18nc ( " @label partition state " , " mounted " ) ;
}
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . status ( ) . setText ( statusText ) ;
2009-05-06 15:19:23 +01:00
dialogWidget ( ) . uuid ( ) . setText ( partition ( ) . fileSystem ( ) . uuid ( ) . isEmpty ( ) ? i18nc ( " @item uuid " , " (none) " ) : partition ( ) . fileSystem ( ) . uuid ( ) ) ;
2008-09-24 20:32:01 +01:00
setupFileSystemComboBox ( ) ;
// don't do this before the file system combo box has been set up!
dialogWidget ( ) . label ( ) . setText ( newLabel ( ) . isEmpty ( ) ? partition ( ) . fileSystem ( ) . label ( ) : newLabel ( ) ) ;
2012-02-15 17:21:40 +00:00
dialogWidget ( ) . capacity ( ) . setText ( Capacity : : formatByteSize ( partition ( ) . capacity ( ) ) ) ;
2008-09-24 20:32:01 +01:00
2010-05-16 12:45:31 +01:00
if ( Capacity ( partition ( ) , Capacity : : Available ) . isValid ( ) )
{
const qint64 availPercent = ( partition ( ) . fileSystem ( ) . length ( ) - partition ( ) . fileSystem ( ) . sectorsUsed ( ) ) * 100 / partition ( ) . fileSystem ( ) . length ( ) ;
const QString availString = QString ( " %1% - %2 " )
. arg ( availPercent )
2012-02-15 17:21:40 +00:00
. arg ( Capacity : : formatByteSize ( partition ( ) . available ( ) ) ) ;
2010-05-16 12:45:31 +01:00
const QString usedString = QString ( " %1% - %2 " )
. arg ( 100 - availPercent )
2012-02-15 17:21:40 +00:00
. arg ( Capacity : : formatByteSize ( partition ( ) . used ( ) ) ) ;
2010-05-16 12:45:31 +01:00
dialogWidget ( ) . available ( ) . setText ( availString ) ;
dialogWidget ( ) . used ( ) . setText ( usedString ) ;
}
else
{
dialogWidget ( ) . available ( ) . setText ( Capacity : : invalidString ( ) ) ;
dialogWidget ( ) . used ( ) . setText ( Capacity : : invalidString ( ) ) ;
}
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . firstSector ( ) . setText ( KGlobal : : locale ( ) - > formatNumber ( partition ( ) . firstSector ( ) , 0 ) ) ;
dialogWidget ( ) . lastSector ( ) . setText ( KGlobal : : locale ( ) - > formatNumber ( partition ( ) . lastSector ( ) , 0 ) ) ;
dialogWidget ( ) . numSectors ( ) . setText ( KGlobal : : locale ( ) - > formatNumber ( partition ( ) . length ( ) , 0 ) ) ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
setupFlagsList ( ) ;
updateHideAndShow ( ) ;
setMinimumSize ( dialogWidget ( ) . size ( ) ) ;
resize ( dialogWidget ( ) . size ( ) ) ;
}
void PartPropsDialog : : setupFlagsList ( )
{
int f = 1 ;
QString s ;
while ( ! ( s = PartitionTable : : flagName ( static_cast < PartitionTable : : Flag > ( f ) ) ) . isEmpty ( ) )
{
if ( partition ( ) . availableFlags ( ) & f )
{
QListWidgetItem * item = new QListWidgetItem ( s ) ;
dialogWidget ( ) . listFlags ( ) . addItem ( item ) ;
item - > setFlags ( Qt : : ItemIsUserCheckable | Qt : : ItemIsEnabled ) ;
item - > setData ( Qt : : UserRole , f ) ;
item - > setCheckState ( ( partition ( ) . activeFlags ( ) & f ) ? Qt : : Checked : Qt : : Unchecked ) ;
}
f < < = 1 ;
}
}
void PartPropsDialog : : updateHideAndShow ( )
{
2009-05-06 15:19:23 +01:00
// create a temporary fs for some checks
2008-09-24 20:32:01 +01:00
const FileSystem * fs = FileSystemFactory : : create ( newFileSystemType ( ) , - 1 , - 1 , - 1 , " " ) ;
2008-12-27 12:01:29 +00:00
2010-01-27 13:00:14 +00:00
if ( fs = = NULL | | fs - > supportSetLabel ( ) = = FileSystem : : cmdSupportNone )
2008-09-24 20:32:01 +01:00
{
dialogWidget ( ) . label ( ) . setReadOnly ( true ) ;
dialogWidget ( ) . noSetLabel ( ) . setVisible ( true ) ;
dialogWidget ( ) . noSetLabel ( ) . setFont ( KGlobalSettings : : smallestReadableFont ( ) ) ;
QPalette palette = dialogWidget ( ) . noSetLabel ( ) . palette ( ) ;
QColor f = palette . color ( QPalette : : Foreground ) ;
f . setAlpha ( 128 ) ;
palette . setColor ( QPalette : : Foreground , f ) ;
dialogWidget ( ) . noSetLabel ( ) . setPalette ( palette ) ;
}
else
{
dialogWidget ( ) . label ( ) . setReadOnly ( isReadOnly ( ) ) ;
dialogWidget ( ) . noSetLabel ( ) . setVisible ( false ) ;
}
2008-12-27 12:01:29 +00:00
2009-05-06 15:19:23 +01:00
// when do we show the uuid?
const bool showUuid =
partition ( ) . state ( ) ! = Partition : : StateNew & & // not for new partitions
2010-01-27 13:00:14 +00:00
! ( fs = = NULL | | fs - > supportGetUUID ( ) = = FileSystem : : cmdSupportNone ) ; // not if the FS doesn't support it
2009-05-06 15:19:23 +01:00
dialogWidget ( ) . showUuid ( showUuid ) ;
2008-09-24 20:32:01 +01:00
delete fs ;
// when do we show available and used capacity?
const bool showAvailableAndUsed =
partition ( ) . state ( ) ! = Partition : : StateNew & & // not for new partitions
! partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) & & // neither for extended
! partition ( ) . roles ( ) . has ( PartitionRole : : Unallocated ) & & // or for unallocated
newFileSystemType ( ) ! = FileSystem : : Unformatted ; // and not for unformatted file systems
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . showAvailable ( showAvailableAndUsed ) ;
dialogWidget ( ) . showUsed ( showAvailableAndUsed ) ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
// when do we show the file system combo box?
const bool showFileSystem =
! partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) & & // not for extended, they have no file system
! partition ( ) . roles ( ) . has ( PartitionRole : : Unallocated ) ; // and not for unallocated: no choice there
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . showFileSystem ( showFileSystem ) ;
// when do we show the recreate file system check box?
const bool showCheckRecreate =
showFileSystem & & // only if we also show the file system
2010-01-27 13:00:14 +00:00
partition ( ) . fileSystem ( ) . supportCreate ( ) ! = FileSystem : : cmdSupportNone & & // and support creating this file system
2008-09-24 20:32:01 +01:00
partition ( ) . fileSystem ( ) . type ( ) ! = FileSystem : : Unknown & & // and not for unknown file systems
partition ( ) . state ( ) ! = Partition : : StateNew ; // or new partitions
dialogWidget ( ) . showCheckRecreate ( showCheckRecreate ) ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
// when do we show the list of partition flags?
const bool showListFlags =
partition ( ) . state ( ) ! = Partition : : StateNew & & // not for new partitions
! partition ( ) . roles ( ) . has ( PartitionRole : : Unallocated ) ; // and not for unallocated space
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . showListFlags ( showListFlags ) ;
dialogWidget ( ) . checkRecreate ( ) . setEnabled ( ! isReadOnly ( ) ) ;
dialogWidget ( ) . listFlags ( ) . setEnabled ( ! isReadOnly ( ) ) ;
dialogWidget ( ) . fileSystem ( ) . setEnabled ( ! isReadOnly ( ) & & ! forceRecreate ( ) ) ;
}
void PartPropsDialog : : setupConnections ( )
{
connect ( & dialogWidget ( ) . label ( ) , SIGNAL ( textEdited ( const QString & ) ) , SLOT ( setDirty ( ) ) ) ;
connect ( & dialogWidget ( ) . fileSystem ( ) , SIGNAL ( currentIndexChanged ( int ) ) , SLOT ( onFilesystemChanged ( int ) ) ) ;
connect ( & dialogWidget ( ) . checkRecreate ( ) , SIGNAL ( stateChanged ( int ) ) , SLOT ( onRecreate ( int ) ) ) ;
2008-11-02 19:21:36 +00:00
// We want to enable the OK-button whenever the user checks or unchecks a flag in the flag list.
2008-09-24 20:32:01 +01:00
// But it seems Qt doesn't offer a foolproof way to detect if this has happened: The currentRow/ItemChanged
// signal only means the _current_ item has changed, but not necessarily that it was checked/unchecked. And
2008-11-02 19:21:36 +00:00
// itemClicked alone isn't enough either. We choose to rather enable the OK-button too often than too
2008-09-24 20:32:01 +01:00
// seldom.
connect ( & dialogWidget ( ) . listFlags ( ) , SIGNAL ( itemClicked ( QListWidgetItem * ) ) , SLOT ( setDirty ( ) ) ) ;
connect ( & dialogWidget ( ) . listFlags ( ) , SIGNAL ( currentRowChanged ( int ) ) , SLOT ( setDirty ( ) ) ) ;
}
void PartPropsDialog : : setDirty ( )
{
2008-11-02 19:21:36 +00:00
setDefaultButton ( KDialog : : Ok ) ;
enableButtonOk ( true ) ;
2008-09-24 20:32:01 +01:00
}
void PartPropsDialog : : setupFileSystemComboBox ( )
{
dialogWidget ( ) . fileSystem ( ) . clear ( ) ;
QString selected ;
QStringList fsNames ;
2008-12-27 12:01:29 +00:00
2009-04-16 17:41:54 +01:00
foreach ( const FileSystem * fs , FileSystemFactory : : map ( ) )
2010-01-27 13:00:14 +00:00
if ( partition ( ) . fileSystem ( ) . type ( ) = = fs - > type ( ) | | ( fs - > supportCreate ( ) ! = FileSystem : : cmdSupportNone & & partition ( ) . capacity ( ) > = fs - > minCapacity ( ) & & partition ( ) . capacity ( ) < = fs - > maxCapacity ( ) ) )
2008-09-24 20:32:01 +01:00
{
QString name = fs - > name ( ) ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
if ( partition ( ) . fileSystem ( ) . type ( ) = = fs - > type ( ) )
selected = name ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
// If the partition isn't extended, skip the extended FS
if ( fs - > type ( ) = = FileSystem : : Extended & & ! partition ( ) . roles ( ) . has ( PartitionRole : : Extended ) )
continue ;
2008-12-27 12:01:29 +00:00
2008-09-24 20:32:01 +01:00
// The user cannot change the filesystem back to "unformatted" once a filesystem has been created.
if ( fs - > type ( ) = = FileSystem : : Unformatted )
{
// .. but if the file system is unknown to us, show the unformatted option as the currently selected one
if ( partition ( ) . fileSystem ( ) . type ( ) = = FileSystem : : Unknown )
{
name = FileSystem : : nameForType ( FileSystem : : Unformatted ) ;
selected = name ;
}
else if ( partition ( ) . fileSystem ( ) . type ( ) ! = FileSystem : : Unformatted & & partition ( ) . state ( ) ! = Partition : : StateNew )
continue ;
}
fsNames . append ( name ) ;
}
2009-05-05 20:33:55 +01:00
qSort ( fsNames . begin ( ) , fsNames . end ( ) , caseInsensitiveLessThan ) ;
2008-09-24 20:32:01 +01:00
2010-02-17 19:39:24 +00:00
foreach ( const QString & fsName , fsNames )
dialogWidget ( ) . fileSystem ( ) . addItem ( createFileSystemColor ( FileSystem : : typeForName ( fsName ) , 8 ) , fsName ) ;
2008-09-24 20:32:01 +01:00
dialogWidget ( ) . fileSystem ( ) . setCurrentIndex ( dialogWidget ( ) . fileSystem ( ) . findText ( selected ) ) ;
2013-01-03 12:43:03 +00:00
const FileSystem * fs = FileSystemFactory : : create ( FileSystem : : typeForName ( dialogWidget ( ) . fileSystem ( ) . currentText ( ) ) , - 1 , - 1 , - 1 , " " ) ;
dialogWidget ( ) . m_EditLabel - > setMaxLength ( fs - > maxLabelLength ( ) ) ;
2008-09-24 20:32:01 +01:00
}
2010-02-17 19:39:24 +00:00
void PartPropsDialog : : updatePartitionFileSystem ( )
{
FileSystem * fs = FileSystemFactory : : create ( newFileSystemType ( ) , partition ( ) . firstSector ( ) , partition ( ) . lastSector ( ) ) ;
partition ( ) . deleteFileSystem ( ) ;
partition ( ) . setFileSystem ( fs ) ;
2010-06-03 16:01:53 +01:00
dialogWidget ( ) . partWidget ( ) . update ( ) ;
2010-02-17 19:39:24 +00:00
}
2008-09-24 20:32:01 +01:00
void PartPropsDialog : : onFilesystemChanged ( int )
{
if ( partition ( ) . state ( ) = = Partition : : StateNew | | warnFileSystemChange ( ) | | KMessageBox : : warningContinueCancel ( this ,
i18nc ( " @info " , " <para><warning>You are about to lose all data on partition <filename>%1</filename>.</warning></para> "
" <para>Changing the file system on a partition already on disk will erase all its contents. If you continue now and apply the resulting operation in the main window, all data on <filename>%1</filename> will unrecoverably be lost.</para> " , partition ( ) . deviceNode ( ) ) ,
2008-12-27 12:01:29 +00:00
i18nc ( " @title:window " , " Really Recreate <filename>%1</filename> with File System %2? " , partition ( ) . deviceNode ( ) , dialogWidget ( ) . fileSystem ( ) . currentText ( ) ) ,
2010-04-11 19:19:24 +01:00
KGuiItem ( i18nc ( " @action:button " , " Change the File System " ) , " arrow-right " ) ,
KGuiItem ( i18nc ( " @action:button " , " Do Not Change the File System " ) , " dialog-cancel " ) , " reallyChangeFileSystem " ) = = KMessageBox : : Continue )
2008-12-27 12:01:29 +00:00
{
2008-09-24 20:32:01 +01:00
setDirty ( ) ;
updateHideAndShow ( ) ;
setWarnFileSystemChange ( ) ;
2010-02-17 19:39:24 +00:00
updatePartitionFileSystem ( ) ;
2013-01-03 12:43:03 +00:00
const FileSystem * fs = FileSystemFactory : : create ( FileSystem : : typeForName ( dialogWidget ( ) . fileSystem ( ) . currentText ( ) ) , - 1 , - 1 , - 1 , " " ) ;
dialogWidget ( ) . m_EditLabel - > setMaxLength ( fs - > maxLabelLength ( ) ) ;
2008-09-24 20:32:01 +01:00
}
else
{
dialogWidget ( ) . fileSystem ( ) . disconnect ( this ) ;
setupFileSystemComboBox ( ) ;
connect ( & dialogWidget ( ) . fileSystem ( ) , SIGNAL ( currentIndexChanged ( int ) ) , SLOT ( onFilesystemChanged ( int ) ) ) ;
}
}
void PartPropsDialog : : onRecreate ( int state )
{
if ( state = = Qt : : Checked & & ( warnFileSystemChange ( ) | | KMessageBox : : warningContinueCancel ( this ,
i18nc ( " @info " , " <para><warning>You are about to lose all data on partition <filename>%1</filename>.</warning></para> "
" <para>Recreating a file system will erase all its contents. If you continue now and apply the resulting operation in the main window, all data on <filename>%1</filename> will unrecoverably be lost.</para> " , partition ( ) . deviceNode ( ) ) ,
2008-12-27 12:01:29 +00:00
i18nc ( " @title:window " , " Really Recreate File System on <filename>%1</filename>? " , partition ( ) . deviceNode ( ) ) ,
2010-04-11 19:19:24 +01:00
KGuiItem ( i18nc ( " @action:button " , " Recreate the File System " ) , " arrow-right " ) ,
KGuiItem ( i18nc ( " @action:button " , " Do Not Recreate the File System " ) , " dialog-cancel " ) , " reallyRecreateFileSystem " ) = = KMessageBox : : Continue ) )
2008-09-24 20:32:01 +01:00
{
setDirty ( ) ;
setWarnFileSystemChange ( ) ;
setForceRecreate ( true ) ;
dialogWidget ( ) . fileSystem ( ) . setCurrentIndex ( dialogWidget ( ) . fileSystem ( ) . findText ( partition ( ) . fileSystem ( ) . name ( ) ) ) ;
dialogWidget ( ) . fileSystem ( ) . setEnabled ( false ) ;
updateHideAndShow ( ) ;
2010-02-17 19:39:24 +00:00
updatePartitionFileSystem ( ) ;
2008-09-24 20:32:01 +01:00
}
else
{
setForceRecreate ( false ) ;
dialogWidget ( ) . checkRecreate ( ) . setCheckState ( Qt : : Unchecked ) ;
dialogWidget ( ) . fileSystem ( ) . setEnabled ( true ) ;
updateHideAndShow ( ) ;
}
}