diff --git a/TODO b/TODO index 3995234..852084e 100644 --- a/TODO +++ b/TODO @@ -22,5 +22,3 @@ Random plans and ideas for 1.1 and beyond: to the file system in use. * Check if no of sectors fits in an unsigned 32 bit int for msdos partition tables. - -* Rememver previously selected device after applying and rescanning. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab1cac1..00578d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,8 +26,6 @@ file(GLOB partitionmanagerprivate_SRCS gui/*.cpp ) -qt4_add_dbus_adaptor(partitionmanagerprivate_SRCS org.kde.PartitionManager.xml gui/partitionmanagerwidget.h PartitionManagerWidget) - file(GLOB partitionmanagerprivate_UIFILES gui/*.ui kcm/*.ui) kde4_add_ui_files(partitionmanagerprivate_SRCS ${partitionmanagerprivate_UIFILES}) @@ -39,7 +37,6 @@ kde4_add_library(partitionmanagerprivate SHARED ${partitionmanagerprivate_SRCS}) target_link_libraries(partitionmanagerprivate libfatlabel ${KDE4_KDECORE_LIBS} ${KDE4_KFILE_LIBS} ${KDE4_KIO_LIBS} ${LIBPARTED_LIBS} ${UUID_LIBRARIES} ${BLKID_LIBRARIES} ${KDE4_KDEUI_LIBS} ${KDE4_SOLID_LIBS}) install(TARGETS partitionmanagerprivate ${INSTALL_TARGETS_DEFAULT_ARGS}) -# install(FILES org.kde.PartitionManager.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}) ############################################ diff --git a/src/core/devicescanner.cpp b/src/core/devicescanner.cpp index 58906f5..b6343b0 100644 --- a/src/core/devicescanner.cpp +++ b/src/core/devicescanner.cpp @@ -30,8 +30,8 @@ /** Constructs a DeviceScanner @param ostack the OperationStack where the devices will be created */ -DeviceScanner::DeviceScanner(OperationStack& ostack) : - QThread(), +DeviceScanner::DeviceScanner(QObject* parent, OperationStack& ostack) : + QThread(parent), m_LibParted(), m_OperationStack(ostack) { @@ -40,10 +40,7 @@ DeviceScanner::DeviceScanner(OperationStack& ostack) : void DeviceScanner::clear() { operationStack().clearOperations(); - emit operationsChanged(); - operationStack().clearDevices(); - emit devicesChanged(); } static quint32 countDevices(const QList& driveList) @@ -83,12 +80,10 @@ void DeviceScanner::run() { d->setIconName(solidDevice.icon()); operationStack().addDevice(d); - emit devicesChanged(); } emit progressChanged(solidBlock->device(), (++count) * 100 / totalDevices); } operationStack().sortDevices(); - emit devicesChanged(); } diff --git a/src/core/devicescanner.h b/src/core/devicescanner.h index b16f4d9..0804ec2 100644 --- a/src/core/devicescanner.h +++ b/src/core/devicescanner.h @@ -37,15 +37,13 @@ class DeviceScanner : public QThread Q_OBJECT public: - DeviceScanner(OperationStack& ostack); + DeviceScanner(QObject* parent, OperationStack& ostack); public: void clear(); /**< clear Devices and the OperationStack */ signals: void progressChanged(const QString& device_node, int progress); - void devicesChanged(); - void operationsChanged(); protected: virtual void run(); diff --git a/src/core/operationrunner.cpp b/src/core/operationrunner.cpp index 4754ec2..85240f4 100644 --- a/src/core/operationrunner.cpp +++ b/src/core/operationrunner.cpp @@ -33,8 +33,8 @@ /** Constructs an OperationRunner. @param ostack the OperationStack to act on */ -OperationRunner::OperationRunner(OperationStack& ostack) : - QThread(), +OperationRunner::OperationRunner(QObject* parent, OperationStack& ostack) : + QThread(parent), m_OperationStack(ostack), m_Report(NULL), m_SuspendMutex(), diff --git a/src/core/operationrunner.h b/src/core/operationrunner.h index 8345148..ded8dd9 100644 --- a/src/core/operationrunner.h +++ b/src/core/operationrunner.h @@ -41,7 +41,7 @@ class OperationRunner : public QThread Q_DISABLE_COPY(OperationRunner) public: - OperationRunner(OperationStack& ostack); + OperationRunner(QObject* parent, OperationStack& ostack); public: void run(); diff --git a/src/core/operationstack.cpp b/src/core/operationstack.cpp index 83473d1..719c1b5 100644 --- a/src/core/operationstack.cpp +++ b/src/core/operationstack.cpp @@ -45,7 +45,8 @@ #include /** Constructs a new OperationStack */ -OperationStack::OperationStack() : +OperationStack::OperationStack(QObject* parent) : + QObject(parent), m_Operations(), m_PreviewDevices(), m_Lock(QReadWriteLock::Recursive) @@ -397,6 +398,7 @@ void OperationStack::push(Operation* o) operations().append(o); o->preview(); o->setStatus(Operation::StatusPending); + emit operationsChanged(); } } @@ -406,6 +408,7 @@ void OperationStack::pop() Operation* o = operations().takeLast(); o->undo(); delete o; + emit operationsChanged(); } /** Removes all Operations from the OperationStack, calling Operation::undo() on them and deleting them. */ @@ -418,6 +421,8 @@ void OperationStack::clearOperations() o->undo(); delete o; } + + emit operationsChanged(); } /** Clears the list of Devices. */ @@ -427,6 +432,7 @@ void OperationStack::clearDevices() qDeleteAll(previewDevices()); previewDevices().clear(); + emit devicesChanged(); } /** Finds a Device a Partition is on. @@ -464,8 +470,8 @@ void OperationStack::addDevice(Device* d) Q_ASSERT(d); QWriteLocker lockDevices(&lock()); - previewDevices().append(d); + emit devicesChanged(); } static bool deviceLessThan(const Device* d1, const Device* d2) @@ -478,4 +484,6 @@ void OperationStack::sortDevices() QWriteLocker lockDevices(&lock()); qSort(previewDevices().begin(), previewDevices().end(), deviceLessThan); + + emit devicesChanged(); } diff --git a/src/core/operationstack.h b/src/core/operationstack.h index 18d8e2f..6fecb18 100644 --- a/src/core/operationstack.h +++ b/src/core/operationstack.h @@ -21,6 +21,7 @@ #define OPERATIONSTACK__H +#include #include #include @@ -38,8 +39,9 @@ class DeviceScanner; @author vl@fidra.de */ -class OperationStack +class OperationStack : public QObject { + Q_OBJECT Q_DISABLE_COPY(OperationStack) friend class DeviceScanner; @@ -49,9 +51,13 @@ class OperationStack typedef QList Operations; public: - OperationStack(); + OperationStack(QObject* parent = NULL); ~OperationStack(); + signals: + void operationsChanged(); + void devicesChanged(); + public: void push(Operation* o); void pop(); diff --git a/src/gui/listdevices.cpp b/src/gui/listdevices.cpp index 6a4e975..c13c909 100644 --- a/src/gui/listdevices.cpp +++ b/src/gui/listdevices.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -55,15 +55,10 @@ ListDevices::ListDevices(QWidget* parent) : void ListDevices::updateDevices(OperationStack::Devices& devices) { - int idx = listDevices().currentRow(); - listDevices().clear(); foreach(const Device* d, devices) listDevices().addItem(new ListDeviceWidgetItem(*d)); - - if (idx > -1 && idx < listDevices().count()) - listDevices().setCurrentRow(idx); } void ListDevices::on_m_ListDevices_itemSelectionChanged() @@ -79,10 +74,7 @@ void ListDevices::on_m_ListDevices_itemSelectionChanged() void ListDevices::on_m_ListDevices_customContextMenuRequested(const QPoint& pos) { - KMenu deviceMenu; - deviceMenu.addAction(actionCollection()->action("createNewPartitionTable")); - deviceMenu.addAction(actionCollection()->action("propertiesDevice")); - deviceMenu.exec(listDevices().viewport()->mapToGlobal(pos)); + emit contextMenuRequested(listDevices().viewport()->mapToGlobal(pos)); } void ListDevices::on_m_ListDevices_itemDoubleClicked(QListWidgetItem* list_item) @@ -92,3 +84,16 @@ void ListDevices::on_m_ListDevices_itemDoubleClicked(QListWidgetItem* list_item) if (item != NULL) emit deviceDoubleClicked(item->deviceNode); } + +bool ListDevices::setSelectedDevice(const QString& device_node) +{ + QList items = listDevices().findItems(device_node, Qt::MatchContains); + + if (items.size() > 0) + { + listDevices().setCurrentItem(items[0]); + return true; + } + + return false; +} diff --git a/src/gui/listdevices.h b/src/gui/listdevices.h index 19945c0..e431697 100644 --- a/src/gui/listdevices.h +++ b/src/gui/listdevices.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -47,9 +47,11 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT ListDevices : public QWidget, public Ui: signals: void selectionChanged(const QString& device_node); void deviceDoubleClicked(const QString& device_node); + void contextMenuRequested(const QPoint&); public: void setActionCollection(KActionCollection* coll) { m_ActionCollection = coll; } + bool setSelectedDevice(const QString& device_node); public slots: void updateDevices(OperationStack::Devices& devices); diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 848cbbc..eb8e4a2 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -21,8 +21,25 @@ #include "gui/infopane.h" #include "gui/applyprogressdialog.h" #include "gui/scanprogressdialog.h" +#include "gui/createpartitiontabledialog.h" +#include "gui/filesystemsupportdialog.h" +#include "gui/configureoptionsdialog.h" +#include "gui/devicepropsdialog.h" #include "core/device.h" +#include "core/partition.h" + +#include "ops/operation.h" +#include "ops/createpartitiontableoperation.h" +#include "ops/resizeoperation.h" +#include "ops/copyoperation.h" +#include "ops/deleteoperation.h" +#include "ops/newoperation.h" +#include "ops/backupoperation.h" +#include "ops/restoreoperation.h" +#include "ops/checkoperation.h" + +#include "fs/filesystem.h" #include #include @@ -33,12 +50,19 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include +#include + /** Creates a new MainWindow instance. @param parent the parent widget @param coll an action collection if used as a KPart @@ -47,13 +71,28 @@ MainWindow::MainWindow(QWidget* parent, KActionCollection* coll) : KXmlGuiWindow(parent), Ui::MainWindowBase(), m_ActionCollection(coll), + 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)), m_InfoPane(new InfoPane(this)) { + setupObjectNames(); setupUi(this); init(); } +void MainWindow::setupObjectNames() +{ + m_OperationStack->setObjectName("m_OperationStack"); + m_OperationRunner->setObjectName("m_OperationRunner"); + m_DeviceScanner->setObjectName("m_DeviceScanner"); + m_ApplyProgressDialog->setObjectName("m_ApplyProgressDialog"); + m_ScanProgressDialog->setObjectName("m_ScanProgressDialog"); +} + void MainWindow::init() { treeLog().init(actionCollection(), &pmWidget()); @@ -66,7 +105,7 @@ void MainWindow::init() listDevices().setActionCollection(actionCollection()); listOperations().setActionCollection(actionCollection()); - pmWidget().init(actionCollection(), "partitionmanagerrc"); + pmWidget().init(&operationStack(), "partitionmanagerrc"); if (isKPart()) { @@ -81,21 +120,23 @@ void MainWindow::init() dockInformation().setWidget(&infoPane()); infoPane().clear(); + + scanDevices(); } void MainWindow::closeEvent(QCloseEvent* event) { - if (pmWidget().applyProgressDialog().isVisible()) + if (applyProgressDialog().isVisible()) { event->ignore(); return; } - if (pmWidget().numPendingOperations() > 0) + if (numPendingOperations() > 0) { if (KMessageBox::warningContinueCancel(this, i18ncp("@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.", pmWidget().numPendingOperations()), + "Do you really want to quit the application?There are still %1 operations pending.", numPendingOperations()), i18nc("@title:window", "Discard Pending Operations and Quit?"), KGuiItem(i18nc("@action:button", "&Quit %1", KGlobal::mainComponent().aboutData()->programName())), KStandardGuiItem::cancel(), "reallyQuit") == KMessageBox::Cancel) @@ -116,10 +157,10 @@ void MainWindow::changeEvent(QEvent* event) { QWidget* w = NULL; - if (pmWidget().applyProgressDialog().isVisible()) - w = &pmWidget().applyProgressDialog(); - else if (pmWidget().scanProgressDialog().isVisible()) - w = &pmWidget().scanProgressDialog(); + if (applyProgressDialog().isVisible()) + w = &applyProgressDialog(); + else if (scanProgressDialog().isVisible()) + w = &scanProgressDialog(); if (w != NULL) { @@ -137,7 +178,146 @@ void MainWindow::setupActions() // File actions KStandardAction::quit(this, SLOT(close()), actionCollection()); + // Edit actions + KAction* undoOperation = actionCollection()->addAction("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(BarIcon("edit-undo")); + + KAction* clearAllOperations = actionCollection()->addAction("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(BarIcon("dialog-cancel")); + + KAction* applyAllOperations = actionCollection()->addAction("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(BarIcon("dialog-ok-apply")); + + // Device actions + KAction* refreshDevices = actionCollection()->addAction("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(BarIcon("view-refresh")); + + KAction* createNewPartitionTable = actionCollection()->addAction("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(BarIcon("edit-clear")); + + KAction* propertiesDevice = actionCollection()->addAction("propertiesDevice", this, SLOT(onPropertiesDevice())); + 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(BarIcon("document-properties")); + + // Partition actions + KAction* newPartition = actionCollection()->addAction("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(BarIcon("document-new")); + + KAction* resizePartition = actionCollection()->addAction("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(BarIcon("arrow-right-double")); + + KAction* deletePartition = actionCollection()->addAction("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(BarIcon("edit-delete")); + + KAction* shredPartition = actionCollection()->addAction("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(BarIcon("edit-delete-shred")); + + KAction* copyPartition = actionCollection()->addAction("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(BarIcon("edit-copy")); + + KAction* pastePartition = actionCollection()->addAction("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(BarIcon("edit-paste")); + + KAction* editMountPoint = actionCollection()->addAction("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.")); + + KAction* mountPartition = actionCollection()->addAction("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.")); + + KAction* checkPartition = actionCollection()->addAction("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(BarIcon("flag")); + + KAction* propertiesPartition = actionCollection()->addAction("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(BarIcon("document-properties")); + + KAction* backup = actionCollection()->addAction("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(BarIcon("document-export")); + + KAction* restore = actionCollection()->addAction("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(BarIcon("document-import")); + // View actions + KAction* fileSystemSupport = actionCollection()->addAction("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("toggleDockDevices", dockDevices().toggleViewAction()); actionCollection()->addAction("toggleDockOperations", dockOperations().toggleViewAction()); actionCollection()->addAction("toggleDockInformation", dockInformation().toggleViewAction()); @@ -145,12 +325,13 @@ void MainWindow::setupActions() // Settings Actions KStandardAction::showMenubar(this, SLOT(onShowMenuBar()), actionCollection()); + KStandardAction::preferences(this, SLOT(onConfigureOptions()), actionCollection()); } void MainWindow::setupConnections() { connect(&listDevices(), SIGNAL(selectionChanged(const QString&)), &pmWidget(), SLOT(setSelectedDevice(const QString&))); - connect(&listDevices(), SIGNAL(deviceDoubleClicked(const QString&)), &pmWidget(), SLOT(onPropertiesDevice(const QString&))); + connect(&listDevices(), SIGNAL(deviceDoubleClicked(const QString&)), SLOT(onPropertiesDevice(const QString&))); } void MainWindow::setupStatusBar() @@ -175,19 +356,59 @@ void MainWindow::saveConfig() const Config::self()->writeConfig(); } -void MainWindow::on_m_PartitionManagerWidget_operationsChanged() +void MainWindow::enableActions() { - listOperations().updateOperations(pmWidget().operations()); + actionCollection()->action("createNewPartitionTable")->setEnabled(CreatePartitionTableOperation::canCreate(pmWidget().selectedDevice())); - if (!isKPart()) - statusText().setText(i18ncp("@info:status", "One pending operation", "%1 pending operations", pmWidget().numPendingOperations())); + actionCollection()->action("undoOperation")->setEnabled(numPendingOperations() > 0); + actionCollection()->action("clearAllOperations")->setEnabled(numPendingOperations() > 0); + actionCollection()->action("applyAllOperations")->setEnabled(numPendingOperations() > 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("newPartition")->setEnabled(!readOnly && NewOperation::canCreateNew(part)); + const bool canResize = ResizeOperation::canGrow(part) || ResizeOperation::canShrink(part) || ResizeOperation::canMove(part); + actionCollection()->action("resizePartition")->setEnabled(!readOnly && canResize); + actionCollection()->action("copyPartition")->setEnabled(CopyOperation::canCopy(part)); + actionCollection()->action("deletePartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part)); + actionCollection()->action("shredPartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part)); + actionCollection()->action("pastePartition")->setEnabled(!readOnly && CopyOperation::canPaste(part, pmWidget().clipboardPartition())); + actionCollection()->action("propertiesPartition")->setEnabled(part != NULL); + + actionCollection()->action("editMountPoint")->setEnabled(part && part->canMount()); + actionCollection()->action("mountPartition")->setEnabled(part && (part->canMount() || part->canUnmount())); + + if (part != NULL) + actionCollection()->action("mountPartition")->setText(part->isMounted() ? part->fileSystem().unmountTitle() : part->fileSystem().mountTitle() ); + + actionCollection()->action("checkPartition")->setEnabled(!readOnly && CheckOperation::canCheck(part)); + + actionCollection()->action("backupPartition")->setEnabled(BackupOperation::canBackup(part)); + actionCollection()->action("restorePartition")->setEnabled(RestoreOperation::canRestore(part)); } -void MainWindow::on_m_PartitionManagerWidget_devicesChanged() +void MainWindow::on_m_ApplyProgressDialog_finished() { - QReadLocker lockDevices(&pmWidget().operationStack().lock()); + scanDevices(); +} - listDevices().updateDevices(pmWidget().previewDevices()); +void MainWindow::on_m_OperationStack_operationsChanged() +{ + listOperations().updateOperations(operationStack().operations()); + + if (!isKPart()) + statusText().setText(i18ncp("@info:status", "One pending operation", "%1 pending operations", numPendingOperations())); +} + +void MainWindow::on_m_OperationStack_devicesChanged() +{ + QReadLocker lockDevices(&operationStack().lock()); + + listDevices().updateDevices(operationStack().previewDevices()); if (pmWidget().selectedDevice()) infoPane().showDevice(dockWidgetArea(&dockInformation()), *pmWidget().selectedDevice()); @@ -214,6 +435,40 @@ void MainWindow::updateWindowTitle() setWindowTitle(title); } +void MainWindow::on_m_ListDevices_contextMenuRequested(const QPoint& pos) +{ + KMenu* menu = static_cast(guiFactory()->container("device", this)); + + if (menu) + menu->exec(pos); +} + +void MainWindow::on_m_PartitionManagerWidget_contextMenuRequested(const QPoint& pos) +{ + KMenu* menu = NULL; + + if (pmWidget().selectedPartition() == NULL) + { + if (pmWidget().selectedDevice() != NULL) + menu = static_cast(guiFactory()->container("device", this)); + } + else + menu = static_cast(guiFactory()->container("partition", this)); + + if (menu) + menu->exec(pos); +} + +void MainWindow::on_m_PartitionManagerWidget_deviceDoubleClicked(const Device*) +{ + actionCollection()->action("propertiesDevice")->trigger(); +} + +void MainWindow::on_m_PartitionManagerWidget_partitionDoubleClicked(const Partition*) +{ + actionCollection()->action("propertiesPartition")->trigger(); +} + void MainWindow::on_m_PartitionManagerWidget_selectedPartitionChanged(const Partition* p) { if (p) @@ -224,6 +479,7 @@ void MainWindow::on_m_PartitionManagerWidget_selectedPartitionChanged(const Part infoPane().clear(); updateWindowTitle(); + enableActions(); } bool MainWindow::isKPart() const @@ -247,3 +503,189 @@ void MainWindow::onShowMenuBar() Config::self()->setShowMenuBar(menuBarAction->isChecked()); } + +void MainWindow::scanDevices() +{ + Log() << i18nc("@info/plain", "Scanning devices..."); + + // remember the currently selected device's node + setSavedSelectedDeviceNode(pmWidget().selectedDevice() ? pmWidget().selectedDevice()->deviceNode() : QString()); + + pmWidget().clear(); + + KApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + + scanProgressDialog().setEnabled(true); + scanProgressDialog().show(); + + deviceScanner().start(); +} + +void MainWindow::on_m_DeviceScanner_progressChanged(const QString& device_node, int percent) +{ + scanProgressDialog().setProgress(percent); + scanProgressDialog().setDeviceName(device_node); +} + +void MainWindow::on_m_DeviceScanner_finished() +{ + QReadLocker lockDevices(&operationStack().lock()); + + if (!operationStack().previewDevices().isEmpty()) + pmWidget().setSelectedDevice(operationStack().previewDevices()[0]); + + pmWidget().updatePartitions(); + + Log() << i18nc("@info/plain", "Scan finished."); + KApplication::restoreOverrideCursor(); + + scanProgressDialog().hide(); + + // 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()); +} + +void MainWindow::onRefreshDevices() +{ + if (numPendingOperations() == 0 || KMessageBox::warningContinueCancel(this, + i18nc("@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")), + KStandardGuiItem::cancel(), "reallyRescanDevices") == KMessageBox::Continue) + { + scanDevices(); + } +} + +void MainWindow::onApplyAllOperations() +{ + QStringList opList; + + foreach (const Operation* op, operationStack().operations()) + opList.append(op->description()); + + if (KMessageBox::warningContinueCancelList(this, + i18nc("@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")), + 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(numPendingOperations() > 0); + + if (numPendingOperations() == 0) + return; + + Log() << i18nc("@info/plain", "Undoing operation: %1", operationStack().operations().last()->description()); + operationStack().pop(); + + 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")), + KStandardGuiItem::cancel(), "reallyClearPendingOperations") == KMessageBox::Continue) + { + Log() << i18nc("@info/plain", "Clearing the list of pending operations."); + operationStack().clearOperations(); + + pmWidget().updatePartitions(); + enableActions(); + } +} + +quint32 MainWindow::numPendingOperations() const +{ + return operationStack().size(); +} + +void MainWindow::onCreateNewPartitionTable() +{ + Q_ASSERT(pmWidget().selectedDevice()); + + if (pmWidget().selectedDevice() == NULL) + { + kWarning() << "selected device is null."; + return; + } + + QPointer dlg = new CreatePartitionTableDialog(this, *pmWidget().selectedDevice()); + + if (dlg->exec() == KDialog::Accepted) + { + operationStack().push(new CreatePartitionTableOperation(*pmWidget().selectedDevice(), dlg->type())); + + pmWidget().updatePartitions(); + enableActions(); + } + + delete dlg; +} + +void MainWindow::onFileSystemSupport() +{ + FileSystemSupportDialog dlg(this); + dlg.exec(); +} + +void MainWindow::onSettingsChanged(const QString&) +{ + enableActions(); + pmWidget().updatePartitions(); +} + +void MainWindow::onConfigureOptions() +{ + if (ConfigureOptionsDialog::showDialog("Settings")) + return; + + QPointer dlg = new ConfigureOptionsDialog(this, "Settings", Config::self()); + + connect(dlg, SIGNAL(settingsChanged(const QString&)), SLOT(onSettingsChanged(const QString&))); + + dlg->show(); +} + +void MainWindow::onPropertiesDevice(const QString&) +{ + Q_ASSERT(pmWidget().selectedDevice()); + + if (pmWidget().selectedDevice()) + { + QPointer dlg = new DevicePropsDialog(this, *pmWidget().selectedDevice()); + dlg->exec(); + delete dlg; + } +} + diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index dbc5ad8..a8fbd74 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -21,19 +21,28 @@ #define MAINWINDOW__H +#include "core/operationrunner.h" +#include "core/operationstack.h" +#include "core/devicescanner.h" + #include "util/libpartitionmanagerexport.h" #include "ui_mainwindowbase.h" #include +class ApplyProgressDialog; +class ScanProgressDialog; +class Device; +class Partition; +class InfoPane; + +class KActionCollection; + class QWidget; class QLabel; -class InfoPane; class QCloseEvent; class QEvent; -class Device; -class KActionCollection; /** @brief The application's main window. @@ -47,7 +56,12 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT MainWindow : public KXmlGuiWindow, publi public: explicit MainWindow(QWidget* parent = NULL, KActionCollection* coll = NULL); + signals: + void operationsChanged(); + protected: + void init(); + void setupObjectNames(); void setupActions(); void setupConnections(); void setupStatusBar(); @@ -55,6 +69,18 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT MainWindow : public KXmlGuiWindow, publi void saveConfig() const; void updateWindowTitle(); + quint32 numPendingOperations() const; + + void enableActions(); + + void closeEvent(QCloseEvent*); + void changeEvent(QEvent* event); + + bool isKPart() const; + + void setSavedSelectedDeviceNode(const QString& s) { m_SavedSelectedDeviceNode = s; } + const QString& savedSelectedDeviceNode() const { return m_SavedSelectedDeviceNode; } + KActionCollection* actionCollection() const { return m_ActionCollection != NULL ? m_ActionCollection : KXmlGuiWindow::actionCollection(); } InfoPane& infoPane() { Q_ASSERT(m_InfoPane); return *m_InfoPane; } @@ -86,25 +112,67 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT MainWindow : public KXmlGuiWindow, publi QLabel& statusText() { Q_ASSERT(m_StatusText); return *m_StatusText; } const QLabel& statusText() const { Q_ASSERT(m_StatusText); return *m_StatusText; } - bool isKPart() const; + OperationStack& operationStack() { Q_ASSERT(m_OperationStack); return *m_OperationStack; } + const OperationStack& operationStack() const { Q_ASSERT(m_OperationStack); return *m_OperationStack; } + + OperationRunner& operationRunner() { Q_ASSERT(m_OperationRunner); return *m_OperationRunner; } + const OperationRunner& operationRunner() const { Q_ASSERT(m_OperationRunner); return *m_OperationRunner; } + + DeviceScanner& deviceScanner() { Q_ASSERT(m_DeviceScanner); return *m_DeviceScanner; } + const DeviceScanner& deviceScanner() const { Q_ASSERT(m_DeviceScanner); return *m_DeviceScanner; } + + ApplyProgressDialog& applyProgressDialog() { Q_ASSERT(m_ApplyProgressDialog); return *m_ApplyProgressDialog; } + const ApplyProgressDialog& applyProgressDialog() const { Q_ASSERT(m_ApplyProgressDialog); return *m_ApplyProgressDialog; } + + ScanProgressDialog& scanProgressDialog() { Q_ASSERT(m_ScanProgressDialog); return *m_ScanProgressDialog; } + const ScanProgressDialog& scanProgressDialog() const { Q_ASSERT(m_ScanProgressDialog); return *m_ScanProgressDialog; } protected slots: - void closeEvent(QCloseEvent*); - void changeEvent(QEvent* event); - - void init(); + void on_m_PartitionManagerWidget_selectedPartitionChanged(const Partition* p); + void on_m_PartitionManagerWidget_contextMenuRequested(const QPoint& pos); + void on_m_PartitionManagerWidget_deviceDoubleClicked(const Device*); + void on_m_PartitionManagerWidget_partitionDoubleClicked(const Partition*); void on_m_DockInformation_dockLocationChanged(Qt::DockWidgetArea); - void on_m_PartitionManagerWidget_devicesChanged(); - void on_m_PartitionManagerWidget_operationsChanged(); - void on_m_PartitionManagerWidget_selectedPartitionChanged(const Partition* p); + + void on_m_OperationStack_operationsChanged(); + void on_m_OperationStack_devicesChanged(); + + void on_m_DeviceScanner_finished(); + void on_m_DeviceScanner_progressChanged(const QString& device_node, int percent); + + void on_m_ApplyProgressDialog_finished(); + + void on_m_ListDevices_contextMenuRequested(const QPoint& pos); + void onShowMenuBar(); + void scanDevices(); + + void onRefreshDevices(); + void onCreateNewPartitionTable(); + + void onApplyAllOperations(); + void onUndoOperation(); + void onClearAllOperations(); + + void onConfigureOptions(); + void onSettingsChanged(const QString&); + + void onFileSystemSupport(); + + void onPropertiesDevice(const QString& device_node = QString()); + private: KActionCollection* m_ActionCollection; + OperationStack* m_OperationStack; + OperationRunner* m_OperationRunner; + DeviceScanner* m_DeviceScanner; + ApplyProgressDialog* m_ApplyProgressDialog; + ScanProgressDialog* m_ScanProgressDialog; QLabel* m_StatusText; InfoPane* m_InfoPane; + QString m_SavedSelectedDeviceNode; }; #endif - diff --git a/src/gui/mainwindowbase.ui b/src/gui/mainwindowbase.ui index 65ea233..0e48ad0 100644 --- a/src/gui/mainwindowbase.ui +++ b/src/gui/mainwindowbase.ui @@ -64,7 +64,7 @@ 1 - + diff --git a/src/gui/partitionmanagerui.rc b/src/gui/partitionmanagerui.rc index 93106d3..021cf19 100644 --- a/src/gui/partitionmanagerui.rc +++ b/src/gui/partitionmanagerui.rc @@ -22,6 +22,7 @@ Device Toolbar + diff --git a/src/gui/partitionmanagerwidget.cpp b/src/gui/partitionmanagerwidget.cpp index 709e9e2..034696f 100644 --- a/src/gui/partitionmanagerwidget.cpp +++ b/src/gui/partitionmanagerwidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -22,21 +22,14 @@ #include "gui/partpropsdialog.h" #include "gui/resizedialog.h" #include "gui/newdialog.h" -#include "gui/filesystemsupportdialog.h" #include "gui/applyprogressdialog.h" #include "gui/insertdialog.h" #include "gui/editmountpointdialog.h" -#include "gui/createpartitiontabledialog.h" -#include "gui/scanprogressdialog.h" -#include "gui/configureoptionsdialog.h" -#include "gui/devicepropsdialog.h" #include "core/partition.h" #include "core/device.h" #include "core/operationstack.h" #include "core/partitiontable.h" -#include "core/operationrunner.h" -#include "core/devicescanner.h" #include "fs/filesystemfactory.h" @@ -44,7 +37,6 @@ #include "ops/resizeoperation.h" #include "ops/newoperation.h" #include "ops/copyoperation.h" -#include "ops/createpartitiontableoperation.h" #include "ops/checkoperation.h" #include "ops/backupoperation.h" #include "ops/restoreoperation.h" @@ -57,10 +49,6 @@ #include "util/report.h" #include "util/helpers.h" -#include -#include -#include -#include #include #include #include @@ -73,10 +61,6 @@ #include -#include - -#include "partitionmanageradaptor.h" - class PartitionTreeWidgetItem : public QTreeWidgetItem { Q_DISABLE_COPY(PartitionTreeWidgetItem) @@ -93,24 +77,15 @@ class PartitionTreeWidgetItem : public QTreeWidgetItem @param parent the parent widget @param coll an action collection (may be NULL and set later) */ -PartitionManagerWidget::PartitionManagerWidget(QWidget* parent, KActionCollection* coll) : +PartitionManagerWidget::PartitionManagerWidget(QWidget* parent) : QWidget(parent), Ui::PartitionManagerWidgetBase(), - m_OperationStack(), - m_OperationRunner(operationStack()), - m_DeviceScanner(operationStack()), - m_ApplyProgressDialog(new ApplyProgressDialog(this, operationRunner())), - m_ScanProgressDialog(new ScanProgressDialog(this)), - m_ActionCollection(coll), + m_OperationStack(NULL), m_SelectedDevice(NULL), m_ClipboardPartition(NULL) { setupUi(this); - (void) new PartitionManagerAdaptor(this); - QDBusConnection dbus = QDBusConnection::sessionBus(); - dbus.registerObject("/PartitionManager", this); - treePartitions().header()->setStretchLastSection(false); treePartitions().header()->setContextMenuPolicy(Qt::CustomContextMenu); } @@ -120,20 +95,16 @@ PartitionManagerWidget::~PartitionManagerWidget() saveConfig(); } -void PartitionManagerWidget::init(KActionCollection* coll, const QString& config_name) +void PartitionManagerWidget::init(OperationStack* ostack, const QString& config_name) { Config::instance(config_name); - Q_ASSERT(coll); - m_ActionCollection = coll; + m_OperationStack = ostack; FileSystemFactory::init(); loadConfig(); - setupActions(); setupConnections(); - - scanDevices(); } void PartitionManagerWidget::loadConfig() @@ -176,250 +147,41 @@ void PartitionManagerWidget::saveConfig() const Config::self()->writeConfig(); } -void PartitionManagerWidget::setupActions() -{ - // Edit actions - KAction* undoOperation = actionCollection()->addAction("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(BarIcon("edit-undo")); - - KAction* clearAllOperations = actionCollection()->addAction("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(BarIcon("dialog-cancel")); - - KAction* applyAllOperations = actionCollection()->addAction("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(BarIcon("dialog-ok-apply")); - - // Device actions - KAction* refreshDevices = actionCollection()->addAction("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(BarIcon("view-refresh")); - - KAction* createNewPartitionTable = actionCollection()->addAction("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(BarIcon("edit-clear")); - - KAction* propertiesDevice = actionCollection()->addAction("propertiesDevice", this, SLOT(onPropertiesDevice())); - 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(BarIcon("document-properties")); - - // Partition actions - KAction* newPartition = actionCollection()->addAction("newPartition", this, 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(BarIcon("document-new")); - - KAction* resizePartition = actionCollection()->addAction("resizePartition", this, 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(BarIcon("arrow-right-double")); - - KAction* deletePartition = actionCollection()->addAction("deletePartition", this, 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(BarIcon("edit-delete")); - - KAction* shredPartition = actionCollection()->addAction("shredPartition", this, 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(BarIcon("edit-delete-shred")); - - KAction* copyPartition = actionCollection()->addAction("copyPartition", this, 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(BarIcon("edit-copy")); - - KAction* pastePartition = actionCollection()->addAction("pastePartition", this, 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(BarIcon("edit-paste")); - - KAction* editMountPoint = actionCollection()->addAction("editMountPoint", this, 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.")); - - KAction* mountPartition = actionCollection()->addAction("mountPartition", this, 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.")); - - KAction* checkPartition = actionCollection()->addAction("checkPartition", this, 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(BarIcon("flag")); - - KAction* propertiesPartition = actionCollection()->addAction("propertiesPartition", this, 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(BarIcon("document-properties")); - - KAction* backup = actionCollection()->addAction("backupPartition", this, 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(BarIcon("document-export")); - - KAction* restore = actionCollection()->addAction("restorePartition", this, 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(BarIcon("document-import")); - - // View actions - KAction* fileSystemSupport = actionCollection()->addAction("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.")); - - // Settings actions - KStandardAction::preferences(this, SLOT(onConfigureOptions()), actionCollection()); -} - void PartitionManagerWidget::setupConnections() { - Q_ASSERT(actionCollection()); - - connect(&partTableWidget(), SIGNAL(itemActivated(const PartWidget*)), actionCollection()->action("propertiesPartition"), SLOT(trigger())); - connect(&applyProgressDialog(), SIGNAL(finished(int)), SLOT(scanDevices())); - - connect(&deviceScanner(), SIGNAL(finished()), SLOT(onScanDevicesFinished())); - connect(&deviceScanner(), SIGNAL(progressChanged(const QString&, int)), SLOT(onScanDevicesProgressChanged(const QString&, int))); - connect(&deviceScanner(), SIGNAL(operationsChanged()), SIGNAL(operationsChanged())); - connect(&deviceScanner(), SIGNAL(devicesChanged()), SIGNAL(devicesChanged())); - connect(treePartitions().header(), SIGNAL(customContextMenuRequested(const QPoint&)), SLOT(onHeaderContextMenu(const QPoint&))); } -void PartitionManagerWidget::scanDevices() -{ - Log() << i18nc("@info/plain", "Scanning devices..."); - - clear(); - - KApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - scanProgressDialog().setEnabled(true); - scanProgressDialog().show(); - - deviceScanner().start(); -} - -void PartitionManagerWidget::onScanDevicesProgressChanged(const QString& device_node, int percent) -{ - scanProgressDialog().setProgress(percent); - scanProgressDialog().setDeviceName(device_node); -} - -void PartitionManagerWidget::onScanDevicesFinished() -{ - QReadLocker lockDevices(&operationStack().lock()); - - if (!operationStack().previewDevices().isEmpty()) - setSelectedDevice(operationStack().previewDevices()[0]); - - updatePartitions(); - - Log() << i18nc("@info/plain", "Scan finished."); - KApplication::restoreOverrideCursor(); - - scanProgressDialog().hide(); -} - -void PartitionManagerWidget::enableActions() -{ - actionCollection()->action("createNewPartitionTable")->setEnabled(CreatePartitionTableOperation::canCreate(selectedDevice())); - - actionCollection()->action("undoOperation")->setEnabled(numPendingOperations() > 0); - actionCollection()->action("clearAllOperations")->setEnabled(numPendingOperations() > 0); - actionCollection()->action("applyAllOperations")->setEnabled(numPendingOperations() > 0 && (geteuid() == 0 || Config::allowApplyOperationsAsNonRoot())); - - const bool readOnly = selectedDevice() == NULL || selectedDevice()->partitionTable() == NULL || selectedDevice()->partitionTable()->isReadOnly(); - - const Partition* part = selectedPartition(); - - actionCollection()->action("newPartition")->setEnabled(!readOnly && NewOperation::canCreateNew(part)); - const bool canResize = ResizeOperation::canGrow(part) || ResizeOperation::canShrink(part) || ResizeOperation::canMove(part); - actionCollection()->action("resizePartition")->setEnabled(!readOnly && canResize); - actionCollection()->action("copyPartition")->setEnabled(CopyOperation::canCopy(part)); - actionCollection()->action("deletePartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part)); - actionCollection()->action("shredPartition")->setEnabled(!readOnly && DeleteOperation::canDelete(part)); - actionCollection()->action("pastePartition")->setEnabled(!readOnly && CopyOperation::canPaste(part, clipboardPartition())); - actionCollection()->action("propertiesPartition")->setEnabled(part != NULL); - - actionCollection()->action("editMountPoint")->setEnabled(part && part->canMount()); - actionCollection()->action("mountPartition")->setEnabled(part && (part->canMount() || part->canUnmount())); - - if (part != NULL) - actionCollection()->action("mountPartition")->setText(part->isMounted() ? part->fileSystem().unmountTitle() : part->fileSystem().mountTitle() ); - - actionCollection()->action("checkPartition")->setEnabled(!readOnly && CheckOperation::canCheck(part)); - - actionCollection()->action("backupPartition")->setEnabled(BackupOperation::canBackup(part)); - actionCollection()->action("restorePartition")->setEnabled(RestoreOperation::canRestore(part)); -} - void PartitionManagerWidget::clear() { setSelectedDevice(NULL); setClipboardPartition(NULL); treePartitions().clear(); partTableWidget().clear(); - deviceScanner().clear(); } -void PartitionManagerWidget::clearSelectedPartition() +void PartitionManagerWidget::setSelectedPartition(const Partition* p) { - treePartitions().setCurrentItem(NULL); - emit selectedPartitionChanged(NULL); - enableActions(); - updatePartitions(); + if (p == NULL) + { + treePartitions().setCurrentItem(NULL); + emit selectedPartitionChanged(NULL); + updatePartitions(); + } + else + partTableWidget().setActivePartition(p); +} + +Partition* PartitionManagerWidget::selectedPartition() +{ + 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) @@ -438,11 +200,8 @@ void PartitionManagerWidget::setSelectedDevice(const QString& device_node) void PartitionManagerWidget::setSelectedDevice(Device* d) { - // NOTE: we cannot emit devicesChanged() here because it will end up calling - // ListDevices::updateDevices() which in turn will modify the QListWidget, which - // will then emit itemSelectionChanged() which will in the end lead us back here. m_SelectedDevice = d; - clearSelectedPartition(); + setSelectedPartition(NULL); } static QTreeWidgetItem* createTreeWidgetItem(const Partition& p) @@ -533,9 +292,15 @@ void PartitionManagerWidget::on_m_TreePartitions_currentItemChanged(QTreeWidgetI void PartitionManagerWidget::on_m_TreePartitions_itemDoubleClicked(QTreeWidgetItem* item, int) { if (item == treePartitions().topLevelItem(0)) - actionCollection()->action("propertiesDevice")->trigger(); + { + if (selectedDevice() != NULL) + emit deviceDoubleClicked(selectedDevice()); + } else - actionCollection()->action("propertiesPartition")->trigger(); + { + if (selectedPartition() != NULL) + emit partitionDoubleClicked(selectedPartition()); + } } void PartitionManagerWidget::onHeaderContextMenu(const QPoint& p) @@ -571,8 +336,6 @@ void PartitionManagerWidget::onHeaderContextMenu(const QPoint& p) void PartitionManagerWidget::on_m_PartTableWidget_itemSelectionChanged(PartWidget* item) { - enableActions(); - if (item == NULL) { treePartitions().setCurrentItem(NULL); @@ -602,77 +365,18 @@ void PartitionManagerWidget::on_m_PartTableWidget_itemSelectionChanged(PartWidge void PartitionManagerWidget::on_m_PartTableWidget_customContextMenuRequested(const QPoint& pos) { - showPartitionContextMenu(partTableWidget().mapToGlobal(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) { - showPartitionContextMenu(treePartitions().viewport()->mapToGlobal(pos)); -} - -void PartitionManagerWidget::showPartitionContextMenu(const QPoint& pos) -{ - Q_ASSERT(actionCollection()); - - if (actionCollection() == NULL) - return; - - if (selectedPartition() == NULL) - { - if (selectedDevice() != NULL) - { - // show context menu for device - return; - } - - return; - } - - KMenu partitionMenu; - - partitionMenu.addAction(actionCollection()->action("newPartition")); - partitionMenu.addAction(actionCollection()->action("resizePartition")); - partitionMenu.addAction(actionCollection()->action("deletePartition")); - partitionMenu.addAction(actionCollection()->action("shredPartition")); - partitionMenu.addSeparator(); - partitionMenu.addAction(actionCollection()->action("copyPartition")); - partitionMenu.addAction(actionCollection()->action("pastePartition")); - partitionMenu.addSeparator(); - partitionMenu.addAction(actionCollection()->action("editMountPoint")); - partitionMenu.addAction(actionCollection()->action("mountPartition")); - partitionMenu.addSeparator(); - partitionMenu.addAction(actionCollection()->action("checkPartition")); - partitionMenu.addSeparator(); - partitionMenu.addAction(actionCollection()->action("propertiesPartition")); - - partitionMenu.exec(pos); -} - -void PartitionManagerWidget::setPartitionTable(const PartitionTable* ptable) -{ - partTableWidget().setPartitionTable(ptable); -} - -void PartitionManagerWidget::setSelection(const Partition* p) -{ - partTableWidget().setActivePartition(p); -} - -quint32 PartitionManagerWidget::numPendingOperations() -{ - return operationStack().size(); -} - -Partition* PartitionManagerWidget::selectedPartition() -{ - 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)); + emit contextMenuRequested(treePartitions().viewport()->mapToGlobal(pos)); } void PartitionManagerWidget::onPropertiesPartition() @@ -695,7 +399,6 @@ void PartitionManagerWidget::onPropertiesPartition() operationStack().push(new SetPartFlagsOperation(*selectedDevice(), *selectedPartition(), dlg->newFlags())); updatePartitions(); - emit operationsChanged(); } delete dlg; @@ -730,7 +433,6 @@ void PartitionManagerWidget::onMountPartition() kWarning() << "parent is null"; } - enableActions(); updatePartitions(); } @@ -799,7 +501,6 @@ void PartitionManagerWidget::onNewPartition() PartitionTable::snap(*selectedDevice(), *newPartition); operationStack().push(new NewOperation(*selectedDevice(), newPartition)); updatePartitions(); - emit operationsChanged(); } else delete newPartition; @@ -857,7 +558,6 @@ void PartitionManagerWidget::onDeletePartition(bool shred) operationStack().push(new DeleteOperation(*selectedDevice(), selectedPartition(), shred)); updatePartitions(); - emit operationsChanged(); } void PartitionManagerWidget::onShredPartition() @@ -901,7 +601,6 @@ void PartitionManagerWidget::onResizePartition() operationStack().push(new ResizeOperation(*selectedDevice(), *selectedPartition(), resizedPartition.firstSector(), resizedPartition.lastSector())); updatePartitions(); - emit operationsChanged(); } } @@ -920,8 +619,6 @@ void PartitionManagerWidget::onCopyPartition() setClipboardPartition(selectedPartition()); Log() << i18nc("@info/plain", "Partition %1 has been copied to the clipboard.", selectedPartition()->deviceNode()); - - enableActions(); } void PartitionManagerWidget::onPastePartition() @@ -960,7 +657,6 @@ void PartitionManagerWidget::onPastePartition() { operationStack().push(new CopyOperation(*selectedDevice(), copiedPartition, *dSource, clipboardPartition())); updatePartitions(); - emit operationsChanged(); } else delete copiedPartition; @@ -1014,107 +710,6 @@ bool PartitionManagerWidget::showInsertDialog(Partition& insertPartition, qint64 return true; } -void PartitionManagerWidget::onCreateNewPartitionTable() -{ - Q_ASSERT(selectedDevice()); - - if (selectedDevice() == NULL) - { - kWarning() << "selected device is null."; - return; - } - - QPointer dlg = new CreatePartitionTableDialog(this, *selectedDevice()); - - if (dlg->exec() == KDialog::Accepted) - { - operationStack().push(new CreatePartitionTableOperation(*selectedDevice(), dlg->type())); - - updatePartitions(); - emit operationsChanged(); - emit devicesChanged(); - enableActions(); - } - - delete dlg; -} - -void PartitionManagerWidget::onRefreshDevices() -{ - if (numPendingOperations() == 0 || KMessageBox::warningContinueCancel(this, - i18nc("@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")), - KStandardGuiItem::cancel(), "reallyRescanDevices") == KMessageBox::Continue) - { - scanDevices(); - } -} - -void PartitionManagerWidget::onUndoOperation() -{ - Log() << i18nc("@info/plain", "Undoing operation: %1", operationStack().operations().last()->description()); - operationStack().pop(); - - updatePartitions(); - emit operationsChanged(); - emit devicesChanged(); - enableActions(); -} - -void PartitionManagerWidget::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")), - KStandardGuiItem::cancel(), "reallyClearPendingOperations") == KMessageBox::Continue) - { - Log() << i18nc("@info/plain", "Clearing the list of pending operations."); - operationStack().clearOperations(); - - updatePartitions(); - emit operationsChanged(); - enableActions(); - } -} - -void PartitionManagerWidget::onApplyAllOperations() -{ - QStringList opList; - - foreach (const Operation* op, operationStack().operations()) - opList.append(op->description()); - - if (KMessageBox::warningContinueCancelList(this, - i18nc("@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")), - 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); - } - - updatePartitions(); - - operationRunner().start(); - } -} - void PartitionManagerWidget::onCheckPartition() { Q_ASSERT(selectedDevice()); @@ -1129,7 +724,6 @@ void PartitionManagerWidget::onCheckPartition() operationStack().push(new CheckOperation(*selectedDevice(), *selectedPartition())); updatePartitions(); - emit operationsChanged(); } void PartitionManagerWidget::onBackupPartition() @@ -1153,7 +747,6 @@ void PartitionManagerWidget::onBackupPartition() { operationStack().push(new BackupOperation(*selectedDevice(), *selectedPartition(), fileName)); updatePartitions(); - emit operationsChanged(); } } @@ -1188,48 +781,10 @@ void PartitionManagerWidget::onRestorePartition() if (showInsertDialog(*restorePartition, restorePartition->length())) { operationStack().push(new RestoreOperation(*selectedDevice(), restorePartition, fileName)); - updatePartitions(); - emit operationsChanged(); } else delete restorePartition; } } -void PartitionManagerWidget::onFileSystemSupport() -{ - FileSystemSupportDialog dlg(this); - dlg.exec(); -} - -void PartitionManagerWidget::onSettingsChanged(const QString&) -{ - enableActions(); - updatePartitions(); -} - -void PartitionManagerWidget::onConfigureOptions() -{ - if (ConfigureOptionsDialog::showDialog("Settings")) - return; - - QPointer dlg = new ConfigureOptionsDialog(this, "Settings", Config::self()); - - connect(dlg, SIGNAL(settingsChanged(const QString&)), SLOT(onSettingsChanged(const QString&))); - - dlg->show(); -} - -void PartitionManagerWidget::onPropertiesDevice(const QString&) -{ - Q_ASSERT(selectedDevice()); - - if (selectedDevice()) - { - QPointer dlg = new DevicePropsDialog(this, *selectedDevice()); - dlg->exec(); - delete dlg; - } -} - diff --git a/src/gui/partitionmanagerwidget.h b/src/gui/partitionmanagerwidget.h index 1cacaff..0620820 100644 --- a/src/gui/partitionmanagerwidget.h +++ b/src/gui/partitionmanagerwidget.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008,2009 by Volker Lanz * + * Copyright (C) 2008,2009,2010 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 * @@ -21,23 +21,22 @@ #define PARTITIONMANAGERWIDGET__H -#include "util/libpartitionmanagerexport.h" - -#include "core/operationrunner.h" #include "core/operationstack.h" -#include "core/devicescanner.h" +#include "core/operationrunner.h" + +#include "util/libpartitionmanagerexport.h" #include "ui_partitionmanagerwidgetbase.h" #include +class Partition; +class PartWidget; +class Device; + class QWidget; class QLabel; -class PartWidget; -class KActionCollection; -class Device; -class ApplyProgressDialog; -class ScanProgressDialog; +class QPoint; /** @brief The central widget for the application. @@ -49,56 +48,58 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT PartitionManagerWidget : public QWidget, Q_DISABLE_COPY(PartitionManagerWidget) public: - explicit PartitionManagerWidget(QWidget* parent, KActionCollection* coll = NULL); + PartitionManagerWidget(QWidget* parent); virtual ~PartitionManagerWidget(); signals: - void devicesChanged(); - void operationsChanged(); void selectedPartitionChanged(const Partition*); + void contextMenuRequested(const QPoint&); + void deviceDoubleClicked(const Device*); + void partitionDoubleClicked(const Partition* p); public 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 onCheckPartition(); + + void onBackupPartition(); + void onRestorePartition(); + + void onPropertiesPartition(); + public: - void init(KActionCollection* coll, const QString& config_name); - KActionCollection* actionCollection() const { return m_ActionCollection; } + void init(OperationStack* ostack, const QString& config_name); void clear(); - void clearSelectedPartition(); - void setPartitionTable(const PartitionTable* ptable); - void setSelection(const Partition* p); - void enableActions(); Device* selectedDevice() { return m_SelectedDevice; } const Device* selectedDevice() const { return m_SelectedDevice; } Partition* selectedPartition(); - - OperationStack::Devices& previewDevices() { return operationStack().previewDevices(); } - const OperationStack::Devices& previewDevices() const { return operationStack().previewDevices(); } - const OperationStack::Operations& operations() const { return operationStack().operations(); } - - OperationStack& operationStack() { return m_OperationStack; } - const OperationStack& operationStack() const { return m_OperationStack; } - - void updatePartitions(); + void setSelectedPartition(const Partition* p); Partition* clipboardPartition() { return m_ClipboardPartition; } const Partition* clipboardPartition() const { return m_ClipboardPartition; } void setClipboardPartition(Partition* p) { m_ClipboardPartition = p; } - ApplyProgressDialog& applyProgressDialog() { Q_ASSERT(m_ApplyProgressDialog); return *m_ApplyProgressDialog; } - const ApplyProgressDialog& applyProgressDialog() const { Q_ASSERT(m_ApplyProgressDialog); return *m_ApplyProgressDialog; } - - ScanProgressDialog& scanProgressDialog() { Q_ASSERT(m_ScanProgressDialog); return *m_ScanProgressDialog; } - const ScanProgressDialog& scanProgressDialog() const { Q_ASSERT(m_ScanProgressDialog); return *m_ScanProgressDialog; } - - quint32 numPendingOperations(); + void updatePartitions(); protected: - void setupActions(); + OperationStack& operationStack() { return *m_OperationStack; } + const OperationStack& operationStack() const { return *m_OperationStack; } + void setupConnections(); void showPartitionContextMenu(const QPoint& pos); void loadConfig(); @@ -111,53 +112,19 @@ class LIBPARTITIONMANAGERPRIVATE_EXPORT PartitionManagerWidget : public QWidget, QTreeWidget& treePartitions() { Q_ASSERT(m_TreePartitions); return *m_TreePartitions; } const QTreeWidget& treePartitions() const { Q_ASSERT(m_TreePartitions); return *m_TreePartitions; } - OperationRunner& operationRunner() { return m_OperationRunner; } - const OperationRunner& operationRunner() const { return m_OperationRunner; } - - DeviceScanner& deviceScanner() { return m_DeviceScanner; } - const DeviceScanner& deviceScanner() const { return m_DeviceScanner; } - protected slots: void on_m_TreePartitions_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous); - void on_m_PartTableWidget_customContextMenuRequested(const QPoint& pos); 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 scanDevices(); - void onScanDevicesFinished(); - void onScanDevicesProgressChanged(const QString& device_node, int percent); - - void onPropertiesPartition(); - void onPropertiesDevice(const QString& device_node = QString()); - void onMountPartition(); - void onEditMountPoint(); - void onNewPartition(); - void onDeletePartition(bool shred = false); - void onShredPartition(); - void onResizePartition(); - void onCopyPartition(); - void onPastePartition(); - void onCheckPartition(); - void onCreateNewPartitionTable(); - void onRefreshDevices(); - void onUndoOperation(); - void onClearAllOperations(); - void onApplyAllOperations(); - void onFileSystemSupport(); - void onBackupPartition(); - void onRestorePartition(); - void onConfigureOptions(); - void onSettingsChanged(const QString&); void onHeaderContextMenu(const QPoint& p); private: - OperationStack m_OperationStack; - OperationRunner m_OperationRunner; - DeviceScanner m_DeviceScanner; - ApplyProgressDialog* m_ApplyProgressDialog; - ScanProgressDialog* m_ScanProgressDialog; - KActionCollection* m_ActionCollection; + OperationStack* m_OperationStack; Device* m_SelectedDevice; Partition* m_ClipboardPartition; }; diff --git a/src/gui/parttablewidget.cpp b/src/gui/parttablewidget.cpp index 1fb10bb..bf3fb95 100644 --- a/src/gui/parttablewidget.cpp +++ b/src/gui/parttablewidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Volker Lanz * + * Copyright (C) 2008,2010 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 * @@ -160,5 +160,5 @@ void PartTableWidget::mouseDoubleClickEvent(QMouseEvent* event) const PartWidget* child = static_cast(childAt(event->pos())); if (child != NULL) - emit itemActivated(child); + emit itemDoubleClicked(child); } diff --git a/src/gui/parttablewidget.h b/src/gui/parttablewidget.h index 5acdaf2..fc356ed 100644 --- a/src/gui/parttablewidget.h +++ b/src/gui/parttablewidget.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2008 by Volker Lanz * + * Copyright (C) 2008,2010 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 * @@ -58,7 +58,7 @@ class PartTableWidget : public QWidget, public PartWidgetBase signals: void itemSelectionChanged(PartWidget*); - void itemActivated(const PartWidget*); + void itemDoubleClicked(const PartWidget*); protected: void resizeEvent(QResizeEvent* event); diff --git a/src/kpart/partitionmanagerpart.rc b/src/kpart/partitionmanagerpart.rc index 71a2bac..31dcfda 100644 --- a/src/kpart/partitionmanagerpart.rc +++ b/src/kpart/partitionmanagerpart.rc @@ -1,6 +1,6 @@ - + Edit Toolbar @@ -22,6 +22,7 @@ Device Toolbar +