diff --git a/CMakeLists.txt b/CMakeLists.txt index 016d3d9..1dc84b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,96 +1,96 @@ # Copyright (C) 2008 by Volker Lanz # # 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 3 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, see . project(partitionmanager) cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) set(CMAKE_USE_RELATIVE_PATHS OFF) set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) set(KDE_INSTALL_USE_QT_SYS_PATHS ON CACHE BOOL "Install mkspecs files, Plugins and Imports to the Qt 5 install dir" FORCE) set(QT_MIN_VERSION "5.4.1") set(VERSION_MAJOR "1") -set(VERSION_MINOR "9") -set(VERSION_RELEASE "50") +set(VERSION_MINOR "2") +set(VERSION_RELEASE "1") set(VERSION_SUFFIX "") set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}${VERSION_SUFFIX}) add_definitions(-D'VERSION="${VERSION}"') #" find_package(ECM 1.0.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) include(ECMInstallIcons) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) include(FeatureSummary) include(GenerateExportHeader) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets ) # Load the frameworks we need find_package(KF5 REQUIRED Config Crash DocTools I18n IconThemes JobWidgets KIO Service XmlGui WidgetsAddons ) # use sane compile flags add_definitions( -fexceptions -DQT_USE_QSTRINGBUILDER -DQT_NO_CAST_TO_ASCII -DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_URL_CAST_FROM_STRING -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_SIGNALS_SLOTS_KEYWORDS -DQT_USE_FAST_OPERATOR_PLUS ) find_package(PkgConfig REQUIRED) find_package(KPMcore CONFIG REQUIRED) pkg_check_modules(BLKID REQUIRED blkid) pkg_check_modules(LIBATASMART REQUIRED libatasmart) include_directories(${Qt5Core_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${BLKID_INCLUDE_DIRS} lib/ src/) add_subdirectory(src) add_subdirectory(icons) add_subdirectory(doc) ki18n_install(po) get_filename_component(_doc_translations_path doc-translations ABSOLUTE) if (EXISTS ${_doc_translations_path}/CMakeLists.txt) add_subdirectory(doc-translations) endif() message(STATUS "KDE Partition Manager ${VERSION} will be built for install into ${CMAKE_INSTALL_PREFIX}") feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/src/gui/editmountpointdialog.cpp b/src/gui/editmountpointdialog.cpp index 25d0568..3de9229 100644 --- a/src/gui/editmountpointdialog.cpp +++ b/src/gui/editmountpointdialog.cpp @@ -1,78 +1,66 @@ /************************************************************************* * Copyright (C) 2009, 2010 by Volker Lanz * - * Copyright (C) 2015 by Teo Mrnjavac * * * * 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 3 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, see .* *************************************************************************/ #include "gui/editmountpointdialog.h" #include "gui/editmountpointdialogwidget.h" #include #include #include #include #include #include #include -#include - EditMountPointDialog::EditMountPointDialog(QWidget* parent, Partition& p) : QDialog(parent), m_Partition(p), m_DialogWidget(new EditMountPointDialogWidget(this, partition())) { QVBoxLayout *mainLayout = new QVBoxLayout(this); setLayout(mainLayout); mainLayout->addWidget(&widget()); setWindowTitle(xi18nc("@title:window", "Edit mount point for %1", p.deviceNode())); KConfigGroup kcg(KSharedConfig::openConfig(), "editMountPointDialog"); restoreGeometry(kcg.readEntry("Geometry", QByteArray())); - - QDialogButtonBox* dbb = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, - Qt::Horizontal, - this ); - mainLayout->addWidget(dbb); - connect(dbb, &QDialogButtonBox::accepted, - this, &EditMountPointDialog::accept); - connect(dbb, &QDialogButtonBox::rejected, - this, &EditMountPointDialog::reject); } /** Destroys an EditMOuntOptionsDialog instance */ EditMountPointDialog::~EditMountPointDialog() { KConfigGroup kcg(KSharedConfig::openConfig(), "editMountPointDialog"); kcg.writeEntry("Geometry", saveGeometry()); } void EditMountPointDialog::accept() { if (KMessageBox::warningContinueCancel(this, xi18nc("@info", "Are you sure you want to save the changes you made to the system table file /etc/fstab?" "This will overwrite the existing file on your hard drive now. This can not be undone."), i18nc("@title:window", "Really save changes?"), KGuiItem(i18nc("@action:button", "Save changes"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyWriteMountPoints")) == KMessageBox::Cancel) return; if (widget().acceptChanges() && widget().writeMountpoints(QStringLiteral("/etc/fstab"))) partition().setMountPoint(widget().editPath().text()); QDialog::accept(); } diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 13cee4f..9902837 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -1,1096 +1,1042 @@ /************************************************************************* * Copyright (C) 2008, 2009, 2010, 2012 by Volker Lanz * - * Copyright (C) 2015 by Teo Mrnjavac * * * * 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 3 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, see .* *************************************************************************/ #include "gui/mainwindow.h" #include "gui/infopane.h" #include "gui/applyprogressdialog.h" #include "gui/scanprogressdialog.h" #include "gui/createpartitiontabledialog.h" #include "gui/filesystemsupportdialog.h" #include "gui/devicepropsdialog.h" #include "gui/smartdialog.h" #include "config/configureoptionsdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include "util/guihelpers.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** Creates a new MainWindow instance. @param parent the parent widget */ MainWindow::MainWindow(QWidget* parent) : KXmlGuiWindow(parent), Ui::MainWindowBase(), m_OperationStack(new OperationStack(this)), m_OperationRunner(new OperationRunner(this, operationStack())), m_DeviceScanner(new DeviceScanner(this, operationStack())), m_ApplyProgressDialog(new ApplyProgressDialog(this, operationRunner())), m_ScanProgressDialog(new ScanProgressDialog(this)), m_StatusText(new QLabel(this)) { setupObjectNames(); setupUi(this); init(); } void MainWindow::setupObjectNames() { m_OperationStack->setObjectName(QStringLiteral("m_OperationStack")); m_OperationRunner->setObjectName(QStringLiteral("m_OperationRunner")); m_DeviceScanner->setObjectName(QStringLiteral("m_DeviceScanner")); m_ApplyProgressDialog->setObjectName(QStringLiteral("m_ApplyProgressDialog")); m_ScanProgressDialog->setObjectName(QStringLiteral("m_ScanProgressDialog")); } void MainWindow::init() { treeLog().init(); connect(GlobalLog::instance(), SIGNAL(newMessage(Log::Level, const QString&)), &treeLog(), SLOT(onNewLogMessage(Log::Level, const QString&))); setupActions(); setupStatusBar(); setupConnections(); listDevices().setActionCollection(actionCollection()); listOperations().setActionCollection(actionCollection()); pmWidget().init(&operationStack()); setupGUI(); loadConfig(); scanDevices(); } void MainWindow::closeEvent(QCloseEvent* event) { if (applyProgressDialog().isVisible()) { event->ignore(); return; } if (operationStack().size() > 0) { if (KMessageBox::warningContinueCancel(this, xi18ncp("@info", "Do you really want to quit the application?There is still an operation pending.", "Do you really want to quit the application?There are still %1 operations pending.", operationStack().size()), i18nc("@title:window", "Discard Pending Operations and Quit?"), KGuiItem(xi18nc("@action:button", "Quit %1", QGuiApplication::applicationDisplayName()), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyQuit")) == KMessageBox::Cancel) { event->ignore(); return; } } saveConfig(); KXmlGuiWindow::closeEvent(event); } void MainWindow::changeEvent(QEvent* event) { if ((event->type() == QEvent::ActivationChange || event->type() == QEvent::WindowStateChange) && event->spontaneous() && isActiveWindow()) { - QWidget* w = nullptr; + QWidget* w = NULL; if (applyProgressDialog().isVisible()) w = &applyProgressDialog(); else if (scanProgressDialog().isVisible()) w = &scanProgressDialog(); - if (w != nullptr) { + if (w != NULL) { w->activateWindow(); w->raise(); w->setFocus(); } } KXmlGuiWindow::changeEvent(event); } void MainWindow::setupActions() { // File actions KStandardAction::quit(this, SLOT(close()), actionCollection()); // Edit actions QAction* undoOperation = actionCollection()->addAction(QStringLiteral("undoOperation"), this, SLOT(onUndoOperation())); undoOperation->setEnabled(false); undoOperation->setText(i18nc("@action:inmenu", "Undo")); undoOperation->setToolTip(i18nc("@info:tooltip", "Undo the last operation")); undoOperation->setStatusTip(i18nc("@info:status", "Remove the last operation from the list.")); undoOperation->setShortcut(Qt::CTRL | Qt::Key_Z); undoOperation->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* clearAllOperations = actionCollection()->addAction(QStringLiteral("clearAllOperations"), this, SLOT(onClearAllOperations())); clearAllOperations->setEnabled(false); clearAllOperations->setText(i18nc("@action:inmenu clear the list of operations", "Clear")); clearAllOperations->setToolTip(i18nc("@info:tooltip", "Clear all operations")); clearAllOperations->setStatusTip(i18nc("@info:status", "Empty the list of pending operations.")); clearAllOperations->setIcon(QIcon::fromTheme(QStringLiteral("dialog-cancel")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* applyAllOperations = actionCollection()->addAction(QStringLiteral("applyAllOperations"), this, SLOT(onApplyAllOperations())); applyAllOperations->setEnabled(false); applyAllOperations->setText(i18nc("@action:inmenu apply all operations", "Apply")); applyAllOperations->setToolTip(i18nc("@info:tooltip", "Apply all operations")); applyAllOperations->setStatusTip(i18nc("@info:status", "Apply the pending operations in the list.")); applyAllOperations->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply")).pixmap(IconSize(KIconLoader::Toolbar))); // Device actions QAction* refreshDevices = actionCollection()->addAction(QStringLiteral("refreshDevices"), this, SLOT(onRefreshDevices())); refreshDevices->setText(i18nc("@action:inmenu refresh list of devices", "Refresh Devices")); refreshDevices->setToolTip(i18nc("@info:tooltip", "Refresh all devices")); refreshDevices->setStatusTip(i18nc("@info:status", "Renew the devices list.")); refreshDevices->setShortcut(Qt::Key_F5); refreshDevices->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* createNewPartitionTable = actionCollection()->addAction(QStringLiteral("createNewPartitionTable"), this, SLOT(onCreateNewPartitionTable())); createNewPartitionTable->setEnabled(false); createNewPartitionTable->setText(i18nc("@action:inmenu", "New Partition Table")); createNewPartitionTable->setToolTip(i18nc("@info:tooltip", "Create a new partition table")); createNewPartitionTable->setStatusTip(i18nc("@info:status", "Create a new and empty partition table on a device.")); createNewPartitionTable->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_N); createNewPartitionTable->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* exportPartitionTable = actionCollection()->addAction(QStringLiteral("exportPartitionTable"), this, SLOT(onExportPartitionTable())); exportPartitionTable->setEnabled(false); exportPartitionTable->setText(i18nc("@action:inmenu", "Export Partition Table")); exportPartitionTable->setToolTip(i18nc("@info:tooltip", "Export a partition table")); exportPartitionTable->setStatusTip(i18nc("@info:status", "Export the device's partition table to a text file.")); exportPartitionTable->setIcon(QIcon::fromTheme(QStringLiteral("document-export")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* importPartitionTable = actionCollection()->addAction(QStringLiteral("importPartitionTable"), this, SLOT(onImportPartitionTable())); importPartitionTable->setEnabled(false); importPartitionTable->setText(i18nc("@action:inmenu", "Import Partition Table")); importPartitionTable->setToolTip(i18nc("@info:tooltip", "Import a partition table")); importPartitionTable->setStatusTip(i18nc("@info:status", "Import a partition table from a text file.")); importPartitionTable->setIcon(QIcon::fromTheme(QStringLiteral("document-import")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* smartStatusDevice = actionCollection()->addAction(QStringLiteral("smartStatusDevice"), this, SLOT(onSmartStatusDevice())); smartStatusDevice->setEnabled(false); smartStatusDevice->setText(i18nc("@action:inmenu", "SMART Status")); smartStatusDevice->setToolTip(i18nc("@info:tooltip", "Show SMART status")); smartStatusDevice->setStatusTip(i18nc("@info:status", "Show the device's SMART status if supported")); QAction* propertiesDevice = actionCollection()->addAction(QStringLiteral("propertiesDevice"), this, SLOT(onPropertiesDevice())); propertiesDevice->setEnabled(false); propertiesDevice->setText(i18nc("@action:inmenu", "Properties")); propertiesDevice->setToolTip(i18nc("@info:tooltip", "Show device properties dialog")); propertiesDevice->setStatusTip(i18nc("@info:status", "View and modify device properties")); propertiesDevice->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")).pixmap(IconSize(KIconLoader::Toolbar))); // Partition actions QAction* newPartition = actionCollection()->addAction(QStringLiteral("newPartition"), &pmWidget(), SLOT(onNewPartition())); newPartition->setEnabled(false); newPartition->setText(i18nc("@action:inmenu create a new partition", "New")); newPartition->setToolTip(i18nc("@info:tooltip", "New partition")); newPartition->setStatusTip(i18nc("@info:status", "Create a new partition.")); newPartition->setShortcut(Qt::CTRL | Qt::Key_N); newPartition->setIcon(QIcon::fromTheme(QStringLiteral("document-new")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* resizePartition = actionCollection()->addAction(QStringLiteral("resizePartition"), &pmWidget(), SLOT(onResizePartition())); resizePartition->setEnabled(false); resizePartition->setText(i18nc("@action:inmenu", "Resize/Move")); resizePartition->setToolTip(i18nc("@info:tooltip", "Resize or move partition")); resizePartition->setStatusTip(i18nc("@info:status", "Shrink, grow or move an existing partition.")); resizePartition->setShortcut(Qt::CTRL | Qt::Key_R); resizePartition->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* deletePartition = actionCollection()->addAction(QStringLiteral("deletePartition"), &pmWidget(), SLOT(onDeletePartition())); deletePartition->setEnabled(false); deletePartition->setText(i18nc("@action:inmenu", "Delete")); deletePartition->setToolTip(i18nc("@info:tooltip", "Delete partition")); deletePartition->setStatusTip(i18nc("@info:status", "Delete a partition.")); deletePartition->setShortcut(Qt::Key_Delete); deletePartition->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* shredPartition = actionCollection()->addAction(QStringLiteral("shredPartition"), &pmWidget(), SLOT(onShredPartition())); shredPartition->setEnabled(false); shredPartition->setText(i18nc("@action:inmenu", "Shred")); shredPartition->setToolTip(i18nc("@info:tooltip", "Shred partition")); shredPartition->setStatusTip(i18nc("@info:status", "Shred a partition so that its contents cannot be restored.")); shredPartition->setShortcut(Qt::SHIFT | Qt::Key_Delete); shredPartition->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete-shred")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* copyPartition = actionCollection()->addAction(QStringLiteral("copyPartition"), &pmWidget(), SLOT(onCopyPartition())); copyPartition->setEnabled(false); copyPartition->setText(i18nc("@action:inmenu", "Copy")); copyPartition->setToolTip(i18nc("@info:tooltip", "Copy partition")); copyPartition->setStatusTip(i18nc("@info:status", "Copy an existing partition.")); copyPartition->setShortcut(Qt::CTRL | Qt::Key_C); copyPartition->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* pastePartition = actionCollection()->addAction(QStringLiteral("pastePartition"), &pmWidget(), SLOT(onPastePartition())); pastePartition->setEnabled(false); pastePartition->setText(i18nc("@action:inmenu", "Paste")); pastePartition->setToolTip(i18nc("@info:tooltip", "Paste partition")); pastePartition->setStatusTip(i18nc("@info:status", "Paste a copied partition.")); pastePartition->setShortcut(Qt::CTRL | Qt::Key_V); pastePartition->setIcon(QIcon::fromTheme(QStringLiteral("edit-paste")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* editMountPoint = actionCollection()->addAction(QStringLiteral("editMountPoint"), &pmWidget(), SLOT(onEditMountPoint())); editMountPoint->setEnabled(false); editMountPoint->setText(i18nc("@action:inmenu", "Edit Mount Point")); editMountPoint->setToolTip(i18nc("@info:tooltip", "Edit mount point")); editMountPoint->setStatusTip(i18nc("@info:status", "Edit a partition's mount point and options.")); QAction* mountPartition = actionCollection()->addAction(QStringLiteral("mountPartition"), &pmWidget(), SLOT(onMountPartition())); mountPartition->setEnabled(false); mountPartition->setText(i18nc("@action:inmenu", "Mount")); mountPartition->setToolTip(i18nc("@info:tooltip", "Mount or unmount partition")); mountPartition->setStatusTip(i18nc("@info:status", "Mount or unmount a partition.")); - QAction* decryptPartition = actionCollection()->addAction(QStringLiteral("decryptPartition"), &pmWidget(), SLOT(onDecryptPartition())); - decryptPartition->setEnabled(false); - decryptPartition->setText(i18nc("@action:inmenu", "Unlock")); - decryptPartition->setToolTip(i18nc("@info:tooltip", "Unlock or lock encrypted partition")); - decryptPartition->setStatusTip(i18nc("@info:status", "Unlock or lock encrypted partition.")); - QAction* checkPartition = actionCollection()->addAction(QStringLiteral("checkPartition"), &pmWidget(), SLOT(onCheckPartition())); checkPartition->setEnabled(false); checkPartition->setText(i18nc("@action:inmenu", "Check")); checkPartition->setToolTip(i18nc("@info:tooltip", "Check partition")); checkPartition->setStatusTip(i18nc("@info:status", "Check a filesystem on a partition for errors.")); checkPartition->setIcon(QIcon::fromTheme(QStringLiteral("flag")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* propertiesPartition = actionCollection()->addAction(QStringLiteral("propertiesPartition"), &pmWidget(), SLOT(onPropertiesPartition())); propertiesPartition->setEnabled(false); propertiesPartition->setText(i18nc("@action:inmenu", "Properties")); propertiesPartition->setToolTip(i18nc("@info:tooltip", "Show partition properties dialog")); propertiesPartition->setStatusTip(i18nc("@info:status", "View and modify partition properties (label, partition flags, etc.)")); propertiesPartition->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* backup = actionCollection()->addAction(QStringLiteral("backupPartition"), &pmWidget(), SLOT(onBackupPartition())); backup->setEnabled(false); backup->setText(i18nc("@action:inmenu", "Backup")); backup->setToolTip(i18nc("@info:tooltip", "Backup partition")); backup->setStatusTip(i18nc("@info:status", "Backup a partition to an image file.")); backup->setIcon(QIcon::fromTheme(QStringLiteral("document-export")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* restore = actionCollection()->addAction(QStringLiteral("restorePartition"), &pmWidget(), SLOT(onRestorePartition())); restore->setEnabled(false); restore->setText(i18nc("@action:inmenu", "Restore")); restore->setToolTip(i18nc("@info:tooltip", "Restore partition")); restore->setStatusTip(i18nc("@info:status", "Restore a partition from an image file.")); restore->setIcon(QIcon::fromTheme(QStringLiteral("document-import")).pixmap(IconSize(KIconLoader::Toolbar))); // View actions QAction* fileSystemSupport = actionCollection()->addAction(QStringLiteral("fileSystemSupport"), this, SLOT(onFileSystemSupport())); fileSystemSupport->setText(i18nc("@action:inmenu", "File System Support")); fileSystemSupport->setToolTip(i18nc("@info:tooltip", "View file system support information")); fileSystemSupport->setStatusTip(i18nc("@info:status", "Show information about supported file systems.")); actionCollection()->addAction(QStringLiteral("toggleDockDevices"), dockDevices().toggleViewAction()); actionCollection()->addAction(QStringLiteral("toggleDockOperations"), dockOperations().toggleViewAction()); actionCollection()->addAction(QStringLiteral("toggleDockInformation"), dockInformation().toggleViewAction()); actionCollection()->addAction(QStringLiteral("toggleDockLog"), dockLog().toggleViewAction()); // Settings Actions KStandardAction::preferences(this, SLOT(onConfigureOptions()), actionCollection()); // Log Actions QAction* clearLog = actionCollection()->addAction(QStringLiteral("clearLog"), &treeLog(), SLOT(onClearLog())); clearLog->setText(i18nc("@action:inmenu", "Clear Log")); clearLog->setToolTip(i18nc("@info:tooltip", "Clear the log output")); clearLog->setStatusTip(i18nc("@info:status", "Clear the log output panel.")); clearLog->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-list")).pixmap(IconSize(KIconLoader::Toolbar))); QAction* saveLog = actionCollection()->addAction(QStringLiteral("saveLog"), &treeLog(), SLOT(onSaveLog())); saveLog->setText(i18nc("@action:inmenu", "Save Log")); saveLog->setToolTip(i18nc("@info:tooltip", "Save the log output")); saveLog->setStatusTip(i18nc("@info:status", "Save the log output to a file.")); saveLog->setIcon(QIcon::fromTheme(QStringLiteral("document-save")).pixmap(IconSize(KIconLoader::Toolbar))); } void MainWindow::setupConnections() { connect(&listDevices(), SIGNAL(selectionChanged(const QString&)), &pmWidget(), SLOT(setSelectedDevice(const QString&))); connect(&listDevices(), SIGNAL(deviceDoubleClicked(const QString&)), SLOT(onPropertiesDevice(const QString&))); } void MainWindow::setupStatusBar() { statusBar()->addWidget(&statusText()); } void MainWindow::loadConfig() { if (Config::firstRun()) { dockLog().setVisible(false); dockInformation().setVisible(false); } PartitionAlignment::setSectorAlignment(Config::sectorAlignment()); } void MainWindow::saveConfig() const { Config::setFirstRun(false); Config::self()->save(); } void MainWindow::enableActions() { - actionCollection()->action(QStringLiteral("createNewPartitionTable")) - ->setEnabled(CreatePartitionTableOperation::canCreate(pmWidget().selectedDevice())); - actionCollection()->action(QStringLiteral("exportPartitionTable")) - ->setEnabled(pmWidget().selectedDevice() && - pmWidget().selectedDevice()->partitionTable() && - operationStack().size() == 0); - actionCollection()->action(QStringLiteral("importPartitionTable")) - ->setEnabled(CreatePartitionTableOperation::canCreate(pmWidget().selectedDevice())); - actionCollection()->action(QStringLiteral("smartStatusDevice")) - ->setEnabled(pmWidget().selectedDevice() != nullptr && - pmWidget().selectedDevice()->smartStatus().isValid()); - actionCollection()->action(QStringLiteral("propertiesDevice")) - ->setEnabled(pmWidget().selectedDevice() != nullptr); - - actionCollection()->action(QStringLiteral("undoOperation")) - ->setEnabled(operationStack().size() > 0); - actionCollection()->action(QStringLiteral("clearAllOperations")) - ->setEnabled(operationStack().size() > 0); - actionCollection()->action(QStringLiteral("applyAllOperations")) - ->setEnabled(operationStack().size() > 0 && (geteuid() == 0 || - Config::allowApplyOperationsAsNonRoot())); - - const bool readOnly = pmWidget().selectedDevice() == nullptr || - pmWidget().selectedDevice()->partitionTable() == nullptr || + actionCollection()->action(QStringLiteral("createNewPartitionTable"))->setEnabled(CreatePartitionTableOperation::canCreate(pmWidget().selectedDevice())); + actionCollection()->action(QStringLiteral("exportPartitionTable"))->setEnabled(pmWidget().selectedDevice() && pmWidget().selectedDevice()->partitionTable() && operationStack().size() == 0); + actionCollection()->action(QStringLiteral("importPartitionTable"))->setEnabled(CreatePartitionTableOperation::canCreate(pmWidget().selectedDevice())); + actionCollection()->action(QStringLiteral("smartStatusDevice"))->setEnabled(pmWidget().selectedDevice() != NULL && pmWidget().selectedDevice()->smartStatus().isValid()); + actionCollection()->action(QStringLiteral("propertiesDevice"))->setEnabled(pmWidget().selectedDevice() != NULL); + + actionCollection()->action(QStringLiteral("undoOperation"))->setEnabled(operationStack().size() > 0); + actionCollection()->action(QStringLiteral("clearAllOperations"))->setEnabled(operationStack().size() > 0); + actionCollection()->action(QStringLiteral("applyAllOperations"))->setEnabled(operationStack().size() > 0 && (geteuid() == 0 || Config::allowApplyOperationsAsNonRoot())); + + const bool readOnly = pmWidget().selectedDevice() == NULL || + pmWidget().selectedDevice()->partitionTable() == NULL || pmWidget().selectedDevice()->partitionTable()->isReadOnly(); const Partition* part = pmWidget().selectedPartition(); - actionCollection()->action(QStringLiteral("newPartition")) - ->setEnabled(!readOnly && NewOperation::canCreateNew(part)); - - const bool canResize = ResizeOperation::canGrow(part) || - ResizeOperation::canShrink(part) || - ResizeOperation::canMove(part); - actionCollection()->action(QStringLiteral("resizePartition")) - ->setEnabled(!readOnly && canResize); - - actionCollection()->action(QStringLiteral("copyPartition")) - ->setEnabled(CopyOperation::canCopy(part)); - actionCollection()->action(QStringLiteral("deletePartition")) - ->setEnabled(!readOnly && DeleteOperation::canDelete(part)); - actionCollection()->action(QStringLiteral("shredPartition")) - ->setEnabled(!readOnly && DeleteOperation::canDelete(part)); - actionCollection()->action(QStringLiteral("pastePartition")) - ->setEnabled(!readOnly && CopyOperation::canPaste(part, pmWidget().clipboardPartition())); - actionCollection()->action(QStringLiteral("propertiesPartition")) - ->setEnabled(part != nullptr); - - actionCollection()->action(QStringLiteral("editMountPoint")) - ->setEnabled(part && !part->isMounted()); - - actionCollection()->action(QStringLiteral("mountPartition")) - ->setEnabled(part && - (part->canMount() || part->canUnmount())); - if (part != nullptr) - actionCollection()->action(QStringLiteral("mountPartition")) - ->setText(part->isMounted() ? - part->fileSystem().unmountTitle() : - part->fileSystem().mountTitle()); - - actionCollection()->action(QStringLiteral("decryptPartition")) - ->setEnabled(part && - (part->fileSystem().type() == FileSystem::Luks) && - (dynamic_cast(part->fileSystem()).canCryptOpen(part->partitionPath()) || - dynamic_cast(part->fileSystem()).canCryptClose(part->partitionPath()))); - if (part && part->fileSystem().type() == FileSystem::Luks) - { - const FS::luks& luksFs = dynamic_cast(part->fileSystem()); - actionCollection()->action(QStringLiteral("decryptPartition")) - ->setText(luksFs.isCryptOpen() ? - luksFs.cryptCloseTitle() : - luksFs.cryptOpenTitle()); - } + actionCollection()->action(QStringLiteral("newPartition"))->setEnabled(!readOnly && NewOperation::canCreateNew(part)); + const bool canResize = ResizeOperation::canGrow(part) || ResizeOperation::canShrink(part) || ResizeOperation::canMove(part); + actionCollection()->action(QStringLiteral("resizePartition"))->setEnabled(!readOnly && canResize); + actionCollection()->action(QStringLiteral("copyPartition"))->setEnabled(CopyOperation::canCopy(part)); + actionCollection()->action(QStringLiteral("deletePartition"))->setEnabled(!readOnly && DeleteOperation::canDelete(part)); + actionCollection()->action(QStringLiteral("shredPartition"))->setEnabled(!readOnly && DeleteOperation::canDelete(part)); + actionCollection()->action(QStringLiteral("pastePartition"))->setEnabled(!readOnly && CopyOperation::canPaste(part, pmWidget().clipboardPartition())); + actionCollection()->action(QStringLiteral("propertiesPartition"))->setEnabled(part != NULL); + + actionCollection()->action(QStringLiteral("editMountPoint"))->setEnabled(part && !part->isMounted()); + actionCollection()->action(QStringLiteral("mountPartition"))->setEnabled(part && (part->canMount() || part->canUnmount())); + + if (part != NULL) + actionCollection()->action(QStringLiteral("mountPartition"))->setText(part->isMounted() ? part->fileSystem().unmountTitle() : part->fileSystem().mountTitle()); - actionCollection()->action(QStringLiteral("checkPartition")) - ->setEnabled(!readOnly && CheckOperation::canCheck(part)); + actionCollection()->action(QStringLiteral("checkPartition"))->setEnabled(!readOnly && CheckOperation::canCheck(part)); - actionCollection()->action(QStringLiteral("backupPartition")) - ->setEnabled(BackupOperation::canBackup(part)); - actionCollection()->action(QStringLiteral("restorePartition")) - ->setEnabled(RestoreOperation::canRestore(part)); + actionCollection()->action(QStringLiteral("backupPartition"))->setEnabled(BackupOperation::canBackup(part)); + actionCollection()->action(QStringLiteral("restorePartition"))->setEnabled(RestoreOperation::canRestore(part)); } void MainWindow::on_m_ApplyProgressDialog_finished() { scanDevices(); } void MainWindow::on_m_OperationStack_operationsChanged() { listOperations().updateOperations(operationStack().operations()); pmWidget().updatePartitions(); enableActions(); // this will make sure that the info pane gets updated on_m_PartitionManagerWidget_selectedPartitionChanged(pmWidget().selectedPartition()); statusText().setText(i18ncp("@info:status", "One pending operation", "%1 pending operations", operationStack().size())); } void MainWindow::on_m_OperationStack_devicesChanged() { QReadLocker lockDevices(&operationStack().lock()); listDevices().updateDevices(operationStack().previewDevices()); if (pmWidget().selectedDevice()) infoPane().showDevice(dockWidgetArea(&dockInformation()), *pmWidget().selectedDevice()); else infoPane().clear(); updateWindowTitle(); } void MainWindow::on_m_DockInformation_dockLocationChanged(Qt::DockWidgetArea) { on_m_PartitionManagerWidget_selectedPartitionChanged(pmWidget().selectedPartition()); } void MainWindow::updateWindowTitle() { QString title; if (pmWidget().selectedDevice()) title = pmWidget().selectedDevice()->deviceNode(); setWindowTitle(title); } void MainWindow::on_m_ListOperations_contextMenuRequested(const QPoint& pos) { QMenu* menu = static_cast(guiFactory()->container(QStringLiteral("edit"), this)); if (menu) menu->exec(pos); } void MainWindow::on_m_TreeLog_contextMenuRequested(const QPoint& pos) { QMenu* menu = static_cast(guiFactory()->container(QStringLiteral("log"), this)); if (menu) menu->exec(pos); } void MainWindow::on_m_ListDevices_contextMenuRequested(const QPoint& pos) { QMenu* menu = static_cast(guiFactory()->container(QStringLiteral("device"), this)); if (menu) menu->exec(pos); } void MainWindow::on_m_PartitionManagerWidget_contextMenuRequested(const QPoint& pos) { - QMenu* menu = nullptr; + QMenu* menu = NULL; - if (pmWidget().selectedPartition() == nullptr) { - if (pmWidget().selectedDevice() != nullptr) + if (pmWidget().selectedPartition() == NULL) { + if (pmWidget().selectedDevice() != NULL) menu = static_cast(guiFactory()->container(QStringLiteral("device"), this)); } else menu = static_cast(guiFactory()->container(QStringLiteral("partition"), this)); if (menu) menu->exec(pos); } void MainWindow::on_m_PartitionManagerWidget_deviceDoubleClicked(const Device*) { actionCollection()->action(QStringLiteral("propertiesDevice"))->trigger(); } void MainWindow::on_m_PartitionManagerWidget_partitionDoubleClicked(const Partition*) { actionCollection()->action(QStringLiteral("propertiesPartition"))->trigger(); } void MainWindow::on_m_PartitionManagerWidget_selectedPartitionChanged(const Partition* p) { if (p) infoPane().showPartition(dockWidgetArea(&dockInformation()), *p); else if (pmWidget().selectedDevice()) infoPane().showDevice(dockWidgetArea(&dockInformation()), *pmWidget().selectedDevice()); else infoPane().clear(); updateWindowTitle(); enableActions(); } void MainWindow::scanDevices() { Log(Log::information) << i18nc("@info/plain", "Using backend plugin: %1 (%2)", CoreBackendManager::self()->backend()->id(), CoreBackendManager::self()->backend()->version()); Log() << i18nc("@info/plain", "Scanning devices..."); // remember the currently selected device's node setSavedSelectedDeviceNode(pmWidget().selectedDevice() ? pmWidget().selectedDevice()->deviceNode() : QString()); pmWidget().clear(); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); scanProgressDialog().setEnabled(true); scanProgressDialog().show(); deviceScanner().start(); } void MainWindow::on_m_DeviceScanner_progress(const QString& device_node, int percent) { scanProgressDialog().setProgress(percent); scanProgressDialog().setDeviceName(device_node); } void MainWindow::on_m_DeviceScanner_finished() { QReadLocker lockDevices(&operationStack().lock()); scanProgressDialog().setProgress(100); if (!operationStack().previewDevices().isEmpty()) pmWidget().setSelectedDevice(operationStack().previewDevices()[0]); pmWidget().updatePartitions(); Log() << i18nc("@info/plain", "Scan finished."); QApplication::restoreOverrideCursor(); // try to set the seleted device, either from the saved one or just select the // first device if (!listDevices().setSelectedDevice(savedSelectedDeviceNode()) && !operationStack().previewDevices().isEmpty()) listDevices().setSelectedDevice(operationStack().previewDevices()[0]->deviceNode()); updateSeletedDeviceMenu(); checkFileSystemSupport(); } void MainWindow::updateSeletedDeviceMenu() { QMenu* devicesMenu = static_cast(guiFactory()->container(QStringLiteral("selectedDevice"), this)); devicesMenu->clear(); devicesMenu->setEnabled(!operationStack().previewDevices().isEmpty()); foreach(const Device * d, operationStack().previewDevices()) { QAction* action = new QAction(d->prettyName(), devicesMenu); action->setCheckable(true); action->setChecked(d->deviceNode() == pmWidget().selectedDevice()->deviceNode()); action->setData(d->deviceNode()); connect(action, SIGNAL(triggered(bool)), SLOT(onSelectedDeviceMenuTriggered(bool))); devicesMenu->addAction(action); } } void MainWindow::onSelectedDeviceMenuTriggered(bool) { QAction* action = qobject_cast(sender()); QMenu* devicesMenu = static_cast(guiFactory()->container(QStringLiteral("selectedDevice"), this)); - if (action == nullptr || action->parent() != devicesMenu) + if (action == NULL || action->parent() != devicesMenu) return; foreach(QAction * entry, devicesMenu->findChildren()) entry->setChecked(entry == action); listDevices().setSelectedDevice(action->data().toString()); } void MainWindow::on_m_ListDevices_selectionChanged(const QString& device_node) { QMenu* devicesMenu = static_cast(guiFactory()->container(QStringLiteral("selectedDevice"), this)); foreach(QAction * entry, devicesMenu->findChildren()) entry->setChecked(entry->data().toString() == device_node); } void MainWindow::onRefreshDevices() { if (operationStack().size() == 0 || KMessageBox::warningContinueCancel(this, xi18nc("@info", "Do you really want to rescan the devices?" "This will also clear the list of pending operations."), i18nc("@title:window", "Really Rescan the Devices?"), KGuiItem(i18nc("@action:button", "Rescan Devices"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyRescanDevices")) == KMessageBox::Continue) { scanDevices(); } } void MainWindow::onApplyAllOperations() { QStringList opList; foreach(const Operation * op, operationStack().operations()) opList.append(op->description()); if (KMessageBox::warningContinueCancelList(this, xi18nc("@info", "Do you really want to apply the pending operations listed below?" "This will permanently modify your disks."), opList, i18nc("@title:window", "Apply Pending Operations?"), KGuiItem(i18nc("@action:button", "Apply Pending Operations"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel()) == KMessageBox::Continue) { Log() << i18nc("@info/plain", "Applying operations..."); applyProgressDialog().show(); operationRunner().setReport(&applyProgressDialog().report()); // Undo all operations so the runner has a defined starting point for (int i = operationStack().operations().size() - 1; i >= 0; i--) { operationStack().operations()[i]->undo(); operationStack().operations()[i]->setStatus(Operation::StatusNone); } pmWidget().updatePartitions(); operationRunner().start(); } } void MainWindow::onUndoOperation() { Q_ASSERT(operationStack().size() > 0); if (operationStack().size() == 0) return; Log() << i18nc("@info/plain", "Undoing operation: %1", operationStack().operations().last()->description()); operationStack().pop(); // it's possible the undo killed the partition in the clipboard. if there's a partition in the clipboard, try // to find a device for it (OperationStack::findDeviceForPartition() only compares pointers, so an invalid // pointer is not a problem). if no device is found, the pointer must be dangling, so clear the clipboard. - if (pmWidget().clipboardPartition() != nullptr && operationStack().findDeviceForPartition(pmWidget().clipboardPartition()) == nullptr) - pmWidget().setClipboardPartition(nullptr); + if (pmWidget().clipboardPartition() != NULL && operationStack().findDeviceForPartition(pmWidget().clipboardPartition()) == NULL) + pmWidget().setClipboardPartition(NULL); pmWidget().updatePartitions(); enableActions(); } void MainWindow::onClearAllOperations() { if (KMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to clear the list of pending operations?"), i18nc("@title:window", "Clear Pending Operations?"), KGuiItem(i18nc("@action:button", "Clear Pending Operations"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyClearPendingOperations")) == KMessageBox::Continue) { Log() << i18nc("@info/plain", "Clearing the list of pending operations."); operationStack().clearOperations(); pmWidget().updatePartitions(); enableActions(); } } void MainWindow::onCreateNewPartitionTable() { Q_ASSERT(pmWidget().selectedDevice()); - if (pmWidget().selectedDevice() == nullptr) { + if (pmWidget().selectedDevice() == NULL) { qWarning() << "selected device is null."; return; } QPointer dlg = new CreatePartitionTableDialog(this, *pmWidget().selectedDevice()); if (dlg->exec() == QDialog::Accepted) operationStack().push(new CreatePartitionTableOperation(*pmWidget().selectedDevice(), dlg->type())); delete dlg; } void MainWindow::onImportPartitionTable() { Q_ASSERT(pmWidget().selectedDevice()); const QUrl url = QFileDialog::getOpenFileUrl(this, QStringLiteral("kfiledialog://importPartitionTable")); if (url.isEmpty()) return; QString fileName; KIO::FileCopyJob *job = KIO::file_copy(url, QUrl::fromLocalFile(fileName)); KJobWidgets::setWindow(job, this); job->exec(); if (job->error()) { KMessageBox::error(this, xi18nc("@info", "Could not open input file %1 for import: %2", url.fileName(), job->errorString()), i18nc("@title:window", "Error Importing Partition Table")); return; } QFile file(fileName); if (!file.open(QFile::ReadOnly)) { KMessageBox::error(this, xi18nc("@info", "Could not open temporary file %1 while trying to import from %2.", fileName, url.fileName()), i18nc("@title:window", "Error Importing Partition Table")); return; } Device& device = *pmWidget().selectedDevice(); QByteArray line; QRegExp rxPartition(QStringLiteral("(\\d+);(\\d+);(\\d+);(\\w+);(\\w+);(\"\\w*\");(\"[^\"]*\")")); QRegExp rxType(QStringLiteral("type:\\s\"(.+)\"")); QRegExp rxAlign(QStringLiteral("align:\\s\"(cylinder|sector)\"")); QRegExp rxMagic(QStringLiteral("^##|v(\\d+)|##")); quint32 lineNo = 0; bool haveMagic = false; - PartitionTable* ptable = nullptr; + PartitionTable* ptable = NULL; PartitionTable::TableType tableType = PartitionTable::unknownTableType; while (!(line = file.readLine()).isEmpty()) { lineNo++; line = line.simplified(); if (line.isEmpty()) continue; if (!haveMagic && rxMagic.indexIn(QString::fromUtf8(line.constData())) == -1) { KMessageBox::error(this, xi18nc("@info", "The import file %1 does not contain a valid partition table.", fileName), i18nc("@title:window", "Error While Importing Partition Table")); return; } else haveMagic = true; if (line.startsWith('#')) continue; if (rxType.indexIn(QString::fromUtf8(line.constData())) != -1) { - if (ptable != nullptr) { + if (ptable != NULL) { KMessageBox::error(this, i18nc("@info", "Found more than one partition table type in import file (line %1).", lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } tableType = PartitionTable::nameToTableType(rxType.cap(1)); if (tableType == PartitionTable::unknownTableType) { KMessageBox::error(this, i18nc("@info", "Partition table type \"%1\" is unknown (line %2).", rxType.cap(1), lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } if (tableType != PartitionTable::msdos && tableType != PartitionTable::gpt) { KMessageBox::error(this, i18nc("@info", "Partition table type \"%1\" is not supported for import (line %2).", rxType.cap(1), lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } ptable = new PartitionTable(tableType, PartitionTable::defaultFirstUsable(device, tableType), PartitionTable::defaultLastUsable(device, tableType)); operationStack().push(new CreatePartitionTableOperation(device, ptable)); } else if (rxAlign.indexIn(QString::fromUtf8(line.constData())) != -1) { // currently ignored } else if (rxPartition.indexIn(QString::fromUtf8(line.constData())) != -1) { - if (ptable == nullptr) { + if (ptable == NULL) { KMessageBox::error(this, i18nc("@info", "Found partition but no partition table type (line %1).", lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } qint32 num = rxPartition.cap(1).toInt(); qint64 firstSector = rxPartition.cap(2).toLongLong(); qint64 lastSector = rxPartition.cap(3).toLongLong(); QString fsName = rxPartition.cap(4); QString roleNames = rxPartition.cap(5); QString volumeLabel = rxPartition.cap(6).replace(QStringLiteral("\""), QString()); QStringList flags = rxPartition.cap(7).replace(QStringLiteral("\""), QString()).split(QStringLiteral(",")); if (firstSector < ptable->firstUsable() || lastSector > ptable->lastUsable()) { KMessageBox::error(this, i18nc("@info the partition is NOT a device path, just a number", "Partition %1 would be outside the device's boundaries (line %2).", num, lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } if (firstSector >= lastSector) { KMessageBox::error(this, i18nc("@info", "Partition %1 has end before start sector (line %2).", num, lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } PartitionNode* parent = ptable; Q_ASSERT(parent); PartitionRole role(PartitionRole::None); if (roleNames == QStringLiteral("extended")) role = PartitionRole(PartitionRole::Extended); else if (roleNames == QStringLiteral("logical")) { role = PartitionRole(PartitionRole::Logical); parent = ptable->findPartitionBySector(firstSector, PartitionRole(PartitionRole::Extended)); } else if (roleNames == QStringLiteral("primary")) role = PartitionRole(PartitionRole::Primary); if (role == PartitionRole(PartitionRole::None)) { KMessageBox::error(this, i18nc("@info the partition is NOT a device path, just a number", "Unrecognized partition role \"%1\" for partition %2 (line %3).", roleNames, num, lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } - if (parent == nullptr) { + if (parent == NULL) { KMessageBox::error(this, i18nc("@info the partition is NOT a device path, just a number", "No parent partition or partition table found for partition %1 (line %2).", num, lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } if (role.has(PartitionRole::Extended) && !PartitionTable::tableTypeSupportsExtended(tableType)) { KMessageBox::error(this, i18nc("@info", "The partition table type \"%1\" does not support extended partitions, but one was found (line %2).", PartitionTable::tableTypeToName(tableType), lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } FileSystem* fs = FileSystemFactory::create(FileSystem::typeForName(fsName), firstSector, lastSector); - if (fs == nullptr) { + if (fs == NULL) { KMessageBox::error(this, i18nc("@info the partition is NOT a device path, just a number", "Could not create file system \"%1\" for partition %2 (line %3).", fsName, num, lineNo), i18nc("@title:window", "Error While Importing Partition Table")); return; } if (fs->supportSetLabel() != FileSystem::cmdSupportNone && !volumeLabel.isEmpty()) fs->setLabel(volumeLabel); Partition* p = new Partition(parent, device, role, fs, firstSector, lastSector, QString(), PartitionTable::FlagNone, QString(), false, PartitionTable::FlagNone, Partition::StateNew); operationStack().push(new NewOperation(device, p)); } else Log(Log::warning) << i18nc("@info/plain", "Could not parse line %1 from import file. Ignoring it.", lineNo); } if (ptable->type() == PartitionTable::msdos && ptable->isSectorBased(device)) ptable->setType(device, PartitionTable::msdos_sectorbased); } void MainWindow::onExportPartitionTable() { Q_ASSERT(pmWidget().selectedDevice()); Q_ASSERT(pmWidget().selectedDevice()->partitionTable()); const QUrl url = QFileDialog::getSaveFileUrl(); if (url.isEmpty()) return; QTemporaryFile tempFile; if (!tempFile.open()) { KMessageBox::error(this, xi18nc("@info", "Could not create temporary file when trying to save to %1.", url.fileName()), i18nc("@title:window", "Error Exporting Partition Table")); return; } QTextStream stream(&tempFile); stream << "##|v1|## partition table of " << pmWidget().selectedDevice()->deviceNode() << "\n"; stream << "# on " << QDateTime::currentDateTime().toString() << "\n"; stream << *pmWidget().selectedDevice()->partitionTable(); tempFile.close(); KIO::CopyJob* job = KIO::move(QUrl::fromLocalFile(tempFile.fileName()), url, KIO::HideProgressInfo); job->exec(); if (job->error()) job->ui()->showErrorMessage(); } void MainWindow::onFileSystemSupport() { FileSystemSupportDialog dlg(this); dlg.exec(); } void MainWindow::onSettingsChanged() { if (CoreBackendManager::self()->backend()->id() != Config::backend()) { CoreBackendManager::self()->unload(); // FIXME: if loadBackend() fails to load the configured backend and loads the default // one instead it also sets the default backend in the config; the config dialog will // overwrite that again, however, after we're done here. if (loadBackend()) { deviceScanner().setupConnections(); scanDevices(); FileSystemFactory::init(); } else close(); } enableActions(); pmWidget().updatePartitions(); PartitionAlignment::setSectorAlignment(Config::sectorAlignment()); emit settingsChanged(); } void MainWindow::onConfigureOptions() { if (ConfigureOptionsDialog::showDialog(QStringLiteral("Settings"))) return; QPointer dlg = new ConfigureOptionsDialog(this, operationStack(), QStringLiteral("Settings")); // FIXME: we'd normally use settingsChanged(), according to the kde api docs. however, this // is emitted each time the user changes any of our own settings (backend, default file system), without // applying or clicking ok. so the below is the workaround for that. connect(dlg->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &MainWindow::onSettingsChanged); connect(dlg->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &MainWindow::onSettingsChanged); dlg->show(); } void MainWindow::onSmartStatusDevice() { Q_ASSERT(pmWidget().selectedDevice()); if (pmWidget().selectedDevice()) { QPointer dlg = new SmartDialog(this, *pmWidget().selectedDevice()); dlg->exec(); delete dlg; } } void MainWindow::onPropertiesDevice(const QString&) { Q_ASSERT(pmWidget().selectedDevice()); if (pmWidget().selectedDevice()) { Device& d = *pmWidget().selectedDevice(); QPointer dlg = new DevicePropsDialog(this, d); if (dlg->exec() == QDialog::Accepted) { if (d.partitionTable()->type() == PartitionTable::msdos && dlg->sectorBasedAlignment()) d.partitionTable()->setType(d, PartitionTable::msdos_sectorbased); else if (d.partitionTable()->type() == PartitionTable::msdos_sectorbased && dlg->cylinderBasedAlignment()) d.partitionTable()->setType(d, PartitionTable::msdos); on_m_OperationStack_devicesChanged(); pmWidget().updatePartitions(); } delete dlg; } } static QStringList checkSupportInNode(const PartitionNode* parent) { - if (parent == nullptr) + if (parent == NULL) return QStringList(); QStringList rval; foreach(const PartitionNode * node, parent->children()) { const Partition* p = dynamic_cast(node); - if (p == nullptr) + if (p == NULL) continue; if (node->children().size() > 0) rval << checkSupportInNode(node); if (!p->fileSystem().supportToolFound() && !p->fileSystem().supportToolName().name.isEmpty()) rval << QStringLiteral("" "%1" "%2" "%3" "%4" "") .arg(p->deviceNode()) .arg(p->fileSystem().name()) .arg(p->fileSystem().supportToolName().name) .arg(p->fileSystem().supportToolName().url.toString()); } return rval; } void MainWindow::checkFileSystemSupport() { QStringList supportList; foreach(const Device * d, operationStack().previewDevices()) supportList << checkSupportInNode(d->partitionTable()); QCollator m_collator; m_collator.setNumericMode(true); m_collator.setCaseSensitivity(Qt::CaseSensitive); std::sort(supportList.begin(), supportList.end(), [&m_collator](QString a, QString b) { return m_collator.compare(a, b) < 0; }); if (!supportList.isEmpty()) KMessageBox::information(this, xi18nc("@info", "No support tools were found for file systems currently present on hard disks in this computer:" "" "" "" "" "" "" "" "%1" "
PartitionFile SystemSupport ToolsURL
" "As long as the support tools for these file systems are not installed you will not be able to modify them." "You should find packages with these support tools in your distribution's package manager.", supportList.join(QStringLiteral("\n"))), i18nc("@title:window", "Missing File System Support Packages"), QStringLiteral("showInformationOnMissingFileSystemSupport"), KMessageBox::Notify | KMessageBox::AllowLink); } diff --git a/src/gui/partitionmanagerui.rc b/src/gui/partitionmanagerui.rc index e6ee636..8cfbc1f 100644 --- a/src/gui/partitionmanagerui.rc +++ b/src/gui/partitionmanagerui.rc @@ -1,85 +1,84 @@ Edit Toolbar Partition Toolbar Device Toolbar View Device Select Current Device Partition - diff --git a/src/gui/partitionmanagerwidget.cpp b/src/gui/partitionmanagerwidget.cpp index efe2727..4368ffd 100644 --- a/src/gui/partitionmanagerwidget.cpp +++ b/src/gui/partitionmanagerwidget.cpp @@ -1,771 +1,742 @@ /************************************************************************* * Copyright (C) 2008-2010 by Volker Lanz * - * Copyright (C) 2015 by Teo Mrnjavac * * * * 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 3 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, see .* *************************************************************************/ #include "gui/partitionmanagerwidget.h" #include "gui/partpropsdialog.h" #include "gui/resizedialog.h" #include "gui/newdialog.h" #include "gui/applyprogressdialog.h" #include "gui/insertdialog.h" #include "gui/editmountpointdialog.h" #include #include #include #include #include -#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util/guihelpers.h" #include #include #include #include #include #include #include #include #include class PartitionTreeWidgetItem : public QTreeWidgetItem { Q_DISABLE_COPY(PartitionTreeWidgetItem) public: PartitionTreeWidgetItem(const Partition* p) : QTreeWidgetItem(), m_Partition(p) {} const Partition* partition() const { return m_Partition; } private: const Partition* m_Partition; }; /** Creates a new PartitionManagerWidget instance. @param parent the parent widget */ PartitionManagerWidget::PartitionManagerWidget(QWidget* parent) : QWidget(parent), Ui::PartitionManagerWidgetBase(), - m_OperationStack(nullptr), - m_SelectedDevice(nullptr), - m_ClipboardPartition(nullptr) + m_OperationStack(NULL), + m_SelectedDevice(NULL), + m_ClipboardPartition(NULL) { setupUi(this); treePartitions().header()->setStretchLastSection(false); treePartitions().header()->setContextMenuPolicy(Qt::CustomContextMenu); } PartitionManagerWidget::~PartitionManagerWidget() { saveConfig(); } void PartitionManagerWidget::init(OperationStack* ostack) { m_OperationStack = ostack; // TODO: shouldn't this also go to the main window class? FileSystemFactory::init(); loadConfig(); setupConnections(); } void PartitionManagerWidget::loadConfig() { QList colWidths = Config::treePartitionColumnWidths(); QList colPositions = Config::treePartitionColumnPositions(); QList colVisible = Config::treePartitionColumnVisible(); QHeaderView* header = treePartitions().header(); for (int i = 0; i < treePartitions().columnCount(); i++) { if (colPositions[0] != -1 && colPositions.size() > i) header->moveSection(header->visualIndex(i), colPositions[i]); if (colVisible[0] != -1 && colVisible.size() > i) treePartitions().setColumnHidden(i, colVisible[i] == 0); if (colWidths[0] != -1 && colWidths.size() > i) treePartitions().setColumnWidth(i, colWidths[i]); } } void PartitionManagerWidget::saveConfig() const { QList colWidths; QList colPositions; QList colVisible; for (int i = 0; i < treePartitions().columnCount(); i++) { colPositions.append(treePartitions().header()->visualIndex(i)); colVisible.append(treePartitions().isColumnHidden(i) ? 0 : 1); colWidths.append(treePartitions().columnWidth(i)); } Config::setTreePartitionColumnPositions(colPositions); Config::setTreePartitionColumnVisible(colVisible); Config::setTreePartitionColumnWidths(colWidths); Config::self()->save(); } void PartitionManagerWidget::setupConnections() { connect(treePartitions().header(), SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onHeaderContextMenu(const QPoint&))); } void PartitionManagerWidget::clear() { - setSelectedDevice(nullptr); - setClipboardPartition(nullptr); + setSelectedDevice(NULL); + setClipboardPartition(NULL); treePartitions().clear(); partTableWidget().clear(); } void PartitionManagerWidget::setSelectedPartition(const Partition* p) { - if (p == nullptr) { - treePartitions().setCurrentItem(nullptr); - emit selectedPartitionChanged(nullptr); + if (p == NULL) { + treePartitions().setCurrentItem(NULL); + emit selectedPartitionChanged(NULL); updatePartitions(); } else partTableWidget().setActivePartition(p); } Partition* PartitionManagerWidget::selectedPartition() { - if (selectedDevice() == nullptr || selectedDevice()->partitionTable() == nullptr || partTableWidget().activeWidget() == nullptr) - return nullptr; + if (selectedDevice() == NULL || selectedDevice()->partitionTable() == NULL || partTableWidget().activeWidget() == NULL) + return NULL; // The active partition we get from the part table widget is const; we need non-const. // So take the first sector and find the partition in the selected device's // partition table. const Partition* activePartition = partTableWidget().activeWidget()->partition(); return selectedDevice()->partitionTable()->findPartitionBySector(activePartition->firstSector(), PartitionRole(PartitionRole::Any)); } void PartitionManagerWidget::setSelectedDevice(const QString& device_node) { QReadLocker lockDevices(&operationStack().lock()); foreach(Device * d, operationStack().previewDevices()) if (d->deviceNode() == device_node) { setSelectedDevice(d); return; } - setSelectedDevice(nullptr); + setSelectedDevice(NULL); } void PartitionManagerWidget::setSelectedDevice(Device* d) { m_SelectedDevice = d; - setSelectedPartition(nullptr); + setSelectedPartition(NULL); } static QTreeWidgetItem* createTreeWidgetItem(const Partition& p) { QTreeWidgetItem* item = new PartitionTreeWidgetItem(&p); quint32 i = 0; item->setText(i++, p.deviceNode()); item->setText(i, p.fileSystem().name()); item->setIcon(i, createFileSystemColor(p.fileSystem().type(), 14)); i++; item->setText(i, p.mountPoint()); if (p.isMounted()) item->setIcon(i, QIcon::fromTheme(QStringLiteral("object-locked")).pixmap(IconSize(KIconLoader::Panel))); i++; item->setText(i++, p.fileSystem().label()); item->setText(i++, p.fileSystem().uuid()); item->setText(i++, Capacity::formatByteSize(p.capacity())); item->setText(i++, Capacity::formatByteSize(p.used())); item->setText(i++, Capacity::formatByteSize(p.available())); item->setText(i++, QLocale().toString(p.firstSector())); item->setText(i++, QLocale().toString(p.lastSector())); item->setText(i++, QLocale().toString(p.length())); item->setText(i++, PartitionTable::flagNames(p.activeFlags()).join(QStringLiteral(", "))); item->setSizeHint(0, QSize(0, 32)); return item; } void PartitionManagerWidget::updatePartitions() { - if (selectedDevice() == nullptr) + if (selectedDevice() == NULL) return; treePartitions().clear(); partTableWidget().clear(); partTableWidget().setPartitionTable(selectedDevice()->partitionTable()); QTreeWidgetItem* deviceItem = new QTreeWidgetItem(); QFont font; font.setBold(true); font.setWeight(75); deviceItem->setFont(0, font); deviceItem->setText(0, selectedDevice()->prettyName()); deviceItem->setIcon(0, QIcon::fromTheme(selectedDevice()->iconName()).pixmap(IconSize(KIconLoader::Desktop))); deviceItem->setSizeHint(0, QSize(0, 32)); treePartitions().addTopLevelItem(deviceItem); - if (selectedDevice()->partitionTable() != nullptr) { + if (selectedDevice()->partitionTable() != NULL) { foreach(const Partition * p, selectedDevice()->partitionTable()->children()) { QTreeWidgetItem* item = createTreeWidgetItem(*p); foreach(const Partition * child, p->children()) { QTreeWidgetItem* childItem = createTreeWidgetItem(*child); item->addChild(childItem); } deviceItem->addChild(item); item->setExpanded(true); } } treePartitions().setFirstItemColumnSpanned(deviceItem, true); deviceItem->setExpanded(true); deviceItem->setFlags(Qt::ItemIsEnabled); partTableWidget().update(); } void PartitionManagerWidget::on_m_TreePartitions_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem*) { if (current) { const PartitionTreeWidgetItem* ptwItem = dynamic_cast(current); - partTableWidget().setActivePartition(ptwItem ? ptwItem->partition() : nullptr); + partTableWidget().setActivePartition(ptwItem ? ptwItem->partition() : NULL); } else - partTableWidget().setActiveWidget(nullptr); + partTableWidget().setActiveWidget(NULL); } void PartitionManagerWidget::on_m_TreePartitions_itemDoubleClicked(QTreeWidgetItem* item, int) { if (item == treePartitions().topLevelItem(0)) { - if (selectedDevice() != nullptr) + if (selectedDevice() != NULL) emit deviceDoubleClicked(selectedDevice()); } else { - if (selectedPartition() != nullptr) + if (selectedPartition() != NULL) emit partitionDoubleClicked(selectedPartition()); } } void PartitionManagerWidget::onHeaderContextMenu(const QPoint& p) { showColumnsContextMenu(p, treePartitions()); } void PartitionManagerWidget::on_m_PartTableWidget_itemSelectionChanged(PartWidget* item) { - if (item == nullptr) { - treePartitions().setCurrentItem(nullptr); - emit selectedPartitionChanged(nullptr); + if (item == NULL) { + treePartitions().setCurrentItem(NULL); + emit selectedPartitionChanged(NULL); return; } const Partition* p = item->partition(); Q_ASSERT(p); if (p) { QList findResult = treePartitions().findItems(p->deviceNode(), Qt::MatchFixedString | Qt::MatchRecursive, 0); for (int idx = 0; idx < findResult.size(); idx++) { const PartitionTreeWidgetItem* ptwItem = dynamic_cast(findResult[idx]); if (ptwItem && ptwItem->partition() == p) { treePartitions().setCurrentItem(findResult[idx]); break; } } } emit selectedPartitionChanged(p); } void PartitionManagerWidget::on_m_PartTableWidget_customContextMenuRequested(const QPoint& pos) { emit contextMenuRequested(partTableWidget().mapToGlobal(pos)); } void PartitionManagerWidget::on_m_PartTableWidget_itemDoubleClicked() { if (selectedPartition()) emit partitionDoubleClicked(selectedPartition()); } void PartitionManagerWidget::on_m_TreePartitions_customContextMenuRequested(const QPoint& pos) { emit contextMenuRequested(treePartitions().viewport()->mapToGlobal(pos)); } void PartitionManagerWidget::onPropertiesPartition() { if (selectedPartition()) { Partition& p = *selectedPartition(); Q_ASSERT(selectedDevice()); QPointer dlg = new PartPropsDialog(this, *selectedDevice(), p); if (dlg->exec() == QDialog::Accepted) { if (dlg->newFileSystemType() != p.fileSystem().type() || dlg->forceRecreate()) operationStack().push(new CreateFileSystemOperation(*selectedDevice(), p, dlg->newFileSystemType())); if (dlg->newLabel() != p.fileSystem().label()) operationStack().push(new SetFileSystemLabelOperation(p, dlg->newLabel())); if (dlg->newFlags() != p.activeFlags()) operationStack().push(new SetPartFlagsOperation(*selectedDevice(), p, dlg->newFlags())); } delete dlg; } } void PartitionManagerWidget::onMountPartition() { Partition* p = selectedPartition(); Q_ASSERT(p); - if (p == nullptr) { + if (p == NULL) { qWarning() << "no partition selected"; return; } - Report report(nullptr); + Report report(NULL); if (p->canMount()) { if (!p->mount(report)) KMessageBox::detailedSorry(this, xi18nc("@info", "The file system on partition %1 could not be mounted.", p->deviceNode()), QStringLiteral("
%1
").arg(report.toText()), i18nc("@title:window", "Could Not Mount File System.")); } else if (p->canUnmount()) { if (!p->unmount(report)) KMessageBox::detailedSorry(this, xi18nc("@info", "The file system on partition %1 could not be unmounted.", p->deviceNode()), QStringLiteral("pre>%1").arg(report.toText()), i18nc("@title:window", "Could Not Unmount File System.")); } if (p->roles().has(PartitionRole::Logical)) { Partition* parent = dynamic_cast(p->parent()); Q_ASSERT(parent); - if (parent != nullptr) + if (parent != NULL) parent->checkChildrenMounted(); else qWarning() << "parent is null"; } updatePartitions(); } -void PartitionManagerWidget::onDecryptPartition() -{ - Partition* p = selectedPartition(); - - Q_ASSERT(p); - - if (p == nullptr) { - qWarning() << "no partition selected"; - return; - } - - if (p->fileSystem().type() != FileSystem::Luks) - return; - - FS::luks& luksFs = dynamic_cast(p->fileSystem()); - - if (luksFs.canCryptOpen(p->partitionPath())) { - if (!luksFs.cryptOpen(p->partitionPath())) - KMessageBox::detailedSorry(this, xi18nc("@info", "The encrypted file system on partition %1 could not be unlocked.", p->deviceNode()), QString(), i18nc("@title:window", "Could Not Unlock Encrypted File System.")); - } else if (luksFs.canCryptClose(p->partitionPath())) { - if (!luksFs.cryptClose(p->partitionPath())) - KMessageBox::detailedSorry(this, xi18nc("@info", "The encrypted file system on partition %1 could not be locked.", p->deviceNode()), QString(), i18nc("@title:window", "Could Not Lock Encrypted File System.")); - } - - updatePartitions(); -} - void PartitionManagerWidget::onEditMountPoint() { Partition* p = selectedPartition(); Q_ASSERT(p); - if (p == nullptr) + if (p == NULL) return; QPointer dlg = new EditMountPointDialog(this, *p); if (dlg->exec() == QDialog::Accepted) updatePartitions(); delete dlg; } static bool checkTooManyPartitions(QWidget* parent, const Device& d, const Partition& p) { Q_ASSERT(d.partitionTable()); if (p.roles().has(PartitionRole::Unallocated) && d.partitionTable()->numPrimaries() >= d.partitionTable()->maxPrimaries() && !p.roles().has(PartitionRole::Logical)) { KMessageBox::sorry(parent, xi18ncp("@info", "There is already one primary partition on this device. This is the maximum number its partition table type can handle." "You cannot create, paste or restore a primary partition on it before you delete an existing one.", "There are already %1 primary partitions on this device. This is the maximum number its partition table type can handle." "You cannot create, paste or restore a primary partition on it before you delete an existing one.", d.partitionTable()->numPrimaries()), i18nc("@title:window", "Too Many Primary Partitions.")); return true; } return false; } void PartitionManagerWidget::onNewPartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } Q_ASSERT(selectedDevice()->partitionTable()); - if (selectedDevice()->partitionTable() == nullptr) { + if (selectedDevice()->partitionTable() == NULL) { qWarning() << "partition table on selected device is null"; return; } if (checkTooManyPartitions(this, *selectedDevice(), *selectedPartition())) return; Partition* newPartition = NewOperation::createNew(*selectedPartition(), static_cast(Config::defaultFileSystem())); QPointer dlg = new NewDialog(this, *selectedDevice(), *newPartition, selectedDevice()->partitionTable()->childRoles(*selectedPartition())); if (dlg->exec() == QDialog::Accepted) operationStack().push(new NewOperation(*selectedDevice(), newPartition)); else delete newPartition; delete dlg; } void PartitionManagerWidget::onDeletePartition(bool shred) { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } if (selectedPartition()->roles().has(PartitionRole::Logical)) { Q_ASSERT(selectedPartition()->parent()); - if (selectedPartition()->parent() == nullptr) { + if (selectedPartition()->parent() == NULL) { qWarning() << "parent of selected partition is null."; return; } if (selectedPartition()->number() > 0 && selectedPartition()->parent()->highestMountedChild() > selectedPartition()->number()) { KMessageBox::sorry(this, xi18nc("@info", "The partition %1 cannot currently be deleted because one or more partitions with higher logical numbers are still mounted." "Please unmount all partitions with higher logical numbers than %2 first.", selectedPartition()->deviceNode(), selectedPartition()->number()), i18nc("@title:window", "Cannot Delete Partition.")); return; } } if (clipboardPartition() == selectedPartition()) { if (KMessageBox::warningContinueCancel(this, i18nc("@info", "Do you really want to delete the partition that is currently in the clipboard? " "It will no longer be available for pasting after it has been deleted."), i18nc("@title:window", "Really Delete Partition in the Clipboard?"), KGuiItem(i18nc("@action:button", "Delete It"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyDeleteClipboardPartition")) == KMessageBox::Cancel) return; - setClipboardPartition(nullptr); + setClipboardPartition(NULL); } if (shred && Config::shredSource() == Config::EnumShredSource::random) operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition(), DeleteOperation::RandomShred)); else if (shred && Config::shredSource() == Config::EnumShredSource::zeros) operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition(), DeleteOperation::ZeroShred)); else operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition(), DeleteOperation::NoShred)); } void PartitionManagerWidget::onShredPartition() { onDeletePartition(true); } void PartitionManagerWidget::onResizePartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } Q_ASSERT(selectedDevice()->partitionTable()); - if (selectedDevice()->partitionTable() == nullptr) { + if (selectedDevice()->partitionTable() == NULL) { qWarning() << "partition table on selected device is null"; return; } // we cannot work with selectedPartition() here because opening and closing the dialog will // clear the selection, so we'll lose the partition after the dialog's been exec'd Partition& p = *selectedPartition(); const qint64 freeBefore = selectedDevice()->partitionTable()->freeSectorsBefore(p); const qint64 freeAfter = selectedDevice()->partitionTable()->freeSectorsAfter(p); QPointer dlg = new ResizeDialog(this, *selectedDevice(), p, p.firstSector() - freeBefore, freeAfter + p.lastSector()); if (dlg->exec() == QDialog::Accepted) { if (dlg->resizedFirstSector() == p.firstSector() && dlg->resizedLastSector() == p.lastSector()) Log(Log::information) << xi18nc("@info/plain", "Partition %1 has the same position and size after resize/move. Ignoring operation.", p.deviceNode()); else operationStack().push(new ResizeOperation(*selectedDevice(), p, dlg->resizedFirstSector(), dlg->resizedLastSector())); } if (p.roles().has(PartitionRole::Extended)) { // Even if the user dismissed the resize dialog we must update the partitions // if it's an extended partition: // The dialog has to remove and create unallocated children if the user resizes // an extended partition. We can't know if that has happened, so to avoid // any problems (like, the user resized an extended and then canceled, which would // lead to the unallocated children having the wrong size) do this now. updatePartitions(); } delete dlg; } void PartitionManagerWidget::onCopyPartition() { Q_ASSERT(selectedPartition()); - if (selectedPartition() == nullptr) { + if (selectedPartition() == NULL) { qWarning() << "selected partition: " << selectedPartition(); return; } setClipboardPartition(selectedPartition()); Log() << xi18nc("@info/plain", "Partition %1 has been copied to the clipboard.", selectedPartition()->deviceNode()); } void PartitionManagerWidget::onPastePartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } - if (clipboardPartition() == nullptr) { + if (clipboardPartition() == NULL) { qWarning() << "no partition in the clipboard."; return; } if (checkTooManyPartitions(this, *selectedDevice(), *selectedPartition())) return; Device* dSource = operationStack().findDeviceForPartition(clipboardPartition()); Q_ASSERT(dSource); - if (dSource == nullptr) { + if (dSource == NULL) { qWarning() << "source partition is null."; return; } Partition* copiedPartition = CopyOperation::createCopy(*selectedPartition(), *clipboardPartition()); if (showInsertDialog(*copiedPartition, clipboardPartition()->length())) operationStack().push(new CopyOperation(*selectedDevice(), copiedPartition, *dSource, clipboardPartition())); else delete copiedPartition; } bool PartitionManagerWidget::showInsertDialog(Partition& insertedPartition, qint64 sourceLength) { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return false; } const bool overwrite = !selectedPartition()->roles().has(PartitionRole::Unallocated); // Make sure the inserted partition has the right parent and logical or primary set. Only then // can PartitionTable::alignPartition() work correctly. selectedPartition()->parent()->reparent(insertedPartition); if (!overwrite) { QPointer dlg = new InsertDialog(this, *selectedDevice(), insertedPartition, *selectedPartition()); int result = dlg->exec(); delete dlg; if (result != QDialog::Accepted) return false; } else if (KMessageBox::warningContinueCancel(this, xi18nc("@info", "You are about to lose all data on partition " "%1." "Overwriting one partition with another (or with an image file) will " "destroy all data on this target partition." "If you continue now and apply the resulting operation in the main " "window, all data currently stored on %1 will " "unrecoverably be overwritten.", selectedPartition()->deviceNode()), i18nc("@title:window", "Really Overwrite Existing Partition?"), KGuiItem(i18nc("@action:button", "Overwrite Partition"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel(), QStringLiteral("reallyOverwriteExistingPartition")) == KMessageBox::Cancel) return false; if (insertedPartition.length() < sourceLength) { if (overwrite) KMessageBox::error(this, xi18nc("@info", "The selected partition is not large enough to hold the source partition or the backup file." "Pick another target or resize this partition so it is as large as the source."), i18nc("@title:window", "Target Not Large Enough")); else KMessageBox::sorry(this, xi18nc("@info", "It is not possible to create the target partition large enough to hold the source." "This may happen if not all partitions on a device are correctly aligned " "or when copying a primary partition into an extended partition."), i18nc("@title:window", "Cannot Create Target Partition.")); return false; } return true; } void PartitionManagerWidget::onCheckPartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } operationStack().push(new CheckOperation(*selectedDevice(), *selectedPartition())); } void PartitionManagerWidget::onBackupPartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } QString fileName = QFileDialog::getSaveFileName(this, QStringLiteral("kfiledialog://backupPartition")); // QString fileName = "/tmp/backuptest.img"; if (fileName.isEmpty()) return; if (!QFile::exists(fileName) || KMessageBox::warningContinueCancel(this, xi18nc("@info", "Do you want to overwrite the existing file %1?", fileName), i18nc("@title:window", "Overwrite Existing File?"), KGuiItem(i18nc("@action:button", "Overwrite File"), QStringLiteral("arrow-right")), KStandardGuiItem::cancel()) == KMessageBox::Continue) operationStack().push(new BackupOperation(*selectedDevice(), *selectedPartition(), fileName)); } void PartitionManagerWidget::onRestorePartition() { Q_ASSERT(selectedDevice()); Q_ASSERT(selectedPartition()); - if (selectedDevice() == nullptr || selectedPartition() == nullptr) { + if (selectedDevice() == NULL || selectedPartition() == NULL) { qWarning() << "selected device: " << selectedDevice() << ", selected partition: " << selectedPartition(); return; } if (checkTooManyPartitions(this, *selectedDevice(), *selectedPartition())) return; QString fileName = QFileDialog::getOpenFileName(this, QStringLiteral("kfiledialog://restorePartition")); // QString fileName = "/tmp/backuptest.img"; if (!fileName.isEmpty() && QFile::exists(fileName)) { Partition* restorePartition = RestoreOperation::createRestorePartition(*selectedDevice(), *selectedPartition()->parent(), selectedPartition()->firstSector(), fileName); if (restorePartition->length() > selectedPartition()->length()) { KMessageBox::error(this, xi18nc("@info", "The file system in the image file %1 is too large to be restored to the selected partition.", fileName), i18nc("@title:window", "Not Enough Space to Restore File System.")); delete restorePartition; return; } if (showInsertDialog(*restorePartition, restorePartition->length())) operationStack().push(new RestoreOperation(*selectedDevice(), restorePartition, fileName)); else delete restorePartition; } } diff --git a/src/gui/partitionmanagerwidget.h b/src/gui/partitionmanagerwidget.h index 1926ffb..3524a4d 100644 --- a/src/gui/partitionmanagerwidget.h +++ b/src/gui/partitionmanagerwidget.h @@ -1,158 +1,156 @@ /************************************************************************* * Copyright (C) 2008-2010 by Volker Lanz * - * Copyright (C) 2015 by Teo Mrnjavac * * * * 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 3 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, see .* *************************************************************************/ #if !defined(PARTITIONMANAGERWIDGET__H) #define PARTITIONMANAGERWIDGET__H #include #include #include "util/libpartitionmanagerguiexport.h" #include "ui_partitionmanagerwidgetbase.h" #include class Partition; class PartWidget; class Device; class QWidget; class QLabel; class QPoint; /** The central widget for the application. @author Volker Lanz */ class LIBKPMGUI_EXPORT PartitionManagerWidget : public QWidget, Ui::PartitionManagerWidgetBase { Q_OBJECT Q_DISABLE_COPY(PartitionManagerWidget) public: PartitionManagerWidget(QWidget* parent = NULL); virtual ~PartitionManagerWidget(); Q_SIGNALS: void selectedPartitionChanged(const Partition*); void contextMenuRequested(const QPoint&); void deviceDoubleClicked(const Device*); void partitionDoubleClicked(const Partition* p); public Q_SLOTS: void setSelectedDevice(Device* d); void setSelectedDevice(const QString& device_node); void onNewPartition(); void onResizePartition(); void onDeletePartition(bool shred = false); void onShredPartition(); void onCopyPartition(); void onPastePartition(); void onEditMountPoint(); void onMountPartition(); - void onDecryptPartition(); void onCheckPartition(); void onBackupPartition(); void onRestorePartition(); void onPropertiesPartition(); public: void init(OperationStack* ostack); void clear(); Device* selectedDevice() { return m_SelectedDevice; } const Device* selectedDevice() const { return m_SelectedDevice; } Partition* selectedPartition(); void setSelectedPartition(const Partition* p); Partition* clipboardPartition() { return m_ClipboardPartition; } const Partition* clipboardPartition() const { return m_ClipboardPartition; } void setClipboardPartition(Partition* p) { m_ClipboardPartition = p; } void updatePartitions(); protected: OperationStack& operationStack() { return *m_OperationStack; } const OperationStack& operationStack() const { return *m_OperationStack; } void setupConnections(); void loadConfig(); void saveConfig() const; bool showInsertDialog(Partition& insertPartition, qint64 sourceLength); PartTableWidget& partTableWidget() { Q_ASSERT(m_PartTableWidget); return *m_PartTableWidget; } const PartTableWidget& partTableWidget() const { Q_ASSERT(m_PartTableWidget); return *m_PartTableWidget; } QTreeWidget& treePartitions() { Q_ASSERT(m_TreePartitions); return *m_TreePartitions; } const QTreeWidget& treePartitions() const { Q_ASSERT(m_TreePartitions); return *m_TreePartitions; } protected Q_SLOTS: void on_m_TreePartitions_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous); void on_m_TreePartitions_customContextMenuRequested(const QPoint& pos); void on_m_TreePartitions_itemDoubleClicked(QTreeWidgetItem* item, int); void on_m_PartTableWidget_itemSelectionChanged(PartWidget* item); void on_m_PartTableWidget_customContextMenuRequested(const QPoint& pos); void on_m_PartTableWidget_itemDoubleClicked(); void onHeaderContextMenu(const QPoint& p); private: OperationStack* m_OperationStack; Device* m_SelectedDevice; Partition* m_ClipboardPartition; }; #endif