File indexing completed on 2023-10-03 07:53:59
0001 /* This file is part of the KDE project 0002 0003 Copyright (C) 2005 Dario Massarin <nekkar@libero.it> 0004 Copyright (C) 2009 Lukas Appelhans <l.appelhans@gmx.de> 0005 Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net> 0006 0007 Based on: 0008 kmainwidget.{h,cpp} 0009 Copyright (C) 2002 by Patrick Charbonnier <pch@freeshell.org> 0010 that was based On Caitoo v.0.7.3 (c) 1998 - 2000, Matej Koss 0011 0012 This program is free software; you can redistribute it and/or 0013 modify it under the terms of the GNU General Public 0014 License as published by the Free Software Foundation; either 0015 version 2 of the License, or (at your option) any later version. 0016 */ 0017 0018 #ifndef KGET_H 0019 #define KGET_H 0020 0021 #include <KActionCollection> 0022 #include <KLocalizedString> 0023 #include <KNotification> 0024 #include <KPluginFactory> 0025 0026 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0027 #include <QNetworkConfigurationManager> 0028 #else 0029 #include <QNetworkInformation> 0030 #endif 0031 #include <QDomElement> 0032 0033 #include "kget_export.h" 0034 #include "kuiserverjobs.h" 0035 #include "scheduler.h" 0036 #include "transfer.h" 0037 #include "transfergrouphandler.h" 0038 #include "transferhandler.h" 0039 0040 class QDomElement; 0041 0042 class TransferDataSource; 0043 class TransferGroup; 0044 class TransferFactory; 0045 class TransferTreeModel; 0046 class TransferTreeSelectionModel; 0047 class KGetPlugin; 0048 class MainWindow; 0049 class NewTransferDialog; 0050 class TransferGroupScheduler; 0051 class TransferHistoryStore; 0052 0053 /** 0054 * This is our KGet class. This is where the user's transfers and searches are 0055 * stored and organized. 0056 * Use this class from the views to add or remove transfers or searches 0057 * In order to organize the transfers inside categories we have a TransferGroup 0058 * class. By definition, a transfer must always belong to a TransferGroup. If we 0059 * don't want it to be displayed by the gui inside a specific group, we will put 0060 * it in the group named "Not grouped" (better name?). 0061 **/ 0062 0063 class KGET_EXPORT KGet 0064 { 0065 friend class NewTransferDialog; 0066 friend class NewTransferDialogHandler; 0067 friend class GenericObserver; 0068 friend class TransferTreeModel; 0069 friend class UrlChecker; 0070 0071 public: 0072 enum AfterFinishAction { 0073 Quit = 0, 0074 Shutdown = 1, 0075 Hibernate = 2, 0076 Suspend = 3, 0077 }; 0078 enum DeleteMode { 0079 AutoDelete, 0080 DeleteFiles, 0081 }; 0082 ~KGet(); 0083 0084 static KGet *self(MainWindow *mainWindow = nullptr); 0085 0086 /** 0087 * Adds a new group to the KGet. 0088 * 0089 * @param groupName The name of the new group 0090 * 0091 * @returns true if the group has been successfully added, otherwise 0092 * it returns false, probably because a group with that named 0093 * already exists 0094 */ 0095 static bool addGroup(const QString &groupName); 0096 0097 /** 0098 * Removes a group from the KGet. 0099 * 0100 * @param group The name of the group to be deleted 0101 * @param askUser Whether to ask user about the deletion 0102 */ 0103 static void delGroup(TransferGroupHandler *group, bool askUser = true); 0104 0105 /** 0106 * Removes specific groups from the KGet. 0107 * 0108 * @param groups The names of the groups to be deleted. 0109 * @param askUser Whether to ask user about the deletion 0110 */ 0111 static void delGroups(QList<TransferGroupHandler *> groups, bool askUser = true); 0112 0113 /** 0114 * Changes the name of the group 0115 * 0116 * @param oldName the name of the group to be changed 0117 * @param newName the new name of the group 0118 */ 0119 static void renameGroup(const QString &oldName, const QString &newName); 0120 0121 /** 0122 * @returns the name of the available transfers groups 0123 */ 0124 static QStringList transferGroupNames(); 0125 0126 /** 0127 * Adds a new transfer to the KGet 0128 * 0129 * @param srcUrl The url to be downloaded 0130 * @param destDir The destination directory. If empty we show a dialog 0131 * where the user can choose it. 0132 * @param suggestedFileName a suggestion of a simple filename to be saved in destDir 0133 * @param groupName The name of the group the new transfer will belong to 0134 * @param start Specifies if the newly added transfers should be started. 0135 * If the group queue is already in a running state, this flag does nothing 0136 */ 0137 static TransferHandler * 0138 addTransfer(QUrl srcUrl, QString destDir = QString(), QString suggestedFileName = QString(), QString groupName = QString(), bool start = false); 0139 0140 /** 0141 * Adds new transfers to the KGet, it is assumed that this takes place because of loading 0142 * that results in less checks for location etc. 0143 * 0144 * @param elements The dom elements of the transfers to add 0145 * @param groupName The name of the group the new transfer will belong to 0146 */ 0147 static QList<TransferHandler *> addTransfers(const QList<QDomElement> &elements, const QString &groupName = QString()); 0148 0149 /** 0150 * Adds new transfers to the KGet 0151 * 0152 * @param srcUrls The urls to be downloaded 0153 * @param destDir The destination directory. If empty we show a dialog 0154 * where the user can choose it. 0155 * @param groupName The name of the group the new transfer will belong to 0156 * @param start Specifies if the newly added transfers should be started. 0157 * If the group queue is already in a running state, this flag does nothing 0158 */ 0159 static const QList<TransferHandler *> addTransfer(QList<QUrl> srcUrls, QString destDir = QString(), QString groupName = QString(), bool start = false); 0160 0161 /** 0162 * Removes a transfer from the KGet 0163 * 0164 * @param transfer The transfer to be removed 0165 * @param mode The deletion mode 0166 */ 0167 static bool delTransfer(TransferHandler *transfer, DeleteMode mode = AutoDelete); 0168 0169 /** 0170 * Removes multiple transfers from the KGet 0171 * 0172 * @param transfers The transfers to be removed 0173 * @param mode The deletion mode 0174 */ 0175 static bool delTransfers(const QList<TransferHandler *> &transfers, DeleteMode mode = AutoDelete); 0176 0177 /** 0178 * Moves a transfer to a new group 0179 * 0180 * @param transfer The transfer to be moved 0181 * @param groupName The name of the new transfer's group 0182 */ 0183 static void moveTransfer(TransferHandler *transfer, const QString &groupName); 0184 0185 /** 0186 * Redownload a transfer 0187 * @param transfer the transfer to redownload 0188 */ 0189 static void redownloadTransfer(TransferHandler *transfer); 0190 0191 /** 0192 * @returns the list of selected transfers 0193 */ 0194 static QList<TransferHandler *> selectedTransfers(); 0195 0196 /** 0197 * @returns the list of the finished transfers 0198 */ 0199 static QList<TransferHandler *> finishedTransfers(); 0200 0201 /** 0202 * @returns the list of selected groups 0203 */ 0204 static QList<TransferGroupHandler *> selectedTransferGroups(); 0205 0206 /** 0207 * @returns a pointer to the TransferTreeModel object 0208 */ 0209 static TransferTreeModel *model(); 0210 0211 /** 0212 * @returns a pointer to the QItemSelectionModel object 0213 */ 0214 static TransferTreeSelectionModel *selectionModel(); 0215 0216 /** 0217 * Imports the transfers and groups included in the provided xml file 0218 * 0219 * @param filename the file name to 0220 */ 0221 static void load(QString filename = QString()); 0222 0223 /** 0224 * Exports all the transfers and groups to the given file 0225 * 0226 * @param filename the file name 0227 * @param plain should list be in plain mode or kget mode 0228 */ 0229 static void save(QString filename = QString(), bool plain = false); 0230 0231 /** 0232 * @returns a list of all transferfactories 0233 */ 0234 static QList<TransferFactory *> factories(); 0235 0236 /** 0237 * @returns a list of pluginInfos associated with all transferFactories 0238 */ 0239 static QVector<KPluginMetaData> plugins(); 0240 0241 /** 0242 * @returns The factory of a given transfer 0243 * 0244 * @param transfer the transfer about which we want to have the factory 0245 */ 0246 static TransferFactory *factory(TransferHandler *transfer); 0247 0248 /** 0249 * @return a pointer to the KActionCollection objects 0250 */ 0251 static KActionCollection *actionCollection(); 0252 0253 /** 0254 * if running == true starts the scheduler 0255 * if running == false stops the scheduler 0256 */ 0257 static void setSchedulerRunning(bool running = true); 0258 0259 /** 0260 * Returns true if the scheduler has running jobs. 0261 */ 0262 static bool schedulerRunning(); 0263 0264 /** 0265 * true suspends the scheduler, any events that would result in a reschedule are ignored 0266 * false wakes up the scheduler, events result in reschedule again 0267 * NOTE this is a HACK for cases where the scheduler is the bottleneck, e.g. when stopping 0268 * a lot of running transfers, or starting a lot transfers 0269 */ 0270 static void setSuspendScheduler(bool isSuspended); 0271 0272 /** 0273 * Gets all transfers 0274 */ 0275 static QList<TransferHandler *> allTransfers(); 0276 0277 /** 0278 * Gets all transfer-groups 0279 */ 0280 static QList<TransferGroupHandler *> allTransferGroups(); 0281 0282 /** 0283 * Get the transfer with the given url 0284 * @param src the url 0285 */ 0286 static TransferHandler *findTransfer(const QUrl &src); 0287 0288 /** 0289 * Get the group with the given name 0290 * @param name the name 0291 */ 0292 static TransferGroupHandler *findGroup(const QString &name); 0293 0294 /** 0295 * Run this function for enabling the systemTray 0296 * (will be automatically done, if there is download running) 0297 */ 0298 static void checkSystemTray(); 0299 0300 /** 0301 * This will be called when the settings have been changed 0302 */ 0303 static void settingsChanged(); 0304 0305 /** 0306 * @return a list of the groups assigned to the filename of a transfer 0307 */ 0308 static QList<TransferGroupHandler *> groupsFromExceptions(const QUrl &filename); 0309 0310 /** 0311 * Returns @c true if sourceUrl matches any of the patterns 0312 */ 0313 static bool matchesExceptions(const QUrl &sourceUrl, const QStringList &patterns); 0314 0315 /** 0316 * Scans for all the available plugins and creates the proper 0317 * transfer DataSource object for transfers Containers 0318 * 0319 * @param src Source Url 0320 * @param type the type of the DataSource that should be created e.g. \<TransferDataSource type="search" /\> 0321 * this is only needed when creating a "special" TransferDataSource like the search for Urls 0322 * you can set additional information and the TransferDataSource will use it if it can 0323 * @param parent the parent QObject 0324 */ 0325 static TransferDataSource *createTransferDataSource(const QUrl &src, const QDomElement &type = QDomElement(), QObject *parent = nullptr); 0326 0327 /** 0328 * Sets the global download limit 0329 * @param limit the new global download limit 0330 */ 0331 static void setGlobalDownloadLimit(int limit); 0332 0333 /** 0334 * Sets the global upload limit 0335 * @param limit the new global upload limit 0336 */ 0337 static void setGlobalUploadLimit(int limit); 0338 0339 /** 0340 * Recalculates the global speedlimits 0341 */ 0342 static void calculateGlobalSpeedLimits(); 0343 0344 /** 0345 * Recalculates the global download-limit 0346 */ 0347 static void calculateGlobalDownloadLimit(); 0348 0349 /** 0350 * Recalculates the global upload-limit 0351 */ 0352 static void calculateGlobalUploadLimit(); 0353 0354 /** 0355 * Shows a knotification 0356 * @param parent QWidget parent of the notification 0357 * @param eventType Notification type 0358 * @param text Description of the information showed by the notification 0359 * @param icon Pixmap showed in the notification, by default 'dialog-error' 0360 * @param title Notification window title 0361 * @param flags Notification flags 0362 */ 0363 static KNotification *showNotification(QWidget *parent, 0364 const QString &eventType, 0365 const QString &text, 0366 const QString &icon = QString("dialog-error"), 0367 const QString &title = i18n("KGet"), 0368 const KNotification::NotificationFlags &flags = KNotification::CloseOnTimeout); 0369 0370 static void loadPlugins(); 0371 0372 /** 0373 * Returns a download directory 0374 * @param preferXDGDownloadDir if true the XDG_DOWNLOAD_DIR will be taken if it is not empty 0375 * @note depending if the directories exist it will return them in the following order: 0376 * (preferXDGDownloadDirectory >) lastDirectory > XDG_DOWNLOAD_DIR 0377 */ 0378 static QString generalDestDir(bool preferXDGDownloadDir = false); 0379 0380 private: 0381 KGet(); 0382 0383 class TransferData; 0384 0385 /** 0386 * Scans for all the available plugins and creates the proper 0387 * transfer object for the given src url 0388 * 0389 * @param src the source url 0390 * @param dest the destination url 0391 * @param groupName the group name 0392 * @param start Specifies if the newly added transfers should be started. 0393 */ 0394 static TransferHandler * 0395 createTransfer(const QUrl &src, const QUrl &dest, const QString &groupName = QString(), bool start = false, const QDomElement *e = nullptr); 0396 0397 /** 0398 * Creates multiple transfers with transferData 0399 */ 0400 static QList<TransferHandler *> createTransfers(const QList<TransferData> &transferData); 0401 0402 static QUrl urlInputDialog(); 0403 static QString destDirInputDialog(); 0404 static QUrl destFileInputDialog(QString destDir = QString(), const QString &suggestedFileName = QString()); 0405 0406 static bool isValidSource(const QUrl &source); 0407 static bool isValidDestDirectory(const QString &destDir); 0408 0409 static QUrl getValidDestUrl(const QUrl &destDir, const QUrl &srcUrl); 0410 0411 // Plugin-related functions 0412 static KGetPlugin *loadPlugin(const KPluginMetaData &md); 0413 0414 /** 0415 * Stops all downloads if there is no connection and also displays 0416 * a message. 0417 * If there is a connection, then the downloads will be started again 0418 */ 0419 static void setHasNetworkConnection(bool hasConnection); 0420 0421 /** 0422 * Deletes the given file, if possible. 0423 * 0424 * @param url The file to delete 0425 * 0426 * @return true if the file was successfully deleted: if the given url 0427 * is a directory or if it is not local it returns false and shows a 0428 * warning message. 0429 */ 0430 static bool safeDeleteFile(const QUrl &url); 0431 0432 // Interview models 0433 static TransferTreeModel *m_transferTreeModel; 0434 static TransferTreeSelectionModel *m_selectionModel; 0435 0436 // Lists of available plugins 0437 static QVector<KPluginMetaData> m_pluginList; 0438 static QList<TransferFactory *> m_transferFactories; 0439 0440 // pointer to the Main window 0441 static MainWindow *m_mainWindow; 0442 0443 // Scheduler object 0444 static TransferGroupScheduler *m_scheduler; 0445 0446 // pointer to the kget uiserver jobs manager 0447 static KUiServerJobs *m_jobManager; 0448 0449 // pointer to the used TransferHistoryStore 0450 static TransferHistoryStore *m_store; 0451 0452 static bool m_hasConnection; 0453 }; 0454 0455 class KGET_EXPORT KGet::TransferData 0456 { 0457 public: 0458 TransferData(const QUrl &src, const QUrl &dest, const QString &groupName = QString(), bool start = false, const QDomElement *e = nullptr); 0459 0460 QUrl src; 0461 QUrl dest; 0462 QString groupName; 0463 bool start; 0464 const QDomElement *e; 0465 }; 0466 0467 class GenericObserver : public QObject 0468 { 0469 Q_OBJECT 0470 public: 0471 explicit GenericObserver(QObject *parent = nullptr); 0472 ~GenericObserver() override; 0473 0474 public Q_SLOTS: 0475 void groupAddedEvent(TransferGroupHandler *handler); 0476 void groupRemovedEvent(TransferGroupHandler *handler); 0477 void transfersAddedEvent(const QList<TransferHandler *> &handlers); 0478 void transfersRemovedEvent(const QList<TransferHandler *> &handlers); 0479 void transfersChangedEvent(QMap<TransferHandler *, Transfer::ChangesFlags> transfers); 0480 void groupsChangedEvent(QMap<TransferGroupHandler *, TransferGroup::ChangesFlags> groups); 0481 void transferMovedEvent(TransferHandler *, TransferGroupHandler *); 0482 0483 private Q_SLOTS: 0484 void slotSave(); 0485 void slotAfterFinishAction(); 0486 void slotAbortAfterFinishAction(); 0487 void slotResolveTransferError(); 0488 void slotNotificationClosed(); 0489 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0490 void slotNetworkStatusChanged(bool online); 0491 #else 0492 void slotNetworkStatusChanged(QNetworkInformation::Reachability reachability); 0493 #endif 0494 0495 private: 0496 bool allTransfersFinished(); 0497 0498 void requestSave(); 0499 0500 private: 0501 QTimer *m_save; 0502 QTimer *m_finishAction; 0503 QHash<KNotification *, TransferHandler *> m_notifications; 0504 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0505 // Silence deprecation warnings as there is no Qt 5 substitute for QNetworkConfigurationManager 0506 QT_WARNING_PUSH 0507 QT_WARNING_DISABLE_CLANG("-Wdeprecated-declarations") 0508 QT_WARNING_DISABLE_GCC("-Wdeprecated-declarations") 0509 QNetworkConfigurationManager m_networkConfig; 0510 QT_WARNING_POP 0511 #endif 0512 }; 0513 #endif