Changeset View
Changeset View
Standalone View
Standalone View
krusader/MountMan/kmountman.cpp
Show First 20 Lines • Show All 56 Lines • ▼ Show 20 Line(s) | |||||
57 | #include "../FileSystem/krpermhandler.h" | 57 | #include "../FileSystem/krpermhandler.h" | ||
58 | 58 | | |||
59 | #ifdef _OS_SOLARIS_ | 59 | #ifdef _OS_SOLARIS_ | ||
60 | #define FSTAB "/etc/filesystemtab" | 60 | #define FSTAB "/etc/filesystemtab" | ||
61 | #else | 61 | #else | ||
62 | #define FSTAB "/etc/fstab" | 62 | #define FSTAB "/etc/fstab" | ||
63 | #endif | 63 | #endif | ||
64 | 64 | | |||
65 | static int __delayedIdx; // ugly: pass the processEvents deadlock | 65 | KMountMan::KMountMan(QWidget *parent) : QObject(), _operational(false), waiting(false), mountManGui(0), parentWindow(parent) | ||
66 | | ||||
67 | KMountMan::KMountMan(QWidget *parent) : QObject(), Operational(false), waiting(false), mountManGui(0), parentWindow(parent) | | |||
68 | { | 66 | { | ||
69 | _actions = 0L; | | |||
70 | | ||||
71 | _action = new KToolBarPopupAction(QIcon::fromTheme("kr_mountman"), i18n("&MountMan..."), this); | 67 | _action = new KToolBarPopupAction(QIcon::fromTheme("kr_mountman"), i18n("&MountMan..."), this); | ||
72 | connect(_action, SIGNAL(triggered(bool)), SLOT(mainWindow())); | 68 | connect(_action, &QAction::triggered, this, &KMountMan::mainWindow); | ||
73 | connect(_action->menu(), SIGNAL(aboutToShow()), SLOT(quickList())); | 69 | connect(_action->menu(), &QMenu::aboutToShow, this, &KMountMan::quickList); | ||
74 | 70 | _manageAction = _action->menu()->addAction(i18n("Open &MountMan")); | |||
71 | connect(_manageAction, &QAction::triggered, this, &KMountMan::mainWindow); | ||||
72 | _action->menu()->addSeparator(); | ||||
75 | 73 | | |||
76 | // added as a precaution, although we use kde services now | 74 | // added as a precaution, although we use kde services now | ||
77 | if (!KrServices::cmdExist("mount")) { | 75 | _operational = KrServices::cmdExist("mount"); | ||
78 | Operational = false; | | |||
79 | } else { | | |||
80 | Operational = true; | | |||
81 | } | | |||
82 | 76 | | |||
83 | network_fs << "nfs" << "smbfs" << "fuse.fusesmb" << "fuse.sshfs"; //TODO: is this list complete ? | 77 | network_fs << "nfs" << "smbfs" << "fuse.fusesmb" << "fuse.sshfs"; //TODO: is this list complete ? | ||
84 | 78 | | |||
85 | // list of FS that we don't manage at all | 79 | // list of FS that we don't manage at all | ||
86 | invalid_fs << "swap" << "/dev/pts" << "tmpfs" << "devpts" << "sysfs" << "rpc_pipefs" << "usbfs" << "binfmt_misc"; | 80 | invalid_fs << "swap" << "/dev/pts" << "tmpfs" << "devpts" << "sysfs" << "rpc_pipefs" << "usbfs" << "binfmt_misc"; | ||
87 | #ifdef BSD | 81 | #ifdef BSD | ||
88 | invalid_fs << "procfs"; | 82 | invalid_fs << "procfs"; | ||
89 | #else | 83 | #else | ||
Show All 31 Lines | |||||
121 | { | 115 | { | ||
122 | return (network_fs.contains(type) > 0); | 116 | return (network_fs.contains(type) > 0); | ||
123 | } | 117 | } | ||
124 | 118 | | |||
125 | void KMountMan::mainWindow() | 119 | void KMountMan::mainWindow() | ||
126 | { | 120 | { | ||
127 | // left as a precaution, although we use kde's services now | 121 | // left as a precaution, although we use kde's services now | ||
128 | if (!KrServices::cmdExist("mount")) { | 122 | if (!KrServices::cmdExist("mount")) { | ||
129 | KMessageBox::error(0, | 123 | KMessageBox::error(0, i18n("Cannot start 'mount'. Check the 'Dependencies' page in konfigurator.")); | ||
130 | i18n("Cannot start 'mount'. Check the 'Dependencies' page in konfigurator.")); | | |||
131 | return; | 124 | return; | ||
132 | } | 125 | } | ||
133 | 126 | | |||
134 | mountManGui = new KMountManGUI(this); | 127 | mountManGui = new KMountManGUI(this); | ||
135 | delete mountManGui; /* as KMountManGUI is modal, we can now delete it */ | 128 | delete mountManGui; /* as KMountManGUI is modal, we can now delete it */ | ||
136 | mountManGui = 0; /* for sanity */ | 129 | mountManGui = nullptr; /* for sanity */ | ||
137 | } | 130 | } | ||
138 | 131 | | |||
139 | QExplicitlySharedDataPointer<KMountPoint> KMountMan::findInListByMntPoint(KMountPoint::List &lst, QString value) | 132 | QExplicitlySharedDataPointer<KMountPoint> KMountMan::findInListByMntPoint(KMountPoint::List &lst, QString value) | ||
140 | { | 133 | { | ||
141 | if (value.length() > 1 && value.endsWith('/')) | 134 | if (value.length() > 1 && value.endsWith('/')) | ||
142 | value = value.left(value.length() - 1); | 135 | value = value.left(value.length() - 1); | ||
143 | 136 | | |||
144 | QExplicitlySharedDataPointer<KMountPoint> m; | 137 | QExplicitlySharedDataPointer<KMountPoint> m; | ||
Show All 18 Lines | |||||
163 | 156 | | |||
164 | void KMountMan::mount(QString mntPoint, bool blocking) | 157 | void KMountMan::mount(QString mntPoint, bool blocking) | ||
165 | { | 158 | { | ||
166 | QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); | 159 | QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); | ||
167 | if (!udi.isNull()) { | 160 | if (!udi.isNull()) { | ||
168 | Solid::Device device(udi); | 161 | Solid::Device device(udi); | ||
169 | Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); | 162 | Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); | ||
170 | if (access && !access->isAccessible()) { | 163 | if (access && !access->isAccessible()) { | ||
171 | connect(access, SIGNAL(setupDone(Solid::ErrorType,QVariant,QString)), | 164 | connect(access, &Solid::StorageAccess::setupDone, this, &KMountMan::slotSetupDone, Qt::UniqueConnection); | ||
172 | this, SLOT(slotSetupDone(Solid::ErrorType,QVariant,QString))); | | |||
173 | if (blocking) | 165 | if (blocking) | ||
174 | waiting = true; // prepare to block | 166 | waiting = true; // prepare to block | ||
175 | access->setup(); | 167 | access->setup(); | ||
176 | } | 168 | } | ||
177 | } else { | 169 | } else { | ||
178 | KMountPoint::List possible = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions); | 170 | KMountPoint::List possible = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions); | ||
179 | QExplicitlySharedDataPointer<KMountPoint> m = findInListByMntPoint(possible, mntPoint); | 171 | QExplicitlySharedDataPointer<KMountPoint> m = findInListByMntPoint(possible, mntPoint); | ||
180 | if (!((bool)m)) return; | 172 | if (!((bool)m)) return; | ||
Show All 30 Lines | 201 | { | |||
211 | if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) | 203 | if(QUrl::fromLocalFile(QDir(mntPoint).canonicalPath()).isParentOf(QUrl::fromLocalFile(QDir::current().canonicalPath()))) | ||
212 | QDir::setCurrent(QDir::homePath()); | 204 | QDir::setCurrent(QDir::homePath()); | ||
213 | 205 | | |||
214 | QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); | 206 | QString udi = findUdiForPath(mntPoint, Solid::DeviceInterface::StorageAccess); | ||
215 | if (!udi.isNull()) { | 207 | if (!udi.isNull()) { | ||
216 | Solid::Device device(udi); | 208 | Solid::Device device(udi); | ||
217 | Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); | 209 | Solid::StorageAccess *access = device.as<Solid::StorageAccess>(); | ||
218 | if (access && access->isAccessible()) { | 210 | if (access && access->isAccessible()) { | ||
219 | connect(access, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)), | 211 | connect(access, &Solid::StorageAccess::teardownDone, this, &KMountMan::slotTeardownDone, Qt::UniqueConnection); | ||
220 | this, SLOT(slotTeardownDone(Solid::ErrorType,QVariant,QString))); | | |||
221 | access->teardown(); | 212 | access->teardown(); | ||
222 | } | 213 | } | ||
223 | } else { | 214 | } else { | ||
224 | if (blocking) | 215 | if (blocking) | ||
225 | waiting = true; // prepare to block | 216 | waiting = true; // prepare to block | ||
226 | 217 | | |||
227 | // KDE4 doesn't allow unmounting devices as user, because they think it's the right behaviour. | 218 | // KDE4 doesn't allow unmounting devices as user, because they think it's the right behaviour. | ||
228 | // I add this patch, as I don't think so. | 219 | // I add this patch, as I don't think so. | ||
Show All 16 Lines | |||||
245 | while (blocking && waiting) { | 236 | while (blocking && waiting) { | ||
246 | qApp->processEvents(); | 237 | qApp->processEvents(); | ||
247 | usleep(1000); | 238 | usleep(1000); | ||
248 | } | 239 | } | ||
249 | } | 240 | } | ||
250 | 241 | | |||
251 | KMountMan::mntStatus KMountMan::getStatus(QString mntPoint) | 242 | KMountMan::mntStatus KMountMan::getStatus(QString mntPoint) | ||
252 | { | 243 | { | ||
253 | KMountPoint::List::iterator it; | 244 | QExplicitlySharedDataPointer<KMountPoint> mountPoint; | ||
254 | QExplicitlySharedDataPointer<KMountPoint> m; | | |||
255 | 245 | | |||
256 | // 1: is it already mounted | 246 | // 1: is it already mounted | ||
257 | KMountPoint::List current = KMountPoint::currentMountPoints(); | 247 | KMountPoint::List current = KMountPoint::currentMountPoints(); | ||
258 | m = findInListByMntPoint(current, mntPoint); | 248 | mountPoint = findInListByMntPoint(current, mntPoint); | ||
259 | if ((bool)m) | 249 | if ((bool) mountPoint) | ||
260 | return MOUNTED; | 250 | return MOUNTED; | ||
261 | 251 | | |||
262 | // 2: is it a mount point but not mounted? | 252 | // 2: is it a mount point but not mounted? | ||
263 | KMountPoint::List possible = KMountPoint::possibleMountPoints(); | 253 | KMountPoint::List possible = KMountPoint::possibleMountPoints(); | ||
264 | m = findInListByMntPoint(possible, mntPoint); | 254 | mountPoint = findInListByMntPoint(possible, mntPoint); | ||
265 | if ((bool)m) | 255 | if ((bool) mountPoint) | ||
266 | return NOT_MOUNTED; | 256 | return NOT_MOUNTED; | ||
267 | 257 | | |||
268 | // 3: unknown | 258 | // 3: unknown | ||
269 | return DOESNT_EXIST; | 259 | return DOESNT_EXIST; | ||
270 | } | 260 | } | ||
271 | 261 | | |||
272 | 262 | | |||
273 | void KMountMan::toggleMount(QString mntPoint) | 263 | void KMountMan::toggleMount(QString mntPoint) | ||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | 346 | { | |||
383 | } | 373 | } | ||
384 | return s; | 374 | return s; | ||
385 | } | 375 | } | ||
386 | 376 | | |||
387 | 377 | | |||
388 | // populate the pop-up menu of the mountman tool-button with actions | 378 | // populate the pop-up menu of the mountman tool-button with actions | ||
389 | void KMountMan::quickList() | 379 | void KMountMan::quickList() | ||
390 | { | 380 | { | ||
391 | if (!Operational) { | 381 | if (!_operational) { | ||
392 | KMessageBox::error(0, i18n("MountMan is not operational. Sorry")); | 382 | KMessageBox::error(0, i18n("MountMan is not operational. Sorry")); | ||
393 | return; | 383 | return; | ||
394 | } | 384 | } | ||
395 | 385 | | |||
396 | // clear the popup menu | 386 | // clear mount / unmount actions | ||
397 | _action->menu() ->clear(); | 387 | for (QAction *action : _action->menu()->actions()) { | ||
388 | if (action == _manageAction || action->isSeparator()) { | ||||
389 | continue; | ||||
390 | } | ||||
391 | _action->menu()->removeAction(action); | ||||
392 | } | ||||
398 | 393 | | |||
399 | // create lists of current and possible mount points | 394 | // create lists of current and possible mount points | ||
400 | KMountPoint::List current = KMountPoint::currentMountPoints(); | 395 | const KMountPoint::List currentMountPoints = KMountPoint::currentMountPoints(); | ||
401 | KMountPoint::List possible = KMountPoint::possibleMountPoints(); | | |||
402 | 396 | | |||
403 | // create a menu, displaying mountpoints with possible actions | 397 | // create a menu, displaying mountpoints with possible actions | ||
404 | // also, populate a small array with the actions | 398 | for (QExplicitlySharedDataPointer<KMountPoint> possibleMountPoint : KMountPoint::possibleMountPoints()) { | ||
405 | if (_actions) | | |||
406 | delete[] _actions; | | |||
407 | _actions = new QString[ possible.size()]; | | |||
408 | | ||||
409 | KMountPoint::List::iterator it; | | |||
410 | QExplicitlySharedDataPointer<KMountPoint> m; | | |||
411 | int idx; | | |||
412 | for (it = possible.begin(), idx = 0; it != possible.end(); ++it, ++idx) { | | |||
413 | m = it->data(); | | |||
414 | // skip nonmountable file systems | 399 | // skip nonmountable file systems | ||
415 | if (nonmountFilesystem(m->mountType(), m->mountPoint()) || invalidFilesystem(m->mountType())) | 400 | if (nonmountFilesystem(possibleMountPoint->mountType(), possibleMountPoint->mountPoint()) | ||
401 | || invalidFilesystem(possibleMountPoint->mountType())) { | ||||
416 | continue; | 402 | continue; | ||
417 | // does the mountpoint exist in current list? if so, it can only | 403 | } | ||
418 | // be umounted, otherwise, it can be mounted | 404 | // does the mountpoint exist in current list? | ||
405 | // if so, it can only be umounted, otherwise, it can be mounted | ||||
419 | bool needUmount = false; | 406 | bool needUmount = false; | ||
420 | KMountPoint::List::iterator otherIt; | 407 | for (QExplicitlySharedDataPointer<KMountPoint> currentMountPoint : currentMountPoints) { | ||
421 | for (otherIt = current.begin(); otherIt != current.end(); ++otherIt) { | 408 | if (currentMountPoint->mountPoint() == possibleMountPoint->mountPoint()) { | ||
422 | if ((*otherIt) ->mountPoint() == m->mountPoint()) { // found it, in needs umount | 409 | // found -> needs umount | ||
423 | needUmount = true; | 410 | needUmount = true; | ||
424 | break; | 411 | break; | ||
425 | } | 412 | } | ||
426 | } | 413 | } | ||
427 | // add the item to the menu | 414 | // add the item to the menu | ||
428 | _actions[ idx ] = QString(needUmount ? "_U_" : "_M_") + m->mountPoint(); | 415 | const QString text = QString("%1 %2 (%3)").arg(needUmount ? i18n("Unmount") : i18n("Mount"), | ||
429 | QString text = QString((needUmount ? i18n("Unmount") : i18n("Mount"))) + ' ' + m->mountPoint() + | 416 | possibleMountPoint->mountPoint(), possibleMountPoint->mountedFrom()); | ||
430 | " (" + m->mountedFrom() + ')'; | | |||
431 | | ||||
432 | 417 | | |||
433 | QAction * act = _action->menu() ->addAction(text); | 418 | QAction *act = _action->menu()->addAction(text); | ||
434 | act->setData(QVariant(idx)); | 419 | act->setData(QList<QVariant>({ | ||
420 | QVariant(needUmount ? KMountMan::ActionType::Unmount : KMountMan::ActionType::Mount), | ||||
421 | QVariant(possibleMountPoint->mountPoint()) | ||||
422 | })); | ||||
435 | } | 423 | } | ||
436 | connect(_action->menu(), SIGNAL(triggered(QAction*)), | 424 | connect(_action->menu(), &QMenu::triggered, this, &KMountMan::delayedPerformAction); | ||
437 | this, SLOT(delayedPerformAction(QAction*))); | | |||
438 | 425 | | |||
439 | } | 426 | } | ||
440 | 427 | | |||
441 | void KMountMan::delayedPerformAction(QAction * act) | 428 | void KMountMan::delayedPerformAction(const QAction *action) | ||
442 | { | 429 | { | ||
443 | int idx = -1; | | |||
444 | if (act && act->data().canConvert<int>()) | | |||
445 | idx = act->data().toInt(); | | |||
446 | __delayedIdx = idx; | | |||
447 | 430 | | |||
448 | if (idx < 0) | 431 | if (!action || !action->data().canConvert<QList<QVariant>>()) { | ||
449 | return; | 432 | return; | ||
450 | | ||||
451 | QTimer::singleShot(0, this, SLOT(performAction())); | | |||
452 | } | 433 | } | ||
453 | 434 | | |||
454 | void KMountMan::performAction() | 435 | disconnect(_action->menu(), &QMenu::triggered, 0, 0); | ||
455 | { | | |||
456 | if (_actions == 0 || __delayedIdx < 0) // for sanity | | |||
457 | return; | | |||
458 | 436 | | |||
459 | // ugly !!! take idx from the value put there by delayedPerformAction so | 437 | const QList<QVariant> actData = action->data().toList(); | ||
460 | // as to NOT DIE because of a processEvents deadlock!!! @#$@!@ | 438 | const int actionType = actData[0].toInt(); | ||
461 | int idx = __delayedIdx; | 439 | const QString mountPoint = actData[1].toString(); | ||
462 | 440 | | |||
463 | bool domount = _actions[ idx ].left(3) == "_M_"; | 441 | QTimer::singleShot(0, this, [=] { | ||
nmel: Thanks for removing the ugly hacks. | |||||
464 | QString mountPoint = _actions[ idx ].mid(3); | 442 | | ||
465 | if (!domount) { // umount | 443 | if (actionType == KMountMan::ActionType::Mount) { | ||
466 | unmount(mountPoint); | | |||
467 | } else { // mount | | |||
468 | mount(mountPoint); | 444 | mount(mountPoint); | ||
445 | } else { | ||||
446 | unmount(mountPoint); | ||||
469 | } | 447 | } | ||
470 | 448 | }); | |||
How about moving actData[0].toInt() out of lambda? Then "Unpacking" will be done in a single place after line 435. nmel: How about moving actData[0].toInt() out of lambda? Then "Unpacking" will be done in a single… | |||||
Why disconnect is within the lambda? I propose to move it to the body of delayedPerformAction. nmel: Why disconnect is within the lambda? I propose to move it to the body of delayedPerformAction. | |||||
471 | // free memory | | |||
472 | delete[] _actions; | | |||
473 | _actions = 0L; | | |||
474 | disconnect(_action->menu(), SIGNAL(triggered(QAction*)), 0, 0); | | |||
475 | } | 449 | } | ||
476 | 450 | | |||
477 | QString KMountMan::findUdiForPath(QString path, const Solid::DeviceInterface::Type &expType) | 451 | QString KMountMan::findUdiForPath(QString path, const Solid::DeviceInterface::Type &expType) | ||
478 | { | 452 | { | ||
479 | KMountPoint::List current = KMountPoint::currentMountPoints(); | 453 | KMountPoint::List current = KMountPoint::currentMountPoints(); | ||
480 | KMountPoint::List possible = KMountPoint::possibleMountPoints(); | 454 | KMountPoint::List possible = KMountPoint::possibleMountPoints(); | ||
481 | QExplicitlySharedDataPointer<KMountPoint> mp = findInListByMntPoint(current, path); | 455 | QExplicitlySharedDataPointer<KMountPoint> mp = findInListByMntPoint(current, path); | ||
482 | if (!(bool)mp) { | 456 | if (!(bool)mp) { | ||
▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines |
Thanks for removing the ugly hacks.