1
//MountManager - the program for easy mounting of storage devices in Linux
2
//Copyright (C) 2007-2008 Tikhonov Sergey
4
//This file is part of MountManager Gui
6
//This program is free software; you can redistribute it and/or
7
//modify it under the terms of the GNU General Public License
8
//as published by the Free Software Foundation; either version 2
9
//of the License, or (at your option) any later version.
11
//This program is distributed in the hope that it will be useful,
12
//but WITHOUT ANY WARRANTY; without even the implied warranty of
13
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
//GNU General Public License for more details.
16
//You should have received a copy of the GNU General Public License
17
//along with this program; if not, write to the Free Software
18
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
#include <QtGui/QVBoxLayout>
20
#include <QtGui/QHBoxLayout>
21
#include <QtGui/QPushButton>
22
#include <QtGui/QStackedWidget>
23
#include <QtGui/QScrollArea>
24
#include <QtGui/QCheckBox>
25
#include <QtGui/QAction>
26
#include <QtGui/QComboBox>
27
#include <QtGui/QLabel>
28
#include <QtGui/QLineEdit>
29
#include <QtCore/QSettings>
31
#include "treewidget.h"
32
#include "../core/diskcore.h"
33
#include "../core/diskdevice.h"
34
#include "centralwidget.h"
35
#include "messagebar.h"
36
#include "volumewidget.h"
37
#include "swapwidget.h"
38
#include "diskwidget.h"
39
#include "infobutton.h"
40
#include "widgetformount.h"
43
CentralWidget::CentralWidget(DiskCore *diskCore,PopupWindow *popup) {
46
mountWidget = new WidgetForMount(core);
50
leftWidget = new QWidget;
52
treeWidget = new TreeWidget(true);
53
treeWidget->setColumnCount(3);
54
treeWidget->setHeaderLabels(QStringList() << tr("Device") << tr("Size") << tr("File system"));
55
treeWidget->setContextMenuIcon(QIcon(PROGRAM_ICON_PATH));
56
treeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
58
mountAction = new QAction(treeWidget);
59
mountAction->setText(tr("Mount"));
60
mountAction->setIcon(QIcon(ICONS_PATH"mount.png"));
62
unmountAction = new QAction(treeWidget);
63
unmountAction->setText(tr("Unmount"));
64
unmountAction->setIcon(QIcon(ICONS_PATH"umount.png"));
66
setAutomountAction = new QAction(treeWidget);
67
setAutomountAction->setText(tr("Set auto-mounting"));
68
setAutomountAction->setIcon(QIcon(ICONS_PATH"set_auto_mount.png"));
70
treeWidget->addContextMenuAction(mountAction);
71
treeWidget->addContextMenuAction(unmountAction);
72
treeWidget->addContextMenuSeparator();
73
treeWidget->addContextMenuAction(setAutomountAction);
75
settingsWidget = new QWidget;
76
settingsWidget->setWhatsThis(tr("Show advanced settings"));
78
settingsWidgetLayout = new QVBoxLayout;
80
showTrayMessages = new QCheckBox(tr("Show tray messages"));
81
settingsWidgetLayout->addWidget(showTrayMessages);
83
format = new QComboBox;
84
format->addItem(tr("As UUID"),"uuid");
85
format->addItem(tr("As label"),"label");
86
format->addItem(tr("As name"),"name");
88
formatInfoButton = new InfoButton(popupWindow);
89
formatInfoButton->setPopupText(tr("There are some formats of writing in configuration file. \"Name\" format is the worst variant, for devices names can be changed, \"label\" format is also not very good, because not every device has its label, but \"UUID\" format is the best, because every device has a unique UUID."));
90
formatInfoButton->setPopupHeaderText(tr("Writing format"));
92
QHBoxLayout *formatLayout = new QHBoxLayout;
93
formatLayout->addWidget(formatInfoButton);
94
formatLayout->addWidget(new QLabel(tr("Format") + ":"));
95
formatLayout->addWidget(format);
96
formatLayout->addStretch();
98
devicesFilter = new QLineEdit;
99
connect(devicesFilter,SIGNAL(textChanged(const QString&)),this,SLOT(setFilter(const QString&)));
101
filterButton = new QPushButton;
102
filterButton->setIcon(QIcon(ICONS_PATH"clear_left.png"));
103
filterButton->setFlat(true);
104
filterButton->setEnabled(false);
105
connect(filterButton,SIGNAL(clicked()),devicesFilter,SLOT(clear()));
107
QHBoxLayout *filterLayout = new QHBoxLayout;
108
filterLayout->addWidget(devicesFilter);
109
filterLayout->addWidget(filterButton);
111
settingsWidgetLayout->addLayout(formatLayout);
113
settingsWidget->setLayout(settingsWidgetLayout);
115
settingsButton = new QPushButton(tr("Settings"));
117
settingsButtonLayout = new QHBoxLayout;
118
settingsButtonLayout->addWidget(settingsButton);
119
settingsButtonLayout->addStretch();
121
leftWidgetLayout = new QVBoxLayout;
122
leftWidgetLayout->addWidget(treeWidget);
123
leftWidgetLayout->addLayout(filterLayout);
124
leftWidgetLayout->addWidget(settingsWidget);
125
leftWidgetLayout->addLayout(settingsButtonLayout);
127
leftWidget->setLayout(leftWidgetLayout);
130
rightWidget = new QWidget;
132
rightSplitter = new QSplitter;
134
stackedWidget = new QStackedWidget;
135
messageBarsArea = new QScrollArea;
137
rightSplitter->addWidget(stackedWidget);
138
rightSplitter->addWidget(messageBarsArea);
139
rightSplitter->setStretchFactor(0,1);
140
rightSplitter->setOrientation(Qt::Vertical);
141
rightSplitter->setCollapsible(0,false);
142
rightSplitter->setCollapsible(1,false);
144
rightWidgetLayout = new QVBoxLayout;
145
rightWidgetLayout->addWidget(mountWidget);
146
rightWidgetLayout->addWidget(rightSplitter);
148
rightWidget->setLayout(rightWidgetLayout);
150
areaWidget = new QWidget;
151
areaWidgetLayout = new QVBoxLayout;
152
areaWidget->setLayout(areaWidgetLayout);
153
messageBarsArea->setWidget(areaWidget);
154
messageBarsArea->setWidgetResizable(true);
156
addWidget(leftWidget);
157
addWidget(rightWidget);
159
setStretchFactor(1,1);
160
setCollapsible(0,false);
161
setCollapsible(1,false);
163
for (int i = core->devices().count()-1; i >= 0; i--)
164
addDevice(core->devices()[i]);
166
treeWidget->expandAll();
167
treeWidget->resizeColumnToContents(0);
168
treeWidget->resizeColumnToContents(1);
169
treeWidget->resizeColumnToContents(2);
172
connect(settingsButton,SIGNAL(clicked()),this,SLOT(hideOrShowSettingsWidget()));
173
connect(treeWidget,SIGNAL(contextMenuEventSignal()),this,SLOT(showMenu()));
174
connect(treeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(itemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
175
connect(core,SIGNAL(deviceAdded(DiskDevice *)),this,SLOT(deviceAdded(DiskDevice *)));
176
connect(core,SIGNAL(deviceRemoved(DiskDevice *)),this,SLOT(removeDevice(DiskDevice *)));
177
connect(core,SIGNAL(errorAppeared(const QString &)),this,SLOT(showError(const QString &)));
178
connect(mountAction,SIGNAL(triggered()),this,SLOT(mount()));
179
connect(unmountAction,SIGNAL(triggered()),this,SLOT(unmount()));
180
connect(setAutomountAction,SIGNAL(triggered()),this,SLOT(setAutomount()));
183
CentralWidget::~CentralWidget() {
185
delete unmountAction;
186
delete setAutomountAction;
188
delete devicesFilter;
191
delete showTrayMessages;
193
delete formatInfoButton;
194
delete settingsWidgetLayout;
195
delete settingsWidget;
196
delete settingsButton;
197
delete settingsButtonLayout;
198
delete leftWidgetLayout;
201
delete stackedWidget;
202
delete messageBarsArea;
204
delete rightSplitter;
205
delete rightWidgetLayout;
209
QList<QAction *> CentralWidget::actions() const {
210
return QList<QAction *>() << mountAction << unmountAction << setAutomountAction;
213
void CentralWidget::addDevice(DiskDevice *addedDevice) {
214
QTreeWidgetItem *parentItem = parentItemForDevice(addedDevice);
215
DiskDevice *parentDevice = parentForDevice(addedDevice);
216
QTreeWidgetItem *addedDeviceItem = 0;
217
VolumeWidget *volumeWidget = 0;
218
DiskWidget *diskWidget = 0;
219
SwapWidget *swapWidget = 0;
220
if (addedDevice->isCdOrFloppy()) {
222
Cd and floppy devices have another behaviour as other devices.
223
When cd or floppy disk is inserted, then child item is shown
224
and the child item has similar widget as from physical disks.
226
if (addedDevice->isDisk()) {
227
addedDeviceItem = new QTreeWidgetItem(treeWidget);
228
if (addedDevice->isSupportDvd())
229
addedDeviceItem->setText(2,tr("Changable"));
230
else if (addedDevice->type() == "cdrom")
231
addedDeviceItem->setText(2,"iso9660");
233
addedDeviceItem->setText(2,addedDevice->fileSystem());
235
volumeWidget = new VolumeWidget(core,addedDevice,popupWindow);
236
stackedWidget->addWidget(volumeWidget);
238
parentDevice->setCdOrFloppyChild(addedDevice);
239
parentItem->setText(1,addedDevice->size(DiskDevice::Truncation));
240
parentItem->setText(2,addedDevice->fileSystem());
243
} else if (addedDevice->isDisk()) {
244
addedDeviceItem = new QTreeWidgetItem(treeWidget);
245
addedDeviceItem->setText(2,tr("Disk"));
247
diskWidget = new DiskWidget(addedDevice);
248
stackedWidget->addWidget(diskWidget);
250
addedDeviceItem = new QTreeWidgetItem(parentItem);
251
// Maybe this device is extended and has unknown file system
252
if (addedDevice->fileSystem().isEmpty()) {
253
delete addedDeviceItem;
256
addedDeviceItem->setText(2,addedDevice->fileSystem());
258
if (addedDevice->fileSystem() == "swap") {
259
swapWidget = new SwapWidget(addedDevice);
260
stackedWidget->addWidget(swapWidget);
262
volumeWidget = new VolumeWidget(core,addedDevice,popupWindow);
263
stackedWidget->addWidget(volumeWidget);
265
Device *parent = deviceByItem(parentItem);
266
if (parent && parent->diskWidget)
267
parent->diskWidget->addVolume(addedDevice);
270
if (parentItem) treeWidget->expandItem(parentItem);
272
if (addedDeviceItem) {
273
if (addedDevice->fileSystem().isEmpty() && showTrayMessages->isChecked())
274
emit(showTrayMessage(tr("Device added"),tr("New storage device with unknown file system was detected: %1").arg(addedDevice->blockName())));
275
else if (showTrayMessages->isChecked())
276
emit(showTrayMessage(tr("Device added"),tr("New storage device was detected: %1").arg(addedDevice->blockName())));
277
if (addedDevice->type() == "cdrom")
278
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"cdrom_disk.png"));
279
else if (addedDevice->type() == "floppy")
280
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"floppy_disk.png"));
281
else if (addedDevice->type() == "memory_stick")
282
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"memory_stick_disk.png"));
283
else if (addedDevice->isRemovable())
284
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"usb_disk.png"));
285
else if (addedDevice->isDisk())
286
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"physical_disk.png"));
288
addedDeviceItem->setIcon(0,QIcon(ICONS_PATH"logical_disk.png"));
291
connect(volumeWidget,SIGNAL(optionsChanged()),this,SLOT(updateCurrentFstabContent()));
293
QString shortBlockName = addedDevice->blockName();
294
shortBlockName.remove("/dev/");
295
addedDeviceItem->setText(0,shortBlockName);
296
addedDeviceItem->setText(1,addedDevice->size(DiskDevice::Truncation));
298
Device *device = new Device;
299
device->treeWidgetItem = addedDeviceItem;
300
device->diskDevice = addedDevice;
301
device->volumeWidget = volumeWidget;
302
device->diskWidget = diskWidget;
303
device->swapWidget = swapWidget;
304
device->index = devices.count();
305
devices.append(device);
309
void CentralWidget::deviceAdded(DiskDevice *addedDevice) {
310
if (!addedDevice->isDisk()) {
311
MessageBar *messageBar = new MessageBar;
312
areaWidgetLayout->insertWidget(0,messageBar);
313
messageBar->setDevice(addedDevice);
315
connect(messageBar,SIGNAL(activated()),this,SLOT(checkMessageBars()));
316
messageBar->setMessage(MessageBar::Information,tr("New storage device was detected: %1").arg(addedDevice->blockName()));
317
messageBar->addAction(MessageBar::Mount);
318
messageBar->addAction(MessageBar::UnMount);
320
connect(messageBar,SIGNAL(mountSignal(DiskDevice *)),this,SLOT(mount(DiskDevice *)));
321
connect(messageBar,SIGNAL(unmountSignal(DiskDevice *)),this,SLOT(unmount(DiskDevice *)));
322
messageBars.append(messageBar);
325
addDevice(addedDevice);
328
void CentralWidget::removeDevice(DiskDevice *removedDevice) {
329
if (removedDevice->isCdOrFloppy()) {
330
removedDevice->parent()->removeCdOrFloppyChild();
331
QTreeWidgetItem *parentItem = parentItemForDevice(removedDevice);
332
DiskDevice *parentDevice = removedDevice->parent();
333
parentItem->setText(1,parentDevice->size(DiskDevice::Truncation));
334
parentItem->setText(2,parentDevice->fileSystem());
335
if (parentDevice->isSupportDvd())
336
parentItem->setText(2,tr("Changable"));
337
else if (parentDevice->type() == "cdrom")
338
parentItem->setText(2,"iso9660");
340
parentItem->setText(2,parentDevice->fileSystem());
342
if (showTrayMessages->isChecked())
343
emit(showTrayMessage(tr("Device removed"),tr("Storage device was removed: %1").arg(removedDevice->blockName())));
344
foreach (Device *device,devices) {
345
if (device->diskDevice == removedDevice) {
346
delete device->treeWidgetItem;
347
// Hide all messages bars which have information about this device
348
foreach (MessageBar *messageBar,messageBars)
349
if (messageBar->device() == removedDevice)
351
devices.removeAll(device);
357
QTreeWidgetItem *CentralWidget::parentItemForDevice(DiskDevice *childDevice) {
358
foreach (Device *device,devices)
359
if (device->diskDevice == childDevice->parent())
360
return device->treeWidgetItem;
364
DiskDevice *CentralWidget::parentForDevice(DiskDevice *childDevice) {
365
foreach (Device *device,devices)
366
if (device->diskDevice == childDevice->parent())
367
return device->diskDevice;
371
QList<Device *> CentralWidget::childsForDevice(DiskDevice *parentDevice) {
372
QList<Device *> childDevices;
373
foreach (Device *device,devices)
374
if (device->diskDevice->parent() == parentDevice)
375
childDevices.append(device);
379
DiskDevice *CentralWidget::currentDiskDevice() {
380
foreach (Device *device,devices)
381
if (device->treeWidgetItem == treeWidget->currentItem())
382
return device->diskDevice;
386
Device *CentralWidget::deviceByItem(QTreeWidgetItem *item) {
387
foreach (Device *device,devices)
388
if (device->treeWidgetItem == item)
393
Device *CentralWidget::currentDevice() {
394
foreach (Device *device,devices)
395
if (device->diskDevice == currentDiskDevice())
400
void CentralWidget::showInformation(const QString &informationContent) {
401
showMessage(MessageBar::Information,informationContent);
404
void CentralWidget::showWarning(const QString &warningContent) {
405
showMessage(MessageBar::Warning,warningContent);
408
void CentralWidget::showError(const QString &errorContent) {
409
showMessage(MessageBar::Error,errorContent);
412
void CentralWidget::showMessage(int messageType,const QString &messageContent) {
413
MessageBar *messageBar = new MessageBar;
414
messageBar->setMessage(messageType,messageContent);
415
areaWidgetLayout->insertWidget(0,messageBar);
416
messageBars.append(messageBar);
417
connect(messageBar,SIGNAL(activated()),this,SLOT(checkMessageBars()));
421
void CentralWidget::checkMessageBars() {
422
bool showMessageBarsArea = false;
423
foreach (MessageBar *bar,messageBars)
424
if (!bar->isHidden()) {
425
showMessageBarsArea = true;
428
messageBarsArea->setVisible(showMessageBarsArea);
431
void CentralWidget::saveSettings() {
432
QSettings settings(ORGANIZATION,PROGRAM_NAME);
433
settings.setValue("CentralWidget/State",saveState());
434
settings.setValue("CentralWidget/ShowTrayMessages",showTrayMessages->isChecked());
435
settings.setValue("CentralWidget/ShowSettingsWidget",!settingsWidget->isHidden());
436
settings.setValue("CentralWidget/RightSplitterState",rightSplitter->saveState());
440
void CentralWidget::loadSettings() {
441
QSettings settings(ORGANIZATION,PROGRAM_NAME);
442
restoreState(settings.value("CentralWidget/State").toByteArray());
443
showTrayMessages->setChecked(settings.value("CentralWidget/ShowTrayMessages",true).toBool());
444
settingsWidget->setVisible(settings.value("CentralWidget/ShowSettingsWidget",false).toBool());
445
rightSplitter->restoreState(settings.value("CentralWidget/RightSplitterState").toByteArray());
448
void CentralWidget::hideOrShowSettingsWidget() {
449
settingsWidget->setVisible(settingsWidget->isHidden());
452
void CentralWidget::showMenu() {
453
if (!treeWidget->currentItem())
455
DiskDevice *current = currentDiskDevice();
456
treeWidget->setContextMenuHeader(current->blockName());
457
setAutomountAction->setEnabled(current->isUsb());
458
if (current->isCdOrFloppy() && !current->isCdOrFloppyInserted()) {
459
mountAction->setEnabled(false);
460
unmountAction->setEnabled(false);
463
if (current->isDisk() && !current->isCdOrFloppy()) {
464
mountAction->setEnabled(false);
465
unmountAction->setEnabled(false);
468
mountAction->setEnabled(!current->isMounted());
469
unmountAction->setEnabled(current->isMounted());
472
void CentralWidget::itemChanged(QTreeWidgetItem* current,QTreeWidgetItem* previous) {
477
Device *currentDevice = deviceByItem(current);
478
stackedWidget->setCurrentIndex(currentDevice->index);
480
emit (currentDeviceFsChanged(currentDevice->diskDevice->fileSystem()));
483
void CentralWidget::mount(DiskDevice *diskDevice) {
484
if (diskDevice == 0) {
485
Device *device = currentDevice();
486
if (device->volumeWidget)
487
mountWidget->setOptionsForMount(device->diskDevice->blockName(),device->volumeWidget->mountPoint(),
488
device->diskDevice->fileSystem(),device->volumeWidget->options());
490
mountWidget->setOptionsForMount(device->diskDevice->blockName(),device->diskDevice->fstabMountPoint(),
491
device->diskDevice->fileSystem(),device->diskDevice->fstabOptions());
493
mountWidget->setOptionsForMount(diskDevice->blockName(),diskDevice->fstabMountPoint(),
494
diskDevice->fileSystem(),diskDevice->fstabOptions());
498
void CentralWidget::unmount(DiskDevice *device) {
500
device = currentDiskDevice();
501
core->unmount(device);
504
QString CentralWidget::currentFstabText(bool warn) {
506
foreach (Device *device,devices) {
507
if (device->diskDevice->isUsb())
509
if (device->volumeWidget)
510
text += device->volumeWidget->fstabLine(warn,format->itemData(format->currentIndex()).toString()) + '\n';
511
if (device->swapWidget != 0)
512
text += device->swapWidget->fstabLine(format->itemData(format->currentIndex()).toString()) + '\n';
517
void CentralWidget::setAutomount() {
518
Device *device = currentDevice();
519
DiskDevice *deviceToAutomount = 0;
520
VolumeWidget *volumeWidgetToAutomount = 0;
521
if (device->treeWidgetItem->childCount() > 0) {
522
Device *childDevice = childsForDevice(device->diskDevice).first();
523
deviceToAutomount = childDevice->diskDevice;
524
volumeWidgetToAutomount = childDevice->volumeWidget;
526
deviceToAutomount = device->diskDevice;
527
volumeWidgetToAutomount = device->volumeWidget;
529
if (!volumeWidgetToAutomount)
531
if (volumeWidgetToAutomount->mountPoint().isEmpty()) {
532
showError(tr("Mount point of %1 is empty. Choose it to set auto-mount of this device.").arg(deviceToAutomount->blockName()));
535
emit (setAutomountSignal(deviceToAutomount,volumeWidgetToAutomount));
538
void CentralWidget::updateCurrentFstabContent() {
539
currentFstabContent = currentFstabText(false);
540
emit (currentFstabContentChanged(currentFstabContent));
543
void CentralWidget::emitSignalsForPlugins() {
544
if (currentFstabContent.isEmpty())
545
updateCurrentFstabContent();
547
emit (currentFstabContentChanged(currentFstabContent));
548
if (currentDiskDevice())
549
emit (currentDeviceFsChanged(currentDiskDevice()->fileSystem()));
552
void CentralWidget::setFilter(const QString& filter) {
553
filterButton->setEnabled(!filter.isEmpty());
554
foreach (Device *device,devices)
555
if (device->treeWidgetItem && device->diskDevice->isDisk())
556
device->treeWidgetItem->setHidden(true);
557
foreach (QTreeWidgetItem *item, treeWidget->findItems(filter,Qt::MatchContains,0))
558
item->setHidden(false);
559
foreach (QTreeWidgetItem *item, treeWidget->findItems(filter,Qt::MatchContains,1))
560
item->setHidden(false);
561
foreach (QTreeWidgetItem *item, treeWidget->findItems(filter,Qt::MatchContains,2))
562
item->setHidden(false);