File indexing completed on 2024-04-28 12:45:28

0001 /*
0002     This class provides notifications for Smb4K.
0003 
0004     SPDX-FileCopyrightText: 2010-2022 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 // application specific includes
0009 #include "smb4knotification.h"
0010 #include "smb4kbookmark.h"
0011 #include "smb4khost.h"
0012 #include "smb4ksettings.h"
0013 #include "smb4kshare.h"
0014 #include "smb4kworkgroup.h"
0015 
0016 // Qt includes
0017 #include <QEventLoop>
0018 
0019 // KDE includes
0020 #include "kauth_version.h"
0021 #include <KAuth/ActionReply>
0022 #include <KIO/OpenUrlJob>
0023 #include <KIconLoader>
0024 #include <KLocalizedString>
0025 #include <KNotification>
0026 
0027 using namespace KAuth;
0028 
0029 //
0030 // Notifications
0031 //
0032 
0033 void Smb4KNotification::shareMounted(const SharePtr &share)
0034 {
0035     Q_ASSERT(share);
0036 
0037     if (share) {
0038         QEventLoop loop;
0039 
0040         KNotification *notification = new KNotification(QStringLiteral("shareMounted"), KNotification::CloseOnTimeout);
0041         notification->setText(i18n("<p>The share <b>%1</b> has been mounted to <b>%2</b>.</p>", share->displayString(), share->path()));
0042         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("folder-network"),
0043                                                                 KIconLoader::NoGroup,
0044                                                                 0,
0045                                                                 KIconLoader::DefaultState,
0046                                                                 QStringList(QStringLiteral("emblem-mounted"))));
0047 
0048         auto open = [&]() {
0049             KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(share->path()), QStringLiteral("inode/directory"));
0050             job->setFollowRedirections(false);
0051             job->setAutoDelete(true);
0052             job->start();
0053         };
0054 
0055 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0056         auto *openAction = notification->addAction(i18nc("Open the contents of the share with the file manager", "Open"));
0057         QObject::connect(openAction, &KNotificationAction::activated, open);
0058 #else
0059         notification->setActions(QStringList(i18nc("Open the contents of the share with the file manager", "Open")));
0060         QObject::connect(notification, &KNotification::action1Activated, open);
0061 #endif
0062         QObject::connect(notification, &KNotification::closed, &loop, &QEventLoop::quit);
0063 
0064         notification->sendEvent();
0065 
0066         loop.exec();
0067     }
0068 }
0069 
0070 void Smb4KNotification::shareUnmounted(const SharePtr &share)
0071 {
0072     Q_ASSERT(share);
0073 
0074     if (share) {
0075         KNotification *notification = new KNotification(QStringLiteral("shareUnmounted"), KNotification::CloseOnTimeout);
0076         notification->setText(i18n("<p>The share <b>%1</b> has been unmounted from <b>%2</b>.</p>", share->displayString(), share->path()));
0077         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("folder-network"),
0078                                                                 KIconLoader::NoGroup,
0079                                                                 0,
0080                                                                 KIconLoader::DefaultState,
0081                                                                 QStringList(QStringLiteral("emblem-unmounted"))));
0082         notification->sendEvent();
0083     }
0084 }
0085 
0086 void Smb4KNotification::sharesMounted(int number)
0087 {
0088     KNotification *notification = new KNotification(QStringLiteral("sharesMounted"), KNotification::CloseOnTimeout);
0089     notification->setText(i18np("<p>%1 share has been mounted.</p>", "<p>%1 shares have been mounted.</p>", number));
0090     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("folder-network"),
0091                                                             KIconLoader::NoGroup,
0092                                                             0,
0093                                                             KIconLoader::DefaultState,
0094                                                             QStringList(QStringLiteral("emblem-mounted"))));
0095     notification->sendEvent();
0096 }
0097 
0098 void Smb4KNotification::sharesUnmounted(int number)
0099 {
0100     KNotification *notification = new KNotification(QStringLiteral("sharesUnmounted"), KNotification::CloseOnTimeout);
0101     notification->setText(i18np("<p>%1 share has been unmounted.</p>", "<p>%1 shares have been unmounted.</p>", number));
0102     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("folder-network"),
0103                                                             KIconLoader::NoGroup,
0104                                                             0,
0105                                                             KIconLoader::DefaultState,
0106                                                             QStringList(QStringLiteral("emblem-unmounted"))));
0107     notification->sendEvent();
0108 }
0109 
0110 //
0111 // Warnings
0112 //
0113 
0114 void Smb4KNotification::openingWalletFailed(const QString &name)
0115 {
0116     KNotification *notification = new KNotification(QStringLiteral("openingWalletFailed"), KNotification::CloseOnTimeout);
0117     notification->setText(i18n("<p>Opening the wallet <b>%1</b> failed.</p>", name));
0118     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-warning"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0119     notification->sendEvent();
0120 }
0121 
0122 void Smb4KNotification::credentialsNotAccessible()
0123 {
0124     KNotification *notification = new KNotification(QStringLiteral("credentialsNotAccessible"), KNotification::CloseOnTimeout);
0125     notification->setText(
0126         i18n("<p>The credentials stored in the wallet could not be accessed. "
0127              "There is either no wallet available or it could not be opened.</p>"));
0128     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-warning"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0129     notification->sendEvent();
0130 }
0131 
0132 void Smb4KNotification::mimetypeNotSupported(const QString &mimetype)
0133 {
0134     KNotification *notification = new KNotification(QStringLiteral("mimetypeNotSupported"), KNotification::CloseOnTimeout);
0135     notification->setText(
0136         i18n("<p>The mimetype <b>%1</b> is not supported for printing. "
0137              "Please convert the file to PDF or Postscript and try again.</p>",
0138              mimetype));
0139     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-warning"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0140     notification->sendEvent();
0141 }
0142 
0143 void Smb4KNotification::bookmarkExists(const BookmarkPtr &bookmark)
0144 {
0145     Q_ASSERT(bookmark);
0146 
0147     if (bookmark) {
0148         KNotification *notification = new KNotification(QStringLiteral("bookmarkExists"), KNotification::CloseOnTimeout);
0149         notification->setText(i18n("<p>The bookmark for share <b>%1</b> already exists and will be skipped.</p>", bookmark->displayString()));
0150         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-warning"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0151         notification->sendEvent();
0152     }
0153 }
0154 
0155 void Smb4KNotification::bookmarkLabelInUse(const BookmarkPtr &bookmark)
0156 {
0157     Q_ASSERT(bookmark);
0158 
0159     if (bookmark) {
0160         KNotification *notification = new KNotification(QStringLiteral("bookmarkLabelInUse"), KNotification::CloseOnTimeout);
0161         notification->setText(
0162             i18n("<p>The label <b>%1</b> of the bookmark for the share <b>%2</b> "
0163                  "is already being used and will automatically be renamed.</p>",
0164                  bookmark->label(),
0165                  bookmark->displayString()));
0166         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-warning"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0167         notification->sendEvent();
0168     }
0169 }
0170 
0171 //
0172 // Errors
0173 //
0174 void Smb4KNotification::mountingFailed(const SharePtr &share, const QString &err_msg)
0175 {
0176     Q_ASSERT(share);
0177 
0178     if (share) {
0179         QString text;
0180 
0181         if (!err_msg.isEmpty()) {
0182             text = i18n("<p>Mounting the share <b>%1</b> failed:</p><p><tt>%2</tt></p>", share->displayString(), err_msg);
0183         } else {
0184             text = i18n("<p>Mounting the share <b>%1</b> failed.</p>", share->displayString());
0185         }
0186 
0187         KNotification *notification = new KNotification(QStringLiteral("mountingFailed"), KNotification::CloseOnTimeout);
0188         notification->setText(text);
0189         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0190         notification->sendEvent();
0191     }
0192 }
0193 
0194 void Smb4KNotification::unmountingFailed(const SharePtr &share, const QString &err_msg)
0195 {
0196     Q_ASSERT(share);
0197 
0198     if (share) {
0199         QString text;
0200 
0201         if (!err_msg.isEmpty()) {
0202             text = i18n("<p>Unmounting the share <b>%1</b> from <b>%2</b> failed:</p><p><tt>%3</tt></p>", share->displayString(), share->path(), err_msg);
0203         } else {
0204             text = i18n("<p>Unmounting the share <b>%1</b> from <b>%2</b> failed.</p>", share->displayString(), share->path());
0205         }
0206 
0207         KNotification *notification = new KNotification(QStringLiteral("unmountingFailed"), KNotification::CloseOnTimeout);
0208         notification->setText(text);
0209         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0210         notification->sendEvent();
0211     }
0212 }
0213 
0214 void Smb4KNotification::unmountingNotAllowed(const SharePtr &share)
0215 {
0216     Q_ASSERT(share);
0217 
0218     if (share) {
0219         KNotification *notification = new KNotification(QStringLiteral("unmountingNotAllowed"), KNotification::CloseOnTimeout);
0220         notification->setText(
0221             i18n("<p>You are not allowed to unmount the share <b>%1</b> from <b>%2</b>. "
0222                  "It is owned by the user <b>%3</b>.</p>",
0223                  share->displayString(),
0224                  share->path(),
0225                  share->user().loginName()));
0226         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0227         notification->sendEvent();
0228     }
0229 }
0230 
0231 void Smb4KNotification::synchronizationFailed(const QUrl &src, const QUrl &dest, const QString &err_msg)
0232 {
0233     QString text;
0234 
0235     if (!err_msg.isEmpty()) {
0236         text = i18n("<p>Synchronizing <b>%1</b> with <b>%2</b> failed:</p><p><tt>%3</tt></p>", dest.path(), src.path(), err_msg);
0237     } else {
0238         text = i18n("<p>Synchronizing <b>%1</b> with <b>%2</b> failed.</p>", dest.path(), src.path());
0239     }
0240 
0241     KNotification *notification = new KNotification(QStringLiteral("synchronizationFailed"), KNotification::CloseOnTimeout);
0242     notification->setText(text);
0243     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0244     notification->sendEvent();
0245 }
0246 
0247 void Smb4KNotification::commandNotFound(const QString &command)
0248 {
0249     KNotification *notification = new KNotification(QStringLiteral("commandNotFound"), KNotification::CloseOnTimeout);
0250     notification->setText(i18n("<p>The command <b>%1</b> could not be found. Please check your installation.</p>", command));
0251     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0252     notification->sendEvent();
0253 }
0254 
0255 void Smb4KNotification::cannotBookmarkPrinter(const SharePtr &share)
0256 {
0257     Q_ASSERT(share);
0258 
0259     if (share && share->isPrinter()) {
0260         KNotification *notification = new KNotification(QStringLiteral("cannotBookmarkPrinter"), KNotification::CloseOnTimeout);
0261         notification->setText(i18n("<p>The share <b>%1</b> is a printer and cannot be bookmarked.</p>", share->displayString()));
0262         notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0263         notification->sendEvent();
0264     }
0265 }
0266 
0267 void Smb4KNotification::fileNotFound(const QString &fileName)
0268 {
0269     KNotification *notification = new KNotification(QStringLiteral("fileNotFound"), KNotification::CloseOnTimeout);
0270     notification->setText(i18n("<p>The file <b>%1</b> could not be found.</p>", fileName));
0271     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0272     notification->sendEvent();
0273 }
0274 
0275 void Smb4KNotification::openingFileFailed(const QFile &file)
0276 {
0277     QString text;
0278 
0279     if (!file.errorString().isEmpty()) {
0280         text = i18n("<p>Opening the file <b>%1</b> failed:</p><p><tt>%2</tt></p>", file.fileName(), file.errorString());
0281     } else {
0282         text = i18n("<p>Opening the file <b>%1</b> failed.</p>", file.fileName());
0283     }
0284 
0285     KNotification *notification = new KNotification(QStringLiteral("openingFileFailed"), KNotification::CloseOnTimeout);
0286     notification->setText(text);
0287     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0288     notification->sendEvent();
0289 }
0290 
0291 void Smb4KNotification::readingFileFailed(const QFile &file, const QString &err_msg)
0292 {
0293     QString text;
0294 
0295     if (!err_msg.isEmpty()) {
0296         text = i18n("<p>Reading from file <b>%1</b> failed:</p><p><tt>%2</tt></p>", file.fileName(), err_msg);
0297     } else {
0298         if (!file.errorString().isEmpty()) {
0299             text = i18n("<p>Reading from file <b>%1</b> failed:</p><p><tt>%2</tt></p>", file.fileName(), file.errorString());
0300         } else {
0301             text = i18n("<p>Reading from file <b>%1</b> failed.</p>", file.fileName());
0302         }
0303     }
0304 
0305     KNotification *notification = new KNotification(QStringLiteral("readingFileFailed"), KNotification::CloseOnTimeout);
0306     notification->setText(text);
0307     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0308     notification->sendEvent();
0309 }
0310 
0311 void Smb4KNotification::mkdirFailed(const QDir &dir)
0312 {
0313     KNotification *notification = new KNotification(QStringLiteral("mkdirFailed"), KNotification::CloseOnTimeout);
0314     notification->setText(i18n("<p>The following directory could not be created:</p><p><tt>%1</tt></p>", dir.absolutePath()));
0315     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0316     notification->sendEvent();
0317 }
0318 
0319 void Smb4KNotification::processError(QProcess::ProcessError error)
0320 {
0321     QString text;
0322 
0323     switch (error) {
0324     case QProcess::FailedToStart: {
0325         text = i18n("<p>The process failed to start (error code: <tt>%1</tt>).</p>", error);
0326         break;
0327     }
0328     case QProcess::Crashed: {
0329         text = i18n("<p>The process crashed (error code: <tt>%1</tt>).</p>", error);
0330         break;
0331     }
0332     case QProcess::Timedout: {
0333         text = i18n("<p>The process timed out (error code: <tt>%1</tt>).</p>", error);
0334         break;
0335     }
0336     case QProcess::WriteError: {
0337         text = i18n("<p>Could not write to the process (error code: <tt>%1</tt>).</p>", error);
0338         break;
0339     }
0340     case QProcess::ReadError: {
0341         text = i18n("<p>Could not read from the process (error code: <tt>%1</tt>).</p>", error);
0342         break;
0343     }
0344     case QProcess::UnknownError:
0345     default: {
0346         text = i18n("<p>The process reported an unknown error.</p>");
0347         break;
0348     }
0349     }
0350 
0351     KNotification *notification = new KNotification(QStringLiteral("processError"), KNotification::CloseOnTimeout);
0352     notification->setText(text);
0353     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0354     notification->sendEvent();
0355 }
0356 
0357 void Smb4KNotification::actionFailed(int errorCode)
0358 {
0359     QString text, errorMessage;
0360 
0361     switch (errorCode) {
0362     case ActionReply::NoResponderError: {
0363         errorMessage = QStringLiteral("NoResponderError");
0364         break;
0365     }
0366     case ActionReply::NoSuchActionError: {
0367         errorMessage = QStringLiteral("NoSuchActionError");
0368         break;
0369     }
0370     case ActionReply::InvalidActionError: {
0371         errorMessage = QStringLiteral("InvalidActionError");
0372         break;
0373     }
0374     case ActionReply::AuthorizationDeniedError: {
0375         errorMessage = QStringLiteral("AuthorizationDeniedError");
0376         break;
0377     }
0378     case ActionReply::UserCancelledError: {
0379         errorMessage = QStringLiteral("UserCancelledError");
0380         break;
0381     }
0382     case ActionReply::HelperBusyError: {
0383         errorMessage = QStringLiteral("HelperBusyError");
0384         break;
0385     }
0386     case ActionReply::AlreadyStartedError: {
0387         errorMessage = QStringLiteral("AlreadyStartedError");
0388         break;
0389     }
0390     case ActionReply::DBusError: {
0391         errorMessage = QStringLiteral("DBusError");
0392         break;
0393     }
0394     case ActionReply::BackendError: {
0395         errorMessage = QStringLiteral("BackendError");
0396         break;
0397     }
0398     default: {
0399         break;
0400     }
0401     }
0402 
0403     if (!errorMessage.isEmpty()) {
0404         text = i18n("<p>Executing an action with root privileges failed (error code: <tt>%1</tt>).</p>", errorMessage);
0405     } else {
0406         text = i18n("<p>Executing an action with root privileges failed.</p>");
0407     }
0408 
0409     KNotification *notification = new KNotification(QStringLiteral("actionFailed"), KNotification::CloseOnTimeout);
0410     notification->setText(text);
0411     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0412     notification->sendEvent();
0413 }
0414 
0415 void Smb4KNotification::invalidURLPassed()
0416 {
0417     KNotification *notification = new KNotification(QStringLiteral("invalidURL"), KNotification::CloseOnTimeout);
0418     notification->setText(i18n("<p>The URL that was passed is invalid.</p>"));
0419     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0420     notification->sendEvent();
0421 }
0422 
0423 void Smb4KNotification::networkCommunicationFailed(const QString &errorMessage)
0424 {
0425     KNotification *notification = new KNotification(QStringLiteral("networkCommunicationFailed"), KNotification::CloseOnTimeout);
0426     notification->setText(i18n("<p>The network communication failed with the following error message: <s>%1</s></p>", errorMessage));
0427     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0428     notification->sendEvent();
0429 }
0430 
0431 void Smb4KNotification::zeroconfError(const QString &errorMessage)
0432 {
0433     KNotification *notification = new KNotification(QStringLiteral("zeroconfError"), KNotification::CloseOnTimeout);
0434     notification->setText(i18n("<p>An error with the Zeroconf service occurred: <s>%1</s></p>", errorMessage));
0435     notification->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-error"), KIconLoader::NoGroup, 0, KIconLoader::DefaultState));
0436     notification->sendEvent();
0437 }