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