Browse Source

version 0.0.2 updated according qbittorent 3.2.0 code

Frédéric Logier 3 years ago
parent
commit
ef28c32d34
65 changed files with 10281 additions and 6304 deletions
  1. 6
    3
      src/account.cpp
  2. 0
    1
      src/account.h
  3. 121
    0
      src/autoexpandabledialog.cpp
  4. 60
    0
      src/autoexpandabledialog.h
  5. 120
    0
      src/autoexpandabledialog.ui
  6. 4
    3
      src/deletionconfirmationdlg.h
  7. 10
    11
      src/downloadthread.cpp
  8. 110
    0
      src/executionlog.cpp
  9. 69
    0
      src/executionlog.h
  10. 43
    0
      src/executionlog.ui
  11. 24
    13
      src/fs_utils.cpp
  12. 3
    0
      src/fs_utils.h
  13. 12
    7
      src/iconprovider.cpp
  14. 137
    0
      src/libs/qtlibtorrent/alertdispatcher.cpp
  15. 80
    0
      src/libs/qtlibtorrent/alertdispatcher.h
  16. 7
    7
      src/libs/qtlibtorrent/bandwidthscheduler.h
  17. 1037
    1085
      src/libs/qtlibtorrent/qbtsession.cpp
  18. 86
    24
      src/libs/qtlibtorrent/qbtsession.h
  19. 6
    2
      src/libs/qtlibtorrent/qtlibtorrent.pri
  20. 620
    611
      src/libs/qtlibtorrent/qtorrenthandle.cpp
  21. 118
    98
      src/libs/qtlibtorrent/qtorrenthandle.h
  22. 561
    361
      src/libs/qtlibtorrent/torrentmodel.cpp
  23. 62
    54
      src/libs/qtlibtorrent/torrentmodel.h
  24. 113
    176
      src/libs/qtlibtorrent/torrentspeedmonitor.cpp
  25. 12
    32
      src/libs/qtlibtorrent/torrentspeedmonitor.h
  26. 100
    0
      src/libs/qtlibtorrent/torrentstatistics.cpp
  27. 41
    0
      src/libs/qtlibtorrent/torrentstatistics.h
  28. 2
    1
      src/libs/tracker/qtracker.cpp
  29. 127
    0
      src/logger.cpp
  30. 83
    0
      src/logger.h
  31. 96
    0
      src/loglistwidget.cpp
  32. 61
    0
      src/loglistwidget.h
  33. 48
    96
      src/mainwindow.cpp
  34. 7
    5
      src/mainwindow.h
  35. 6
    0
      src/mainwindow.ui
  36. 53
    53
      src/preferences/advancedsettings.h
  37. 185
    215
      src/preferences/options_imp.cpp
  38. 2526
    0
      src/preferences/preferences.cpp
  39. 550
    1536
      src/preferences/preferences.h
  40. 4
    2
      src/preferences/preferences.pri
  41. 1
    1
      src/preferences/qinisettings.h
  42. 8
    9
      src/programupdater.cpp
  43. 2
    2
      src/room.cpp
  44. 3
    3
      src/scannedfoldersmodel.cpp
  45. 16
    11
      src/sphere.cpp
  46. 0
    1
      src/sphere.h
  47. 16
    4
      src/src.pro
  48. 4
    4
      src/stacktrace_win_dlg.h
  49. 4
    2
      src/torrentcreator/torrentcreatordlg.cpp
  50. 0
    1
      src/torrentcreator/torrentcreatordlg.h
  51. 13
    2
      src/torrentfilterenum.h
  52. 527
    0
      src/torrentpersistentdata.cpp
  53. 128
    475
      src/torrentpersistentdata.h
  54. 835
    0
      src/transferlistfilterswidget.cpp
  55. 129
    441
      src/transferlistfilterswidget.h
  56. 359
    0
      src/transferlistsortmodel.cpp
  57. 29
    139
      src/transferlistsortmodel.h
  58. 835
    769
      src/transferlistwidget.cpp
  59. 9
    2
      src/transferlistwidget.h
  60. 15
    10
      src/widgettorrent.cpp
  61. 9
    8
      src/xmpp/xmpp_client.cpp
  62. 0
    1
      src/xmpp/xmpp_client.h
  63. 2
    2
      version.pri
  64. 9
    6
      winconf-msvc.pri
  65. 18
    15
      winconf.pri

+ 6
- 3
src/account.cpp View File

@@ -37,7 +37,9 @@ account::account(QWidget *parent) :
37 37
 {
38 38
     ui->setupUi(this);
39 39
     QHash<QString, QString> account;
40
-    account = pref.getNodecastAccount();
40
+    const Preferences* const pref = Preferences::instance();
41
+
42
+    account = pref->getNodecastAccount();
41 43
 
42 44
     ui->lineEdit_login->setText(account.value("login") );
43 45
     ui->lineEdit_password->setText(account.value("password"));
@@ -55,14 +57,15 @@ account::~account()
55 57
 void account::on_buttonBox_accepted()
56 58
 {
57 59
     QHash<QString, QString> hash;
60
+    Preferences* const pref = Preferences::instance();
58 61
 
59 62
 
60 63
     hash["login"] = ui->lineEdit_login->text();
61 64
     hash["password"]  = ui->lineEdit_password->text();
62 65
     hash["nickname"]  = ui->lineEdit_nickname->text();
63 66
 
64
-    pref.setNodecastAccount(hash);
65
-    pref.sync();
67
+    pref->setNodecastAccount(hash);
68
+    pref->save();
66 69
 
67 70
     qDebug() << "ACCOUNT : " << hash;
68 71
 

+ 0
- 1
src/account.h View File

@@ -54,7 +54,6 @@ private slots:
54 54
     void receive_tchat(QString message);
55 55
 
56 56
 private:
57
-    Preferences pref;
58 57
     Ui::account *ui;
59 58
 };
60 59
 

+ 121
- 0
src/autoexpandabledialog.cpp View File

@@ -0,0 +1,121 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2013  Nick Tiskov
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : daymansmail@gmail.com
29
+ */
30
+
31
+#include <QDesktopWidget>
32
+
33
+#include "mainwindow.h"
34
+#include "autoexpandabledialog.h"
35
+#include "ui_autoexpandabledialog.h"
36
+
37
+AutoExpandableDialog::AutoExpandableDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AutoExpandableDialog) {
38
+  ui->setupUi(this);
39
+}
40
+
41
+AutoExpandableDialog::~AutoExpandableDialog() {
42
+  delete ui;
43
+}
44
+
45
+QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, const QString &label,
46
+                                      QLineEdit::EchoMode mode, const QString &text, bool *ok,
47
+                                      Qt::InputMethodHints inputMethodHints) {
48
+
49
+  AutoExpandableDialog d(parent);
50
+  d.setWindowTitle(title);
51
+  d.ui->textLabel->setText(label);
52
+  d.ui->textEdit->setText(text);
53
+  d.ui->textEdit->setEchoMode(mode);
54
+  d.ui->textEdit->setInputMethodHints(inputMethodHints);
55
+
56
+  bool res = d.exec();
57
+  if (ok)
58
+    *ok = res;
59
+
60
+  if (!res)
61
+    return QString();
62
+
63
+  return d.ui->textEdit->text();
64
+}
65
+
66
+void AutoExpandableDialog::showEvent(QShowEvent *e) {
67
+  // Overriding showEvent is required for consistent UI with fixed size under custom DPI
68
+  // Show dialog
69
+  QDialog::showEvent(e);
70
+  // and resize textbox to fit the text
71
+
72
+  // NOTE: For some strange reason QFontMetrics gets more accurate
73
+  // when called from showEvent. Only 6 symbols off instead of 11 symbols off.
74
+  int textW = ui->textEdit->fontMetrics().width(ui->textEdit->text()) + 4;
75
+  int screenW = QApplication::desktop()->width() / 4;
76
+  int wd = textW;
77
+
78
+  if (!windowTitle().isEmpty()) {
79
+    int _w = fontMetrics().width(windowTitle());
80
+    if (_w > wd)
81
+      wd = _w;
82
+  }
83
+
84
+  if (!ui->textLabel->text().isEmpty()) {
85
+    int _w = ui->textLabel->fontMetrics().width(ui->textLabel->text());
86
+    if (_w > wd)
87
+      wd = _w;
88
+  }
89
+
90
+
91
+  // Now resize the dialog to fit the contents
92
+  // Maximum value is whichever is smaller:
93
+  // 1. screen width / 4
94
+  // 2. max width of text from either of: label, title, textedit
95
+  // If the value is less than dialog default size default size is used
96
+  wd = textW < screenW ? textW : screenW;
97
+  if (wd > width())
98
+    resize(width() - ui->horizontalLayout->sizeHint().width() + wd, height());
99
+
100
+  // Use old dialog behavior: prohibit resizing the dialog
101
+  setFixedHeight(height());
102
+
103
+  // Update geometry: center on screen
104
+  QDesktopWidget *desk = QApplication::desktop();
105
+  MainWindow *wnd = qobject_cast<MainWindow*>(QApplication::activeWindow());
106
+  QPoint p = QCursor::pos();
107
+
108
+  int screenNum = 0;
109
+  if (wnd == 0)
110
+    screenNum = desk->screenNumber(p);
111
+  else if (!wnd->isHidden())
112
+    screenNum = desk->screenNumber(wnd);
113
+  else
114
+    screenNum = desk->screenNumber(p);
115
+
116
+  QRect screenRes = desk->screenGeometry(screenNum);
117
+
118
+  QRect geom = geometry();
119
+  geom.moveCenter(QPoint(screenRes.width() / 2, screenRes.height() / 2));
120
+  setGeometry(geom);
121
+}

+ 60
- 0
src/autoexpandabledialog.h View File

@@ -0,0 +1,60 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2013  Nick Tiskov
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : daymansmail@gmail.com
29
+ */
30
+
31
+#ifndef AUTOEXPANDABLEDIALOG_H
32
+#define AUTOEXPANDABLEDIALOG_H
33
+
34
+#include <QDialog>
35
+#include <QString>
36
+#include <QLineEdit>
37
+
38
+namespace Ui {
39
+class AutoExpandableDialog;
40
+}
41
+
42
+class AutoExpandableDialog : public QDialog {
43
+  Q_OBJECT
44
+  
45
+public:
46
+  explicit AutoExpandableDialog(QWidget *parent = 0);
47
+  ~AutoExpandableDialog();
48
+
49
+  static QString getText(QWidget *parent, const QString& title,  const QString& label,
50
+                         QLineEdit::EchoMode mode = QLineEdit::Normal, const QString & text = QString(),
51
+                         bool * ok = 0, Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
52
+
53
+protected:
54
+  void showEvent(QShowEvent *e);
55
+  
56
+private:
57
+  Ui::AutoExpandableDialog *ui;
58
+};
59
+
60
+#endif // AUTOEXPANDABLEDIALOG_H

+ 120
- 0
src/autoexpandabledialog.ui View File

@@ -0,0 +1,120 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<ui version="4.0">
3
+ <class>AutoExpandableDialog</class>
4
+ <widget class="QDialog" name="AutoExpandableDialog">
5
+  <property name="geometry">
6
+   <rect>
7
+    <x>0</x>
8
+    <y>0</y>
9
+    <width>222</width>
10
+    <height>94</height>
11
+   </rect>
12
+  </property>
13
+  <property name="sizePolicy">
14
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
15
+    <horstretch>0</horstretch>
16
+    <verstretch>0</verstretch>
17
+   </sizepolicy>
18
+  </property>
19
+  <property name="windowTitle">
20
+   <string notr="true">Dialog</string>
21
+  </property>
22
+  <layout class="QVBoxLayout" name="verticalLayout">
23
+   <item>
24
+    <spacer name="verticalSpacer">
25
+     <property name="orientation">
26
+      <enum>Qt::Vertical</enum>
27
+     </property>
28
+     <property name="sizeHint" stdset="0">
29
+      <size>
30
+       <width>20</width>
31
+       <height>40</height>
32
+      </size>
33
+     </property>
34
+    </spacer>
35
+   </item>
36
+   <item>
37
+    <widget class="QLabel" name="textLabel">
38
+     <property name="toolTip">
39
+      <string notr="true"/>
40
+     </property>
41
+     <property name="text">
42
+      <string notr="true"/>
43
+     </property>
44
+    </widget>
45
+   </item>
46
+   <item>
47
+    <widget class="QLineEdit" name="textEdit">
48
+     <property name="toolTip">
49
+      <string notr="true"/>
50
+     </property>
51
+     <property name="text">
52
+      <string notr="true"/>
53
+     </property>
54
+    </widget>
55
+   </item>
56
+   <item>
57
+    <layout class="QHBoxLayout" name="horizontalLayout">
58
+     <item>
59
+      <spacer name="horizontalSpacer">
60
+       <property name="orientation">
61
+        <enum>Qt::Horizontal</enum>
62
+       </property>
63
+       <property name="sizeHint" stdset="0">
64
+        <size>
65
+         <width>40</width>
66
+         <height>20</height>
67
+        </size>
68
+       </property>
69
+      </spacer>
70
+     </item>
71
+     <item>
72
+      <widget class="QDialogButtonBox" name="buttonBox">
73
+       <property name="orientation">
74
+        <enum>Qt::Horizontal</enum>
75
+       </property>
76
+       <property name="standardButtons">
77
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
78
+       </property>
79
+      </widget>
80
+     </item>
81
+    </layout>
82
+   </item>
83
+  </layout>
84
+ </widget>
85
+ <resources/>
86
+ <connections>
87
+  <connection>
88
+   <sender>buttonBox</sender>
89
+   <signal>accepted()</signal>
90
+   <receiver>AutoExpandableDialog</receiver>
91
+   <slot>accept()</slot>
92
+   <hints>
93
+    <hint type="sourcelabel">
94
+     <x>248</x>
95
+     <y>254</y>
96
+    </hint>
97
+    <hint type="destinationlabel">
98
+     <x>157</x>
99
+     <y>274</y>
100
+    </hint>
101
+   </hints>
102
+  </connection>
103
+  <connection>
104
+   <sender>buttonBox</sender>
105
+   <signal>rejected()</signal>
106
+   <receiver>AutoExpandableDialog</receiver>
107
+   <slot>reject()</slot>
108
+   <hints>
109
+    <hint type="sourcelabel">
110
+     <x>316</x>
111
+     <y>260</y>
112
+    </hint>
113
+    <hint type="destinationlabel">
114
+     <x>286</x>
115
+     <y>274</y>
116
+    </hint>
117
+   </hints>
118
+  </connection>
119
+ </connections>
120
+</ui>

+ 4
- 3
src/deletionconfirmationdlg.h View File

@@ -35,6 +35,7 @@
35 35
 #include "ui_confirmdeletiondlg.h"
36 36
 #include "preferences.h"
37 37
 #include "iconprovider.h"
38
+#include "misc.h"
38 39
 
39 40
 class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg {
40 41
   Q_OBJECT
@@ -52,7 +53,7 @@ class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg {
52 53
     rememberBtn->setIcon(IconProvider::instance()->getIcon("object-locked"));
53 54
 
54 55
     move(misc::screenCenter(this));
55
-    checkPermDelete->setChecked(Preferences().deleteTorrentFilesAsDefault());
56
+    checkPermDelete->setChecked(Preferences::instance()->deleteTorrentFilesAsDefault());
56 57
     connect(checkPermDelete, SIGNAL(clicked()), this, SLOT(updateRememberButtonState()));
57 58
     buttonBox->setFocus();
58 59
   }
@@ -72,11 +73,11 @@ class DeletionConfirmationDlg : public QDialog, private Ui::confirmDeletionDlg {
72 73
 
73 74
 private slots:
74 75
   void updateRememberButtonState() {
75
-    rememberBtn->setEnabled(checkPermDelete->isChecked() != Preferences().deleteTorrentFilesAsDefault());
76
+    rememberBtn->setEnabled(checkPermDelete->isChecked() != Preferences::instance()->deleteTorrentFilesAsDefault());
76 77
   }
77 78
 
78 79
   void on_rememberBtn_clicked() {
79
-    Preferences().setDeleteTorrentFilesAsDefault(checkPermDelete->isChecked());
80
+    Preferences::instance()->setDeleteTorrentFilesAsDefault(checkPermDelete->isChecked());
80 81
     rememberBtn->setEnabled(false);
81 82
   }
82 83
 };

+ 10
- 11
src/downloadthread.cpp View File

@@ -33,13 +33,12 @@
33 33
 #include <QNetworkRequest>
34 34
 #include <QNetworkProxy>
35 35
 #include <QNetworkCookieJar>
36
+#include <QDebug>
36 37
 
37 38
 #include "downloadthread.h"
38 39
 #include "preferences.h"
39
-#ifndef DISABLE_GUI
40
-//#include "rsssettings.h"
41
-#endif
42 40
 #include "qinisettings.h"
41
+#include "fs_utils.h"
43 42
 #include <zlib.h>
44 43
 
45 44
 /** Download Thread **/
@@ -229,13 +228,13 @@ void DownloadThread::checkDownloadSize(qint64 bytesReceived, qint64 bytesTotal)
229 228
 
230 229
 void DownloadThread::applyProxySettings() {
231 230
   QNetworkProxy proxy;
232
-  const Preferences pref;
233
-  if (pref.isProxyEnabled()) {
231
+  const Preferences* const pref = Preferences::instance();
232
+  if (pref->isProxyEnabled()) {
234 233
     // Proxy enabled
235
-    proxy.setHostName(pref.getProxyIp());
236
-    proxy.setPort(pref.getProxyPort());
234
+    proxy.setHostName(pref->getProxyIp());
235
+    proxy.setPort(pref->getProxyPort());
237 236
     // Default proxy type is HTTP, we must change if it is SOCKS5
238
-    const int proxy_type = pref.getProxyType();
237
+    const int proxy_type = pref->getProxyType();
239 238
     if (proxy_type == Proxy::SOCKS5 || proxy_type == Proxy::SOCKS5_PW) {
240 239
       qDebug() << Q_FUNC_INFO << "using SOCKS proxy";
241 240
       proxy.setType(QNetworkProxy::Socks5Proxy);
@@ -244,10 +243,10 @@ void DownloadThread::applyProxySettings() {
244 243
       proxy.setType(QNetworkProxy::HttpProxy);
245 244
     }
246 245
     // Authentication?
247
-    if (pref.isProxyAuthEnabled()) {
246
+    if (pref->isProxyAuthEnabled()) {
248 247
       qDebug("Proxy requires authentication, authenticating");
249
-      proxy.setUser(pref.getProxyUsername());
250
-      proxy.setPassword(pref.getProxyPassword());
248
+      proxy.setUser(pref->getProxyUsername());
249
+      proxy.setPassword(pref->getProxyPassword());
251 250
     }
252 251
   } else {
253 252
     proxy.setType(QNetworkProxy::NoProxy);

+ 110
- 0
src/executionlog.cpp View File

@@ -0,0 +1,110 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2011  Christophe Dumez
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : chris@qbittorrent.org
29
+ */
30
+
31
+#include <QListWidgetItem>
32
+#include <QLabel>
33
+#include <QDateTime>
34
+#include <QColor>
35
+#include <QPalette>
36
+#include "executionlog.h"
37
+#include "ui_executionlog.h"
38
+#include "logger.h"
39
+#include "iconprovider.h"
40
+#include "loglistwidget.h"
41
+
42
+ExecutionLog::ExecutionLog(QWidget *parent)
43
+    : QWidget(parent)
44
+    , ui(new Ui::ExecutionLog)
45
+    , m_msgList(new LogListWidget(MAX_LOG_MESSAGES))
46
+    , m_peerList(new LogListWidget(MAX_LOG_MESSAGES))
47
+{
48
+    ui->setupUi(this);
49
+
50
+    ui->tabConsole->setTabIcon(0, IconProvider::instance()->getIcon("view-calendar-journal"));
51
+    ui->tabConsole->setTabIcon(1, IconProvider::instance()->getIcon("view-filter"));
52
+    ui->tabGeneral->layout()->addWidget(m_msgList);
53
+    ui->tabBan->layout()->addWidget(m_peerList);
54
+
55
+    const Logger* const logger = Logger::instance();
56
+    foreach (const Log::Msg& msg, logger->getMessages())
57
+        addLogMessage(msg);
58
+    foreach (const Log::Peer& peer, logger->getPeers())
59
+        addPeerMessage(peer);
60
+    connect(logger, SIGNAL(newLogMessage(const Log::Msg &)), SLOT(addLogMessage(const Log::Msg &)));
61
+    connect(logger, SIGNAL(newLogPeer(const Log::Peer &)), SLOT(addPeerMessage(const Log::Peer &)));
62
+}
63
+
64
+ExecutionLog::~ExecutionLog()
65
+{
66
+    delete m_msgList;
67
+    delete m_peerList;
68
+    delete ui;
69
+}
70
+
71
+void ExecutionLog::addLogMessage(const Log::Msg &msg)
72
+{
73
+    QString text;
74
+    QDateTime time = QDateTime::fromMSecsSinceEpoch(msg.timestamp);
75
+    QColor color;
76
+
77
+    switch (msg.type) {
78
+    case Log::INFO:
79
+        color.setNamedColor("blue");
80
+        break;
81
+    case Log::WARNING:
82
+        color.setNamedColor("orange");
83
+        break;
84
+    case Log::CRITICAL:
85
+        color.setNamedColor("red");
86
+        break;
87
+    default:
88
+        color = QApplication::palette().color(QPalette::WindowText);
89
+    }
90
+
91
+    text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - <font color='" + color.name() + "'>" + msg.message + "</font>";
92
+    m_msgList->appendLine(text);
93
+}
94
+
95
+void ExecutionLog::addPeerMessage(const Log::Peer& peer)
96
+{
97
+    QString text;
98
+    QDateTime time = QDateTime::fromMSecsSinceEpoch(peer.timestamp);
99
+
100
+    if (peer.blocked)
101
+#if LIBTORRENT_VERSION_NUM < 10000
102
+        text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - " + tr("<font color='red'>%1</font> was blocked", "x.y.z.w was blocked").arg(peer.ip);
103
+#else
104
+        text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - " + tr("<font color='red'>%1</font> was blocked %2", "x.y.z.w was blocked").arg(peer.ip).arg(peer.reason);
105
+#endif
106
+    else
107
+        text = "<font color='grey'>" + time.toString(Qt::SystemLocaleShortDate) + "</font> - " + tr("<font color='red'>%1</font> was banned", "x.y.z.w was banned").arg(peer.ip);
108
+
109
+    m_peerList->appendLine(text);
110
+}

+ 69
- 0
src/executionlog.h View File

@@ -0,0 +1,69 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2011  Christophe Dumez
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : chris@qbittorrent.org
29
+ */
30
+
31
+#ifndef EXECUTIONLOG_H
32
+#define EXECUTIONLOG_H
33
+
34
+#include <QWidget>
35
+
36
+QT_BEGIN_NAMESPACE
37
+namespace Ui {
38
+    class ExecutionLog;
39
+}
40
+QT_END_NAMESPACE
41
+class Logger;
42
+class LogListWidget;
43
+
44
+namespace Log
45
+{
46
+    struct Msg;
47
+    struct Peer;
48
+}
49
+
50
+class ExecutionLog: public QWidget
51
+{
52
+    Q_OBJECT
53
+
54
+public:
55
+    explicit ExecutionLog(QWidget *parent = 0);
56
+    ~ExecutionLog();
57
+
58
+private slots:
59
+    void addLogMessage(const Log::Msg &msg);
60
+    void addPeerMessage(const Log::Peer &peer);
61
+
62
+private:
63
+    Ui::ExecutionLog *ui;
64
+
65
+    LogListWidget *m_msgList;
66
+    LogListWidget *m_peerList;
67
+};
68
+
69
+#endif // EXECUTIONLOG_H

+ 43
- 0
src/executionlog.ui View File

@@ -0,0 +1,43 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<ui version="4.0">
3
+ <class>ExecutionLog</class>
4
+ <widget class="QWidget" name="ExecutionLog">
5
+  <property name="geometry">
6
+   <rect>
7
+    <x>0</x>
8
+    <y>0</y>
9
+    <width>400</width>
10
+    <height>300</height>
11
+   </rect>
12
+  </property>
13
+  <property name="windowTitle">
14
+   <string notr="true">Form</string>
15
+  </property>
16
+  <layout class="QVBoxLayout" name="verticalLayout">
17
+   <item>
18
+    <widget class="QTabWidget" name="tabConsole">
19
+     <property name="tabPosition">
20
+      <enum>QTabWidget::East</enum>
21
+     </property>
22
+     <property name="currentIndex">
23
+      <number>0</number>
24
+     </property>
25
+     <widget class="QWidget" name="tabGeneral">
26
+      <attribute name="title">
27
+       <string>General</string>
28
+      </attribute>
29
+      <layout class="QVBoxLayout"/>
30
+     </widget>
31
+     <widget class="QWidget" name="tabBan">
32
+      <attribute name="title">
33
+       <string>Blocked IPs</string>
34
+      </attribute>
35
+      <layout class="QVBoxLayout" name="_2"/>
36
+     </widget>
37
+    </widget>
38
+   </item>
39
+  </layout>
40
+ </widget>
41
+ <resources/>
42
+ <connections/>
43
+</ui>

+ 24
- 13
src/fs_utils.cpp View File

@@ -79,6 +79,14 @@ using namespace libtorrent;
79 79
  * This function makes sure the directory separator used is consistent
80 80
  * with the OS being run.
81 81
  */
82
+QString fsutils::toNativePath(const QString& path) {
83
+  return QDir::toNativeSeparators(path);
84
+}
85
+
86
+QString fsutils::fromNativePath(const QString &path) {
87
+  return QDir::fromNativeSeparators(path);
88
+}
89
+
82 90
 QString fsutils::toDisplayPath(const QString& path)
83 91
 {
84 92
   return QDir::toNativeSeparators(path);
@@ -350,21 +358,24 @@ bool fsutils::sameFileNames(const QString &first, const QString &second)
350 358
 #endif
351 359
 }
352 360
 
353
-// Replace ~ in path
354
-QString fsutils::expandPath(const QString& path) {
355
-  QString ret = path.trimmed();
356
-  if (ret.isEmpty()) return ret;
357
-  if (ret == "~")
358
-    return QDir::homePath();
359
-  if (ret[0] == '~' && (ret[1] == '/' || ret[1] == '\\')) {
360
-    ret.replace(0, 1, QDir::homePath());
361
-  } else {
362
-    if (!QDir::isAbsolutePath(ret))
363
-      ret = QDir(ret).absolutePath();
364
-  }
365
-  return QDir::cleanPath(path);
361
+QString fsutils::expandPath(const QString &path) {
362
+  QString ret = fsutils::fromNativePath(path.trimmed());
363
+  if (ret.isEmpty())
364
+    return ret;
365
+
366
+  return QDir::cleanPath(ret);
366 367
 }
367 368
 
369
+QString fsutils::expandPathAbs(const QString& path) {
370
+  QString ret = fsutils::expandPath(path);
371
+
372
+  if (!QDir::isAbsolutePath(ret))
373
+    ret = QDir(ret).absolutePath();
374
+
375
+  return ret;
376
+}
377
+
378
+
368 379
 bool fsutils::createLink(const QString& filename_source, const QString& filename_target) {
369 380
   qDebug() << "CREATE LINK source : " << filename_source << " TARGET : " << filename_target;
370 381
   QFile f(filename_source);

+ 3
- 0
src/fs_utils.h View File

@@ -43,6 +43,8 @@ class fsutils
43 43
   Q_DECLARE_TR_FUNCTIONS(fsutils)
44 44
 
45 45
 public:
46
+static QString toNativePath(const QString& path);
47
+static QString fromNativePath(const QString& path);
46 48
 static QString toDisplayPath(const QString& path);
47 49
 static QString fileExtension(const QString& filename);
48 50
 static QString fileName(const QString& file_path);
@@ -55,6 +57,7 @@ static long long freeDiskSpaceOnPath(QString path);
55 57
 static QString branchPath(const QString& file_path, QString* removed = 0);
56 58
 static bool sameFileNames(const QString& first, const QString& second);
57 59
 static QString expandPath(const QString& path);
60
+static QString expandPathAbs(const QString& path);
58 61
 static bool isValidTorrentFile(const QString& path);
59 62
 static bool smartRemoveEmptyFolderTree(const QString& dir_path);
60 63
 static bool forceRemove(const QString& file_path);

+ 12
- 7
src/iconprovider.cpp View File

@@ -31,12 +31,17 @@
31 31
 #include "iconprovider.h"
32 32
 #include "preferences.h"
33 33
 
34
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
35
+#include <QDir>
36
+#include <QFile>
37
+#endif
38
+
34 39
 IconProvider* IconProvider::m_instance = 0;
35 40
 
36 41
 IconProvider::IconProvider()
37 42
 {
38
-#if defined(Q_WS_X11)
39
-  m_useSystemTheme = Preferences().useSystemIconTheme();
43
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
44
+  m_useSystemTheme = Preferences::instance()->useSystemIconTheme();
40 45
 #endif
41 46
 }
42 47
 
@@ -57,9 +62,9 @@ void IconProvider::drop()
57 62
 
58 63
 QIcon IconProvider::getIcon(const QString &iconId)
59 64
 {
60
-#if defined(Q_WS_X11)
65
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
61 66
   if (m_useSystemTheme) {
62
-    QIcon icon = QIcon::fromTheme(iconId, QIcon(":/Icons/oxygen/"+iconId+".png"));
67
+    QIcon icon = QIcon::fromTheme(iconId, QIcon(":/icons/oxygen/"+iconId+".png"));
63 68
     icon = generateDifferentSizes(icon);
64 69
     return icon;
65 70
   }
@@ -67,7 +72,7 @@ QIcon IconProvider::getIcon(const QString &iconId)
67 72
   return QIcon(":/Icons/oxygen/"+iconId+".png");
68 73
 }
69 74
 
70
-#if defined(Q_WS_X11)
75
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
71 76
 void IconProvider::useSystemIconTheme(bool enable)
72 77
 {
73 78
   m_useSystemTheme = enable;
@@ -102,12 +107,12 @@ QIcon IconProvider::generateDifferentSizes(const QIcon& icon)
102 107
 
103 108
 QString IconProvider::getIconPath(const QString& iconId)
104 109
 {
105
-#if defined(Q_WS_X11)
110
+#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
106 111
   if (m_useSystemTheme) {
107 112
     QString path = QDir::temp().absoluteFilePath(iconId+".png");
108 113
     if (!QFile::exists(path)) {
109 114
       const QIcon icon = QIcon::fromTheme(iconId);
110
-      if (icon.isNull()) return ":/Icons/oxygen/"+iconId+".png";
115
+      if (icon.isNull()) return ":/icons/oxygen/"+iconId+".png";
111 116
       QPixmap px = icon.pixmap(32);
112 117
       px.save(path);
113 118
     }

+ 137
- 0
src/libs/qtlibtorrent/alertdispatcher.cpp View File

@@ -0,0 +1,137 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2014  Ivan Sorokin
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : vanyacpp@gmail.com
29
+ */
30
+
31
+#include "alertdispatcher.h"
32
+// workaround to fix this issue https://github.com/qbittorrent/qBittorrent/issues/3056
33
+#define BOOST_NO_CXX11_RVALUE_REFERENCES
34
+
35
+#include <libtorrent/session.hpp>
36
+#include <boost/bind.hpp>
37
+#include <QMutexLocker>
38
+
39
+const size_t DEFAULT_ALERTS_CAPACITY = 32;
40
+
41
+struct QAlertDispatcher::Tag {
42
+    Tag(QAlertDispatcher* dispatcher);
43
+
44
+    QAlertDispatcher* dispatcher;
45
+    QMutex alerts_mutex;
46
+};
47
+
48
+QAlertDispatcher::Tag::Tag(QAlertDispatcher* dispatcher)
49
+    : dispatcher(dispatcher)
50
+{}
51
+
52
+QAlertDispatcher::QAlertDispatcher(libtorrent::session *session, QObject* parent)
53
+    : QObject(parent)
54
+    , m_session(session)
55
+    , current_tag(new Tag(this))
56
+    , event_posted(false)
57
+{
58
+    alerts.reserve(DEFAULT_ALERTS_CAPACITY);
59
+    m_session->set_alert_dispatch(boost::bind(&QAlertDispatcher::dispatch, current_tag, _1));
60
+}
61
+
62
+QAlertDispatcher::~QAlertDispatcher() {
63
+    // When QAlertDispatcher is destoyed, libtorrent still can call
64
+    // QAlertDispatcher::dispatch a few times after destruction. This is
65
+    // handled by passing a "tag". A tag is a object that references QAlertDispatch.
66
+    // Tag could be invalidated. So on destruction QAlertDispatcher invalidates a tag
67
+    // and then unsubscribes from alerts. When QAlertDispatcher::dispatch is called
68
+    // with invalid tag it simply discard an alert.
69
+
70
+    {
71
+        QMutexLocker lock(&current_tag->alerts_mutex);
72
+        current_tag->dispatcher = 0;
73
+        current_tag.clear();
74
+    }
75
+
76
+    typedef boost::function<void (std::auto_ptr<libtorrent::alert>)> dispatch_function_t;
77
+    m_session->set_alert_dispatch(dispatch_function_t());
78
+}
79
+
80
+void QAlertDispatcher::getPendingAlertsNoWait(std::vector<libtorrent::alert*>& out) {
81
+    Q_ASSERT(out.empty());
82
+    out.reserve(DEFAULT_ALERTS_CAPACITY);
83
+
84
+    QMutexLocker lock(&current_tag->alerts_mutex);
85
+    alerts.swap(out);
86
+    event_posted = false;
87
+}
88
+
89
+void QAlertDispatcher::getPendingAlerts(std::vector<libtorrent::alert*>& out, unsigned long time) {
90
+    Q_ASSERT(out.empty());
91
+    out.reserve(DEFAULT_ALERTS_CAPACITY);
92
+
93
+    QMutexLocker lock(&current_tag->alerts_mutex);
94
+
95
+    while (alerts.empty())
96
+        alerts_condvar.wait(&current_tag->alerts_mutex, time);
97
+
98
+    alerts.swap(out);
99
+    event_posted = false;
100
+}
101
+
102
+void QAlertDispatcher::dispatch(QSharedPointer<Tag> tag,
103
+                                std::auto_ptr<libtorrent::alert> alert_ptr) {
104
+    QMutexLocker lock(&(tag->alerts_mutex));
105
+    QAlertDispatcher* that = tag->dispatcher;
106
+    if (!that)
107
+        return;
108
+
109
+    bool was_empty = that->alerts.empty();
110
+
111
+    that->alerts.push_back(alert_ptr.get());
112
+    alert_ptr.release();
113
+
114
+    if (was_empty)
115
+        that->alerts_condvar.wakeAll();
116
+
117
+    that->enqueueToMainThread();
118
+
119
+    Q_ASSERT(that->current_tag == tag);
120
+}
121
+
122
+void QAlertDispatcher::enqueueToMainThread() {
123
+    if (!event_posted) {
124
+        event_posted = true;
125
+        QMetaObject::invokeMethod(this, "deliverSignal", Qt::QueuedConnection);
126
+    }
127
+}
128
+
129
+void QAlertDispatcher::deliverSignal() {
130
+    emit alertsReceived();
131
+
132
+    QMutexLocker lock(&current_tag->alerts_mutex);
133
+    event_posted = false;
134
+
135
+    if (!alerts.empty())
136
+        enqueueToMainThread();
137
+}

+ 80
- 0
src/libs/qtlibtorrent/alertdispatcher.h View File

@@ -0,0 +1,80 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2014  Ivan Sorokin
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : vanyacpp@gmail.com
29
+ */
30
+
31
+#ifndef ALERTDISPATCHER_H
32
+#define ALERTDISPATCHER_H
33
+
34
+#include <QObject>
35
+#include <QMutex>
36
+#include <QWaitCondition>
37
+#include <QAtomicPointer>
38
+#include <QSharedPointer>
39
+
40
+#include <vector>
41
+#include <memory>
42
+
43
+namespace libtorrent {
44
+class session;
45
+class alert;
46
+}
47
+
48
+class QAlertDispatcher : public QObject {
49
+    Q_OBJECT
50
+    Q_DISABLE_COPY(QAlertDispatcher)
51
+
52
+    struct Tag;
53
+
54
+public:
55
+    QAlertDispatcher(libtorrent::session *session, QObject* parent);
56
+    ~QAlertDispatcher();
57
+
58
+    void getPendingAlertsNoWait(std::vector<libtorrent::alert*>&);
59
+    void getPendingAlerts(std::vector<libtorrent::alert*>&, unsigned long time = ULONG_MAX);
60
+
61
+signals:
62
+    void alertsReceived();
63
+
64
+private:
65
+    static void dispatch(QSharedPointer<Tag>,
66
+                         std::auto_ptr<libtorrent::alert>);
67
+    void enqueueToMainThread();
68
+
69
+private slots:
70
+    void deliverSignal();
71
+
72
+private:
73
+    libtorrent::session *m_session;
74
+    QWaitCondition alerts_condvar;
75
+    std::vector<libtorrent::alert*> alerts;
76
+    QSharedPointer<Tag> current_tag;
77
+    bool event_posted;
78
+};
79
+
80
+#endif // ALERTDISPATCHER_H

+ 7
- 7
src/libs/qtlibtorrent/bandwidthscheduler.h View File

@@ -13,7 +13,7 @@ class BandwidthScheduler: public QTimer {
13 13
 
14 14
 public:
15 15
   BandwidthScheduler(QObject *parent): QTimer(parent) {
16
-    Q_ASSERT(Preferences().isSchedulerEnabled());
16
+    Q_ASSERT(Preferences::instance()->isSchedulerEnabled());
17 17
     // Signal shot, we call start() again manually
18 18
     setSingleShot(true);
19 19
     // Connect Signals/Slots
@@ -22,14 +22,14 @@ public:
22 22
 
23 23
 public slots:
24 24
   void start() {
25
-    const Preferences pref;
26
-    Q_ASSERT(pref.isSchedulerEnabled());
27
-    bool alt_bw_enabled = pref.isAltBandwidthEnabled();
25
+    const Preferences* const pref = Preferences::instance();
26
+    Q_ASSERT(pref->isSchedulerEnabled());
27
+    bool alt_bw_enabled = pref->isAltBandwidthEnabled();
28 28
 
29
-    QTime start = pref.getSchedulerStartTime();
30
-    QTime end = pref.getSchedulerEndTime();
29
+    QTime start = pref->getSchedulerStartTime();
30
+    QTime end = pref->getSchedulerEndTime();
31 31
     QTime now = QTime::currentTime();
32
-    int sched_days = pref.getSchedulerDays();
32
+    int sched_days = pref->getSchedulerDays();
33 33
     int day = QDateTime::currentDateTime().toLocalTime().date().dayOfWeek();
34 34
     bool new_mode = false;
35 35
     bool reverse = false;

+ 1037
- 1085
src/libs/qtlibtorrent/qbtsession.cpp
File diff suppressed because it is too large
View File


+ 86
- 24
src/libs/qtlibtorrent/qbtsession.h View File

@@ -42,10 +42,13 @@
42 42
 #include <QRegularExpression>
43 43
 
44 44
 #include <libtorrent/version.hpp>
45
-#include <libtorrent/session.hpp>
45
+#include <libtorrent/session_settings.hpp>
46
+
47
+/*#include <libtorrent/session.hpp>
46 48
 #include <libtorrent/ip_filter.hpp>
47 49
 #include <libtorrent/upnp.hpp>
48 50
 #include <libtorrent/natpmp.hpp>
51
+*/
49 52
 
50 53
 //#include "qtracker.h"
51 54
 #include "qtrackerserv.h"
@@ -54,15 +57,48 @@
54 57
 #include "misc.h"
55 58
 #include "bandwidthscheduler.h"
56 59
 
57
-#define MAX_SAMPLES 20
60
+//#define MAX_SAMPLES 20
61
+
58 62
 
63
+namespace libtorrent {
64
+struct add_torrent_params;
65
+struct pe_settings;
66
+struct proxy_settings;
67
+class session;
68
+struct session_status;
69
+
70
+class alert;
71
+struct torrent_finished_alert;
72
+struct save_resume_data_alert;
73
+struct file_renamed_alert;
74
+struct torrent_deleted_alert;
75
+struct storage_moved_alert;
76
+struct storage_moved_failed_alert;
77
+struct metadata_received_alert;
78
+struct file_error_alert;
79
+struct file_completed_alert;
80
+struct torrent_paused_alert;
81
+struct tracker_error_alert;
82
+struct tracker_reply_alert;
83
+struct tracker_warning_alert;
84
+struct portmap_error_alert;
85
+struct portmap_alert;
86
+struct peer_blocked_alert;
87
+struct peer_ban_alert;
88
+struct fastresume_rejected_alert;
89
+struct url_seed_alert;
90
+struct listen_succeeded_alert;
91
+struct listen_failed_alert;
92
+struct torrent_checked_alert;
93
+struct external_ip_alert;
94
+struct state_update_alert;
95
+struct stats_alert;
59 96
 
60 97
 #if LIBTORRENT_VERSION_NUM < 10000
61 98
 class upnp;
62 99
 class natpmp;
63 100
 #endif
64
-
65
-
101
+}
66 102
 
67 103
 class DownloadThread;
68 104
 class FilterParserThread;
@@ -70,9 +106,8 @@ class FilterParserThread;
70 106
 //class BandwidthScheduler;
71 107
 class ScanFoldersModel;
72 108
 class TorrentSpeedMonitor;
73
-//class DNSUpdater;
74
-
75
-const int MAX_LOG_MESSAGES = 1000;
109
+class TorrentStatistics;
110
+class QAlertDispatcher;
76 111
 
77 112
 enum TorrentExportFolder {
78 113
   RegularTorrentExportFolder,
@@ -98,12 +133,11 @@ public:
98 133
   ~QBtSession();
99 134
   QTorrentHandle getTorrentHandle(const QString &hash) const;
100 135
   std::vector<libtorrent::torrent_handle> getTorrents() const;
101
-  bool isFilePreviewPossible(const QString& hash) const;
102 136
   qreal getPayloadDownloadRate() const;
103 137
   qreal getPayloadUploadRate() const;
104 138
   libtorrent::session_status getSessionStatus() const;
105 139
   int getListenPort() const;
106
-  qreal getRealRatio(const QString& hash) const;
140
+  qreal getRealRatio(const libtorrent::torrent_status &status) const;
107 141
   QHash<QString, TrackerInfos> getTrackersInfo(const QString &hash) const;
108 142
   bool hasActiveTorrents() const;
109 143
   bool hasDownloadingTorrents() const;
@@ -121,6 +155,7 @@ public:
121 155
   inline bool isQueueingEnabled() const { return queueingEnabled; }
122 156
   quint64 getAlltimeDL() const;
123 157
   quint64 getAlltimeUL() const;
158
+  void postTorrentUpdate();
124 159
 
125 160
 public slots:
126 161
   QTorrentHandle addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false, bool imported = false);
@@ -132,11 +167,12 @@ public slots:
132 167
   void startUpTorrents();
133 168
   void recheckTorrent(const QString &hash);
134 169
   void useAlternativeSpeedsLimit(bool alternative);
135
-  qlonglong getETA(const QString& hash) const;
170
+  qlonglong getETA(const QString &hash, const libtorrent::torrent_status &status) const;
171
+
136 172
   /* Needed by Web UI */
137 173
   void pauseAllTorrents();
138 174
   void pauseTorrent(const QString &hash);
139
-  void resumeTorrent(const QString &hash);
175
+  void resumeTorrent(const QString &hash, const bool force = false);
140 176
   void resumeAllTorrents();
141 177
   /* End Web UI */
142 178
   void preAllocateAllFiles(bool b);
@@ -175,13 +211,6 @@ public slots:
175 211
   void enableUPnP(bool b);
176 212
   void enableLSD(bool b);
177 213
   bool enableDHT(bool b);
178
-#ifdef DISABLE_GUI
179
-  void addConsoleMessage(QString msg, QString color=QString::null);
180
-#else
181
-  //void addConsoleMessage(QString msg, QString color=QString::null);
182
-  void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
183
-#endif
184
-  void addPeerBanMessage(QString msg, bool from_ipfilter);
185 214
   void clearConsoleMessages() { consoleMessages.clear(); }
186 215
   void clearPeerBanMessages() { peerBanMessages.clear(); }
187 216
   void processDownloadedFile(QString, QString);
@@ -205,6 +234,32 @@ private:
205 234
   void updateRatioTimer();
206 235
   void recoverPersistentData(const QString &hash, const std::vector<char> &buf);
207 236
   void backupPersistentData(const QString &hash, boost::shared_ptr<libtorrent::entry> data);
237
+  void handleAlert(libtorrent::alert* a);
238
+  void handleTorrentFinishedAlert(libtorrent::torrent_finished_alert* p);
239
+  void handleSaveResumeDataAlert(libtorrent::save_resume_data_alert* p);
240
+  void handleFileRenamedAlert(libtorrent::file_renamed_alert* p);
241
+  void handleTorrentDeletedAlert(libtorrent::torrent_deleted_alert* p);
242
+  void handleStorageMovedAlert(libtorrent::storage_moved_alert* p);
243
+  void handleStorageMovedFailedAlert(libtorrent::storage_moved_failed_alert* p);
244
+  void handleMetadataReceivedAlert(libtorrent::metadata_received_alert* p);
245
+  void handleFileErrorAlert(libtorrent::file_error_alert* p);
246
+  void handleFileCompletedAlert(libtorrent::file_completed_alert* p);
247
+  void handleTorrentPausedAlert(libtorrent::torrent_paused_alert* p);
248
+  void handleTrackerErrorAlert(libtorrent::tracker_error_alert* p);
249
+  void handleTrackerReplyAlert(libtorrent::tracker_reply_alert* p);
250
+  void handleTrackerWarningAlert(libtorrent::tracker_warning_alert* p);
251
+  void handlePortmapWarningAlert(libtorrent::portmap_error_alert* p);
252
+  void handlePortmapAlert(libtorrent::portmap_alert* p);
253
+  void handlePeerBlockedAlert(libtorrent::peer_blocked_alert* p);
254
+  void handlePeerBanAlert(libtorrent::peer_ban_alert* p);
255
+  void handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert* p);
256
+  void handleUrlSeedAlert(libtorrent::url_seed_alert* p);
257
+  void handleListenSucceededAlert(libtorrent::listen_succeeded_alert *p);
258
+  void handleListenFailedAlert(libtorrent::listen_failed_alert *p);
259
+  void handleTorrentCheckedAlert(libtorrent::torrent_checked_alert* p);
260
+  void handleExternalIPAlert(libtorrent::external_ip_alert *p);
261
+  void handleStateUpdateAlert(libtorrent::state_update_alert *p);
262
+  void handleStatsAlert(libtorrent::stats_alert *p);
208 263
 
209 264
 private slots:
210 265
   void addTorrentsFromScanFolder(QStringList&);
@@ -214,8 +269,9 @@ private slots:
214 269
   void saveTempFastResumeData();
215 270
 //  void sendNotificationEmail(const QTorrentHandle &h);
216 271
   void autoRunExternalProgram(const QTorrentHandle &h);
217
-  void mergeTorrents(QTorrentHandle& h_ex, boost::intrusive_ptr<libtorrent::torrent_info> t);
218
-  void mergeTorrents(QTorrentHandle& h_ex, const QString& magnet_uri);
272
+  void mergeTorrents(const QTorrentHandle &h, const boost::intrusive_ptr<libtorrent::torrent_info> t);
273
+  void mergeTorrents(const QTorrentHandle &h, const QString &magnet_uri);
274
+  void mergeTorrents_impl(const QTorrentHandle &h, const QStringList &trackers, const QStringList& urlSeeds);
219 275
   void exportTorrentFile(const QTorrentHandle &h, TorrentExportFolder folder = RegularTorrentExportFolder);
220 276
   //void initWebUi();
221 277
   void handleIPFilterParsed(int ruleCount);
@@ -229,7 +285,9 @@ signals:
229 285
   void resumedTorrent(const QTorrentHandle& h);
230 286
   void finishedTorrent(const QTorrentHandle& h);
231 287
   void fullDiskError(const QTorrentHandle& h, QString msg);
232
-  void trackerError(const QString &hash, QString time, QString msg);
288
+  void trackerSuccess(const QString &hash, const QString &tracker);
289
+  void trackerError(const QString &hash, const QString &tracker);
290
+  void trackerWarning(const QString &hash, const QString &tracker);
233 291
   void trackerAuthenticationRequired(const QTorrentHandle& h);
234 292
   void newDownloadedTorrent(QString path, QString url);
235 293
   void newDownloadedTorrentFromRss(QString url);
@@ -246,6 +304,11 @@ signals:
246 304
   void ipFilterParsed(bool error, int ruleCount);
247 305
   void metadataReceivedHidden(const QTorrentHandle &h);
248 306
   void UPnPSuccess(bool);
307
+  void stateUpdate(const std::vector<libtorrent::torrent_status> &statuses);
308
+  void statsReceived(const libtorrent::stats_alert&);
309
+  void trackersAdded(const QStringList &trackers, const QString &hash);
310
+  void trackerlessChange(bool trackerless, const QString &hash);
311
+  void reloadTrackersAndUrlSeeds(const QTorrentHandle &h);
249 312
 
250 313
 private:
251 314
   // Bittorrent
@@ -303,9 +366,8 @@ private:
303 366
    libtorrent::upnp *m_upnp;
304 367
    libtorrent::natpmp *m_natpmp;
305 368
 #endif
306
-  //bool m_upnp;
307
-  // DynDNS
308
-  //DNSUpdater *m_dynDNSUpdater;
369
+   QAlertDispatcher* m_alertDispatcher;
370
+   TorrentStatistics* m_torrentStatistics;
309 371
 };
310 372
 
311 373
 #endif

+ 6
- 2
src/libs/qtlibtorrent/qtlibtorrent.pri View File

@@ -5,11 +5,15 @@ HEADERS += $$PWD/qbtsession.h \
5 5
            $$PWD/bandwidthscheduler.h \
6 6
            $$PWD/trackerinfos.h \
7 7
            $$PWD/torrentspeedmonitor.h \
8
-           $$PWD/filterparserthread.h
8
+           $$PWD/filterparserthread.h \
9
+    $$PWD/alertdispatcher.h \
10
+    $$PWD/torrentstatistics.h
9 11
 
10 12
 SOURCES += $$PWD/qbtsession.cpp \
11 13
            $$PWD/qtorrenthandle.cpp \
12
-           $$PWD/torrentspeedmonitor.cpp
14
+           $$PWD/torrentspeedmonitor.cpp \
15
+    $$PWD/alertdispatcher.cpp \
16
+    $$PWD/torrentstatistics.cpp
13 17
 
14 18
 !contains(DEFINES, DISABLE_GUI) {
15 19
   HEADERS += $$PWD/torrentmodel.h \

+ 620
- 611
src/libs/qtlibtorrent/qtorrenthandle.cpp
File diff suppressed because it is too large
View File


+ 118
- 98
src/libs/qtlibtorrent/qtorrenthandle.h View File

@@ -31,9 +31,7 @@
31 31
 #ifndef QTORRENTHANDLE_H
32 32
 #define QTORRENTHANDLE_H
33 33
 
34
-#include <libtorrent/version.hpp>
35 34
 #include <libtorrent/torrent_handle.hpp>
36
-#include <libtorrent/torrent_info.hpp>
37 35
 
38 36
 #include <QString>
39 37
 
@@ -41,109 +39,131 @@ QT_BEGIN_NAMESPACE
41 39
 class QStringList;
42 40
 QT_END_NAMESPACE
43 41
 
42
+class QTorrentState
43
+{
44
+public:
45
+    enum
46
+    {
47
+        Unknown = -1,
48
+
49
+        Error,
50
+
51
+        Uploading,
52
+        PausedUploading,
53
+        QueuedUploading,
54
+        StalledUploading,
55
+        CheckingUploading,
56
+
57
+        Downloading,
58
+        PausedDownloading,
59
+        QueuedDownloading,
60
+        StalledDownloading,
61
+        CheckingDownloading
62
+    };
63
+
64
+    QTorrentState(int value);
65
+
66
+    operator int() const;
67
+    QString toString() const;
68
+
69
+private:
70
+    int m_value;
71
+};
72
+
44 73
 // A wrapper for torrent_handle in libtorrent
45 74
 // to interact well with Qt types
46
-class QTorrentHandle : public libtorrent::torrent_handle {
75
+class QTorrentHandle: public libtorrent::torrent_handle
76
+{
47 77
 
48 78
 public:
49 79
 
50
-  //
51
-  // Constructors
52
-  //
53
-
54
-  QTorrentHandle() {}
55
-  explicit QTorrentHandle(const libtorrent::torrent_handle& h);
56
-
57
-  //
58
-  // Getters
59
-  //
60
-  QString hash() const;
61
-  QString name() const;
62
-  float progress() const;
63
-  libtorrent::bitfield pieces() const;
64
-  QString current_tracker() const;
65
-  bool is_paused() const;
66
-  bool has_filtered_pieces() const;
67
-  libtorrent::size_type total_size() const;
68
-  libtorrent::size_type piece_length() const;
69
-  int num_pieces() const;
70
-  libtorrent::size_type total_wanted_done() const;
71
-  libtorrent::size_type total_wanted() const;
72
-  qreal download_payload_rate() const;
73
-  qreal upload_payload_rate() const;
74
-  int num_connections() const;
75
-  int connections_limit() const;
76
-  int num_peers() const;
77
-  int num_seeds() const;
78
-  int num_complete() const;
79
-  int num_incomplete() const;
80
-  QString save_path() const;
81
-  QString save_path_parsed() const;
82
-  QStringList url_seeds() const;
83
-  libtorrent::size_type actual_size() const;
84
-  int num_files() const;
85
-  int queue_position() const;
86
-  bool is_queued() const;
87
-  QString filename_at(unsigned int index) const;
88
-  libtorrent::size_type filesize_at(unsigned int index) const;
89
-  QString filepath_at(unsigned int index) const;
90
-  QString orig_filepath_at(unsigned int index) const;
91
-  libtorrent::torrent_status::state_t state() const;
92
-  QString creator() const;
93
-  QString comment() const;
94
-  libtorrent::size_type total_failed_bytes() const;
95
-  libtorrent::size_type total_redundant_bytes() const;
96
-  libtorrent::size_type total_payload_download() const;
97
-  libtorrent::size_type total_payload_upload() const;
98
-  libtorrent::size_type all_time_upload() const;
99
-  libtorrent::size_type all_time_download() const;
100
-  libtorrent::size_type total_done() const;
101
-  QStringList absolute_files_path() const;
102
-  QStringList absolute_files_path_uneeded() const;
103
-  bool has_missing_files() const;
104
-  int num_uploads() const;
105
-  bool is_seed() const;
106
-  bool is_checking() const;
107
-  bool is_auto_managed() const;
108
-  bool is_sequential_download() const;
109
-  qlonglong active_time() const;
110
-  qlonglong seeding_time() const;
111
-  QString creation_date() const;
112
-  QString next_announce() const;
113
-  qlonglong next_announce_s() const;
114
-  bool priv() const;
115
-  bool first_last_piece_first() const;
116
-  QString root_path() const;
117
-  QString firstFileSavePath() const;
118
-  bool has_error() const;
119
-  QString error() const;
120
-  void downloading_pieces(libtorrent::bitfield& bf) const;
121
-  bool has_metadata() const;
122
-  float distributed_copies() const;
123
-  void file_progress(std::vector<libtorrent::size_type>& fp) const;
124
-
125
-  //
126
-  // Setters
127
-  //
128
-  void pause() const;
129
-  void resume() const;
130
-  void remove_url_seed(const QString& seed) const;
131
-  void add_url_seed(const QString& seed) const;
132
-  void set_tracker_login(const QString& username, const QString& password) const;
133
-  void move_storage(const QString& path) const;
134
-  void prioritize_first_last_piece(bool b) const;
135
-  void rename_file(int index, const QString& name) const;
136
-  bool save_torrent_file(const QString& path) const;
137
-  void prioritize_files(const std::vector<int>& files) const;
138
-  void file_priority(int index, int priority) const;
139
-
140
-  //
141
-  // Operators
142
-  //
143
-  bool operator ==(const QTorrentHandle& new_h) const;
80
+    //
81
+    // Constructors
82
+    //
83
+
84
+    QTorrentHandle() {}
85
+    explicit QTorrentHandle(const libtorrent::torrent_handle& h);
86
+
87
+    //
88
+    // Getters
89
+    //
90
+    QString hash() const;
91
+    QString name() const;
92
+    QString current_tracker() const;
93
+    bool is_paused() const;
94
+    bool has_filtered_pieces() const;
95
+    libtorrent::size_type total_size() const;
96
+    libtorrent::size_type piece_length() const;
97
+    int num_pieces() const;
98
+    QString save_path() const;
99
+    QString save_path_parsed() const;
100
+    QStringList url_seeds() const;
101
+    libtorrent::size_type actual_size() const;
102
+    int num_files() const;
103
+    int queue_position() const;
104
+    bool is_queued() const;
105
+    QString filename_at(unsigned int index) const;
106
+    libtorrent::size_type filesize_at(unsigned int index) const;
107
+    QString filepath_at(unsigned int index) const;
108
+    QString orig_filepath_at(unsigned int index) const;
109
+    libtorrent::torrent_status::state_t state() const;
110
+    QString creator() const;
111
+    QString comment() const;
112
+    QStringList absolute_files_path() const;
113
+    QStringList absolute_files_path_uneeded() const;
114
+    bool has_missing_files() const;
115
+    bool is_seed() const;
116
+    bool is_checking() const;
117
+    bool is_sequential_download() const;
118
+    QString creation_date() const;
119
+    qlonglong creation_date_unix() const;
120
+    bool priv() const;
121
+    bool first_last_piece_first() const;
122
+    QString root_path() const;
123
+    QString firstFileSavePath() const;
124
+    bool has_error() const;
125
+    QString error() const;
126
+    void downloading_pieces(libtorrent::bitfield& bf) const;
127
+    bool has_metadata() const;
128
+    void file_progress(std::vector<libtorrent::size_type>& fp) const;
129
+    QTorrentState torrentState() const;
130
+    qulonglong eta() const;
131
+    void toggleSequentialDownload();
132
+    void toggleFirstLastPiecePrio();
133
+    bool is_forced() const;
134
+
135
+    //
136
+    // Setters
137
+    //
138
+    void pause() const;
139
+    void resume(const bool force = false) const;
140
+    void remove_url_seed(const QString& seed) const;
141
+    void add_url_seed(const QString& seed) const;
142
+    void set_tracker_login(const QString& username, const QString& password) const;
143
+    void move_storage(const QString& path) const;
144
+    void prioritize_first_last_piece(bool b) const;
145
+    void rename_file(int index, const QString& name) const;
146
+    bool save_torrent_file(const QString& path) const;
147
+    void prioritize_files(const std::vector<int>& files) const;
148
+    void file_priority(int index, int priority) const;
149
+
150
+    //
151
+    // Operators
152
+    //
153
+    bool operator ==(const QTorrentHandle& new_h) const;
154
+
155
+    static bool is_paused(const libtorrent::torrent_status &status);
156
+    static int queue_position(const libtorrent::torrent_status &status);
157
+    static bool is_queued(const libtorrent::torrent_status &status);
158
+    static bool is_seed(const libtorrent::torrent_status &status);
159
+    static bool is_checking(const libtorrent::torrent_status &status);
160
+    static bool has_error(const libtorrent::torrent_status &status);
161
+    static float progress(const libtorrent::torrent_status &status);
162
+    static QString filepath_at(const libtorrent::torrent_info &info, unsigned int index);
163
+    static bool is_forced(const libtorrent::torrent_status &status);
144 164
 
145 165
 private:
146
-  void prioritize_first_last_piece(int file_index, bool b) const;
166
+    void prioritize_first_last_piece(int file_index, bool b) const;
147 167
 
148 168
 };
149 169
 

+ 561
- 361
src/libs/qtlibtorrent/torrentmodel.cpp
File diff suppressed because it is too large
View File


+ 62
- 54
src/libs/qtlibtorrent/torrentmodel.h View File

@@ -40,87 +40,95 @@
40 40
 #include "qtorrenthandle.h"
41 41
 
42 42
 struct TorrentStatusReport {
43
-  TorrentStatusReport(): nb_downloading(0), nb_seeding(0), nb_active(0), nb_inactive(0), nb_paused(0) {}
44
-  uint nb_downloading; uint nb_seeding; uint nb_active; uint nb_inactive; uint nb_paused;
43
+    TorrentStatusReport();
44
+    uint nb_downloading;
45
+    uint nb_seeding;
46
+    uint nb_completed;
47
+    uint nb_active;
48
+    uint nb_inactive;
49
+    uint nb_paused;
45 50
 };
46 51
 
47 52
 class TorrentModelItem : public QObject {
48
-Q_OBJECT
53
+    Q_OBJECT
49 54
 
50 55
 public:
51
-  enum State {STATE_DOWNLOADING, STATE_DOWNLOADING_META, STATE_ALLOCATING, STATE_STALLED_DL, STATE_STALLED_UP, STATE_SEEDING, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_QUEUED_CHECK, STATE_QUEUED_FASTCHECK, STATE_INVALID};
52
-  enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_TRACKER, TR_DLLIMIT, TR_UPLIMIT, TR_AMOUNT_DOWNLOADED, TR_AMOUNT_UPLOADED, TR_AMOUNT_LEFT, TR_TIME_ELAPSED, TR_SAVE_PATH, TR_COMPLETED, TR_RATIO_LIMIT, NB_COLUMNS};
56
+    enum State {STATE_DOWNLOADING, STATE_DOWNLOADING_META, STATE_ALLOCATING, STATE_STALLED_DL, STATE_SEEDING, STATE_STALLED_UP, STATE_QUEUED_DL, STATE_QUEUED_UP, STATE_CHECKING_UP, STATE_CHECKING_DL, STATE_QUEUED_CHECK, STATE_QUEUED_FASTCHECK, STATE_PAUSED_DL, STATE_PAUSED_UP, STATE_PAUSED_MISSING, STATE_FORCED_DL, STATE_FORCED_UP, STATE_INVALID};
57
+    enum Column {TR_NAME, TR_PRIORITY, TR_SIZE, TR_TOTAL_SIZE, TR_PROGRESS, TR_STATUS, TR_SEEDS, TR_PEERS, TR_DLSPEED, TR_UPSPEED, TR_ETA, TR_RATIO, TR_LABEL, TR_ADD_DATE, TR_SEED_DATE, TR_TRACKER, TR_DLLIMIT, TR_UPLIMIT, TR_AMOUNT_DOWNLOADED, TR_AMOUNT_UPLOADED, TR_AMOUNT_LEFT, TR_TIME_ELAPSED, TR_SAVE_PATH, TR_COMPLETED, TR_RATIO_LIMIT, TR_SEEN_COMPLETE_DATE, TR_LAST_ACTIVITY, TR_AMOUNT_DOWNLOADED_SESSION, TR_AMOUNT_UPLOADED_SESSION, NB_COLUMNS};
53 58
 
54 59
 public:
55
-  TorrentModelItem(const QTorrentHandle& h);
56
-  inline int columnCount() const { return NB_COLUMNS; }
57
-  QVariant data(int column, int role = Qt::DisplayRole) const;
58
-  bool setData(int column, const QVariant &value, int role = Qt::DisplayRole);
59
-  inline QString hash() const { return m_hash; }
60
+    TorrentModelItem(const QTorrentHandle& h);
61
+    void refreshStatus(libtorrent::torrent_status const& status);
62
+    inline int columnCount() const { return NB_COLUMNS; }
63
+    QVariant data(int column, int role = Qt::DisplayRole) const;
64
+    bool setData(int column, const QVariant &value, int role = Qt::DisplayRole);
65
+    inline QString const& hash() const { return m_hash; }
66
+    State state() const;
67
+    QTorrentHandle torrentHandle() const;
60 68
 
61 69
 signals:
62
-  void labelChanged(QString previous, QString current);
70
+    void labelChanged(QString previous, QString current);
63 71
 
64 72
 private:
65
-  State state() const;
73
+    static QIcon getIconByState(State state);
74
+    static QColor getColorByState(State state);
66 75
 
67 76
 private:
68
-  QTorrentHandle m_torrent;
69
-  QDateTime m_addedTime;
70
-  QDateTime m_seedTime;
71
-  QString m_label;
72
-  QString m_name;
73
-  mutable QIcon m_icon;
74
-  mutable QColor m_fgColor;
75
-  QString m_hash; // Cached for safety reasons
77
+    QTorrentHandle m_torrent;
78
+    libtorrent::torrent_status m_lastStatus;
79
+    QDateTime m_addedTime;
80
+    QString m_label;
81
+    QString m_name;
82
+    QString m_hash; // Cached for safety reasons
76 83
 };
77 84
 
78 85
 class TorrentModel : public QAbstractListModel
79 86
 {
80
-  Q_OBJECT
81
-  Q_DISABLE_COPY(TorrentModel)
87
+    Q_OBJECT
88
+    Q_DISABLE_COPY(TorrentModel)
82 89
 
83 90
 public:
84
-  explicit TorrentModel(QObject *parent = 0);
85
-  ~TorrentModel();
86
-  inline int rowCount(const QModelIndex& index = QModelIndex()) const { Q_UNUSED(index); return m_torrents.size(); }
87
-  int columnCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return TorrentModelItem::NB_COLUMNS; }
88
-  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
89
-  bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
90
-  QVariant headerData(int section, Qt::Orientation orientation, int role) const;
91
-  int torrentRow(const QString &hash) const;
92
-  QString torrentHash(int row) const;
93
-  void setRefreshInterval(int refreshInterval);
94
-  TorrentStatusReport getTorrentStatusReport() const;
95
-  Qt::ItemFlags flags(const QModelIndex &index) const;
96
-  void populate();
97
-  bool inhibitSystem();
91
+    explicit TorrentModel(QObject *parent = 0);
92
+    ~TorrentModel();
93
+    inline int rowCount(const QModelIndex& index = QModelIndex()) const { Q_UNUSED(index); return m_torrents.size(); }
94
+    int columnCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return TorrentModelItem::NB_COLUMNS; }
95
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
96
+    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
97
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
98
+    int torrentRow(const QString &hash) const;
99
+    QString torrentHash(int row) const;
100
+    void setRefreshInterval(int refreshInterval);
101
+    TorrentStatusReport getTorrentStatusReport() const;
102
+    Qt::ItemFlags flags(const QModelIndex &index) const;
103
+    void populate();
104
+    bool inhibitSystem();
98 105
 
99 106
 signals:
100
-  void torrentAdded(TorrentModelItem *torrentItem);
101
-  void torrentAboutToBeRemoved(TorrentModelItem *torrentItem);
102
-  void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current);
107
+    void torrentAdded(TorrentModelItem *torrentItem);
108
+    void torrentAboutToBeRemoved(TorrentModelItem *torrentItem);
109
+    void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current);
110
+    void modelRefreshed();
103 111
 
104 112
 private slots:
105
-  void addTorrent(const QTorrentHandle& h);
106
-  void removeTorrent(const QString &hash);
107
-  void handleTorrentUpdate(const QTorrentHandle &h);
108
-  void handleFinishedTorrent(const QTorrentHandle& h);
109
-  void notifyTorrentChanged(int row);
110
-  void forceModelRefresh();
111
-  void handleTorrentLabelChange(QString previous, QString current);
112
-  void handleTorrentAboutToBeRemoved(const QTorrentHandle & h);
113
+    void addTorrent(const QTorrentHandle& h);
114
+    void handleTorrentUpdate(const QTorrentHandle &h);
115
+    void handleFinishedTorrent(const QTorrentHandle& h);
116
+    void notifyTorrentChanged(int row);
117
+    void forceModelRefresh();
118
+    void handleTorrentLabelChange(QString previous, QString current);
119
+    void handleTorrentAboutToBeRemoved(const QTorrentHandle & h);
120
+    void stateUpdated(const std::vector<libtorrent::torrent_status> &statuses);
113 121
 
114 122
 private:
115
-  void beginInsertTorrent(int row);
116
-  void endInsertTorrent();
117
-  void beginRemoveTorrent(int row);
118
-  void endRemoveTorrent();
123
+    void beginInsertTorrent(int row);
124
+    void endInsertTorrent();
125
+    void beginRemoveTorrent(int row);
126
+    void endRemoveTorrent();
119 127
 
120 128
 private:
121
-  QList<TorrentModelItem*> m_torrents;
122
-  int m_refreshInterval;
123
-  QTimer m_refreshTimer;
129
+    QList<TorrentModelItem*> m_torrents;
130
+    int m_refreshInterval;
131
+    QTimer m_refreshTimer;
124 132
 };
125 133
 
126 134
 #endif // TORRENTMODEL_H

+ 113
- 176
src/libs/qtlibtorrent/torrentspeedmonitor.cpp View File

@@ -28,231 +28,168 @@
28 28
  * Contact : chris@qbittorrent.org
29 29
  */
30 30
 
31
-#include <QMutexLocker>
32 31
 #include <QList>
33
-#include <QDateTime>
34
-#include <vector>
35 32
 
36 33
 #include "qbtsession.h"
37 34
 #include "misc.h"
38 35
 #include "torrentspeedmonitor.h"
39
-#include "qinisettings.h"
40 36
 
41 37
 using namespace libtorrent;
42 38
 
39
+namespace {
40
+
43 41
 template<class T> struct Sample {
44
-  Sample(const T down = 0, const T up = 0) : download(down), upload(up) {}
45
-  T download;
46
-  T upload;
42
+    Sample()
43
+        : download()
44
+        , upload()
45
+    {}
46
+
47
+    Sample(T download, T upload)
48
+        : download(download)
49
+        , upload(upload)
50
+    {}
51
+
52
+    template <typename U>
53
+    explicit Sample(Sample<U> other)
54
+        : download(static_cast<U>(other.download))
55
+        , upload(static_cast<U>(other.upload))
56
+    {}
57
+
58
+    T download;
59
+    T upload;
47 60
 };
48 61
 
49
-class SpeedSample {
50
-
51
-public:
52
-  SpeedSample() {}
53
-  void addSample(int speedDL, int speedUL);
54
-  Sample<qreal> average() const;
55
-  void clear();
62
+template <typename T>
63
+Sample<T>& operator+=(Sample<T>& lhs, Sample<T> const& rhs) {
64
+    lhs.download += rhs.download;
65
+    lhs.upload   += rhs.upload;
66
+    return lhs;
67
+}
56 68
 
57
-private:
58
-  static const int max_samples = 30;
69
+template <typename T>
70
+Sample<T>& operator-=(Sample<T>& lhs, Sample<T> const& rhs) {
71
+    lhs.download -= rhs.download;
72
+    lhs.upload   -= rhs.upload;
73
+    return lhs;
74
+}
59 75
 
60
-private:
61
-  QList<Sample<int> > m_speedSamples;
62
-};
76
+template <typename T>
77
+Sample<T> operator+(Sample<T> const& lhs, Sample<T> const& rhs) {
78
+    return Sample<T>(lhs.download + rhs.download, lhs.upload + rhs.upload);
79
+}
63 80
 
64
-TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session) :
65
-  QThread(session), m_abort(false), m_session(session),
66
-  sessionUL(0), sessionDL(0), lastWrite(0), dirty(false)
67
-{
68
-  connect(m_session, SIGNAL(deletedTorrent(QString)), SLOT(removeSamples(QString)));
69
-  connect(m_session, SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle)));
70
-  loadStats();
81
+template <typename T>
82
+Sample<T> operator-(Sample<T> const& lhs, Sample<T> const& rhs) {
83
+    return Sample<T>(lhs.download - rhs.download, lhs.upload - rhs.upload);
71 84
 }
72 85
 
73
-TorrentSpeedMonitor::~TorrentSpeedMonitor() {
74
-  m_abort = true;
75
-  m_abortCond.wakeOne();
76
-  wait();
77
-  if (dirty)
78
-    lastWrite = 0;
79
-  saveStats();
86
+template <typename T>
87
+Sample<T> operator*(Sample<T> const& lhs, T rhs) {
88
+    return Sample<T>(lhs.download * rhs, lhs.upload * rhs);
80 89
 }
81 90
 
82
-void TorrentSpeedMonitor::run()
83
-{
84
-  do {
85
-    m_mutex.lock();
86
-    getSamples();
87
-    saveStats();
88
-    m_abortCond.wait(&m_mutex, 1000);
89
-    m_mutex.unlock();
90
-  } while(!m_abort);
91
+template <typename T>
92
+Sample<T> operator*(T lhs,Sample<T> const& rhs) {
93
+    return Sample<T>(lhs * rhs.download, lhs * rhs.upload);
91 94
 }
92 95
 
93
-void SpeedSample::addSample(int speedDL, int speedUL)
94
-{
95
-  m_speedSamples << Sample<int>(speedDL, speedUL);
96
-  if (m_speedSamples.size() > max_samples)
97
-    m_speedSamples.removeFirst();
96
+template <typename T>
97
+Sample<T> operator/(Sample<T> const& lhs, T rhs) {
98
+    return Sample<T>(lhs.download / rhs, lhs.upload / rhs);
99
+}
98 100
 }
99 101
 
100
-Sample<qreal> SpeedSample::average() const
101
-{
102
-  if (m_speedSamples.empty())
103
-    return Sample<qreal>();
102
+class SpeedSample {
104 103
 
105
-  qlonglong sumDL = 0;
106
-  qlonglong sumUL = 0;
104
+public:
105
+    SpeedSample() {}
106
+    void addSample(Sample<int> const& item);
107
+    Sample<qreal> average() const;
108
+
109
+private:
110
+    static const int max_samples = 30;
107 111
 
108
-  foreach (const Sample<int>& s, m_speedSamples) {
109
-    sumDL += s.download;
110
-    sumUL += s.upload;
111
-  }
112
+private:
113
+    QList<Sample<int> > m_speedSamples;
114
+    Sample<long long> m_sum;
115
+};
112 116
 
113
-  const qreal numSamples = m_speedSamples.size();
114
-  return Sample<qreal>(sumDL/numSamples, sumUL/numSamples);
117
+TorrentSpeedMonitor::TorrentSpeedMonitor(QBtSession* session)
118
+    : m_session(session)
119
+{
120
+    connect(m_session, SIGNAL(torrentAboutToBeRemoved(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle)));
121
+    connect(m_session, SIGNAL(pausedTorrent(QTorrentHandle)), SLOT(removeSamples(QTorrentHandle)));
122
+    connect(m_session, SIGNAL(statsReceived(libtorrent::stats_alert)), SLOT(statsReceived(libtorrent::stats_alert)));
115 123
 }
116 124
 
117
-void SpeedSample::clear()
125
+TorrentSpeedMonitor::~TorrentSpeedMonitor()
126
+{}
127
+
128
+void SpeedSample::addSample(Sample<int> const& item)
118 129
 {
119
-  m_speedSamples.clear();
130
+    m_speedSamples.push_back(item);
131
+    m_sum += Sample<long long>(item);
132
+    if (m_speedSamples.size() > max_samples) {
133
+        m_sum -= Sample<long long>(m_speedSamples.front());
134
+        m_speedSamples.pop_front();
135
+    }
120 136
 }
121 137
 
122
-void TorrentSpeedMonitor::removeSamples(const QString &hash)
138
+Sample<qreal> SpeedSample::average() const
123 139
 {
124
-  m_samples.remove(hash);
140
+    if (m_speedSamples.empty())
141
+        return Sample<qreal>();
142
+
143
+    return Sample<qreal>(m_sum) * (qreal(1.) / m_speedSamples.size());
125 144
 }
126 145
 
127 146
 void TorrentSpeedMonitor::removeSamples(const QTorrentHandle& h) {
128
-  try {
129
-    m_samples.remove(h.hash());
130
-  } catch(invalid_handle&) {}
147
+    try {
148
+        m_samples.remove(h.hash());
149
+    } catch(invalid_handle&) {}
131 150
 }
132 151
 
133
-qlonglong TorrentSpeedMonitor::getETA(const QString &hash) const
152
+qlonglong TorrentSpeedMonitor::getETA(const QString &hash, const libtorrent::torrent_status &status) const
134 153
 {
135
-  QMutexLocker locker(&m_mutex);
136
-  QTorrentHandle h = m_session->getTorrentHandle(hash);
137
-  if (h.is_paused() || !m_samples.contains(hash))
138
-    return MAX_ETA;
139
-
140
-  const Sample<qreal> speed_average = m_samples[hash].average();
154
+    if (QTorrentHandle::is_paused(status))
155
+        return MAX_ETA;
141 156
 
142
-  if (h.is_seed()) {
143
-    if (!speed_average.upload)
144
-      return MAX_ETA;
157
+    QHash<QString, SpeedSample>::const_iterator i = m_samples.find(hash);
158
+    if (i == m_samples.end())
159
+        return MAX_ETA;
145 160
 
146
-    bool _unused;
147
-    qreal max_ratio = m_session->getMaxRatioPerTorrent(hash, &_unused);
148
-    if (max_ratio < 0)
149
-      return MAX_ETA;
161
+    const Sample<qreal> speed_average = i->average();
150 162
 
151
-    libtorrent::size_type realDL = h.all_time_download();
152
-    if (realDL <= 0)
153
-      realDL = h.total_wanted();
163
+    if (QTorrentHandle::is_seed(status)) {
164
+        if (!speed_average.upload)
165
+            return MAX_ETA;
154 166
 
155
-    return (realDL * max_ratio - h.all_time_upload()) / speed_average.upload;
156
-  }
167
+        bool _unused;
168
+        qreal max_ratio = m_session->getMaxRatioPerTorrent(hash, &_unused);
169
+        if (max_ratio < 0)
170
+            return MAX_ETA;
157 171
 
158
-  if (!speed_average.download)
159
-    return MAX_ETA;
172
+        libtorrent::size_type realDL = status.all_time_download;
173
+        if (realDL <= 0)
174
+            realDL = status.total_wanted;
160 175
 
161
-  return (h.total_wanted() - h.total_wanted_done()) / speed_average.download;
162
-}
176
+        return (realDL * max_ratio - status.all_time_upload) / speed_average.upload;
177
+    }
163 178
 
164
-quint64 TorrentSpeedMonitor::getAlltimeDL() const {
165
-  QMutexLocker l(&m_mutex);
166
-  return alltimeDL + sessionDL;
167
-}
179
+    if (!speed_average.download)
180
+        return MAX_ETA;
168 181
 
169
-quint64 TorrentSpeedMonitor::getAlltimeUL() const {
170
-  QMutexLocker l(&m_mutex);
171
-  return alltimeUL + sessionUL;
182
+    return (status.total_wanted - status.total_wanted_done) / speed_average.download;
172 183
 }
173 184
 
174
-void TorrentSpeedMonitor::getSamples()
185
+void TorrentSpeedMonitor::statsReceived(const stats_alert &stats)
175 186
 {
176
-  const std::vector<torrent_handle> torrents = m_session->getSession()->get_torrents();
177
-
178
-  std::vector<torrent_handle>::const_iterator it = torrents.begin();
179
-  std::vector<torrent_handle>::const_iterator itend = torrents.end();
180
-  for ( ; it != itend; ++it) {
181
-    try {
182
-#if LIBTORRENT_VERSION_NUM >= 1600
183
-      torrent_status st = it->status(0x0);
184
-#else
185
-      torrent_status st = it->status();
186
-#endif
187
-      if (!st.paused) {
188
-        int up = st.upload_payload_rate;
189
-        int down = st.download_payload_rate;
190
-        m_samples[misc::toQString(it->info_hash())].addSample(down, up);
191
-      }
192
-    } catch(invalid_handle&) {}
193
-  }
194
-  libtorrent::session_status ss = m_session->getSessionStatus();
195
-  if (ss.total_download > sessionDL) {
196
-    sessionDL = ss.total_download;
197
-    dirty = true;
198
-  }
199
-  if (ss.total_upload > sessionUL) {
200
-    sessionUL = ss.total_upload;
201
-    dirty = true;
202
-  }
203
-}
187
+    Q_ASSERT(stats.interval >= 1000);
204 188
 
205
-void TorrentSpeedMonitor::saveStats() const {
206
-#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
207
-  if (!(dirty && (QDateTime().toTime_t() * 1000 - lastWrite >= 15*60*1000) ))
208
-#else
209
-  if (!(dirty && (QDateTime::currentMSecsSinceEpoch() - lastWrite >= 15*60*1000) ))
210
-#endif
211
-    return;
212
-  QIniSettings s("pcode", "nodecast-data");
213
-  QVariantHash v;
214
-  v.insert("AlltimeDL", alltimeDL + sessionDL);
215
-  v.insert("AlltimeUL", alltimeUL + sessionUL);
216
-  s.setValue("Stats/AllStats", v);
217
-  dirty = false;
218
-#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
219
-  lastWrite = QDateTime().toTime_t() * 1000;
220
-#else
221
-  lastWrite = QDateTime::currentMSecsSinceEpoch();
222
-#endif
223
-}
224
-
225
-void TorrentSpeedMonitor::loadStats() {
226
-  // Temp code. Versions v3.1.4 and v3.1.5 saved the data in the qbittorrent.ini file.
227
-  // This code reads the data from there, writes it to the new file, and removes the keys
228
-  // from the old file. This code should be removed after some time has passed.
229
-  // e.g. When we reach v3.3.0
230
-  QIniSettings s_old;
231
-  QIniSettings s("pcode", "nodecast-data");
232
-  QVariantHash v;
233
-
234
-  // Let's test if the qbittorrent.ini holds the key
235
-  if (s_old.contains("Stats/AllStats")) {
236
-    v = s_old.value("Stats/AllStats").toHash();
237
-    dirty = true;
238
-
239
-    // If the user has used qbt > 3.1.5 and then reinstalled/used
240
-    // qbt < 3.1.6, there will be stats in qbittorrent-data.ini too
241
-    // so we need to merge those 2.
242
-    if (s.contains("Stats/AllStats")) {
243
-      QVariantHash tmp = s.value("Stats/AllStats").toHash();
244
-      v["AlltimeDL"] = v["AlltimeDL"].toULongLong() + tmp["AlltimeDL"].toULongLong();
245
-      v["AlltimeUL"] = v["AlltimeUL"].toULongLong() + tmp["AlltimeUL"].toULongLong();
246
-    }
247
-  }
248
-  else
249
-    v = s.value("Stats/AllStats").toHash();
189
+    Sample<int> transferred(stats.transferred[stats_alert::download_payload],
190
+            stats.transferred[stats_alert::upload_payload]);
250 191
 
251
-  alltimeDL = v["AlltimeDL"].toULongLong();
252
-  alltimeUL = v["AlltimeUL"].toULongLong();
192
+    Sample<int> normalized = Sample<int>(Sample<long long>(transferred) * 1000LL / static_cast<long long>(stats.interval));
253 193
 
254
-  if (dirty) {
255
-    saveStats();
256
-    s_old.remove("Stats/AllStats");
257
-  }
194
+    m_samples[misc::toQString(stats.handle.info_hash())].addSample(normalized);
258 195
 }

+ 12
- 32
src/libs/qtlibtorrent/torrentspeedmonitor.h View File

@@ -31,52 +31,32 @@
31 31
 #ifndef TORRENTSPEEDMONITOR_H
32 32
 #define TORRENTSPEEDMONITOR_H
33 33
 
34
+#include <QObject>
34 35
 #include <QString>
35
-#include <QThread>
36
-#include <QWaitCondition>
37 36
 #include <QHash>
38
-#include <QMutex>
39 37
 #include "qtorrenthandle.h"
38
+#include <libtorrent/alert_types.hpp>
40 39
 
41 40
 class QBtSession;
42 41
 class SpeedSample;
43 42
 
44
-class TorrentSpeedMonitor : public QThread
43
+class TorrentSpeedMonitor : public QObject
45 44
 {
46
-  Q_OBJECT
45
+    Q_OBJECT
46
+    Q_DISABLE_COPY(TorrentSpeedMonitor)
47 47
 
48 48
 public:
49
-  explicit TorrentSpeedMonitor(QBtSession* session);
50
-  ~TorrentSpeedMonitor();
51
-  qlonglong getETA(const QString &hash) const;
52
-  quint64 getAlltimeDL() const;
53
-  quint64 getAlltimeUL() const;
54
-
55
-protected:
56
-  void run();
57
-
58
-private:
59
-  void getSamples();
60
-  void saveStats() const;
61
-  void loadStats();
49
+    explicit TorrentSpeedMonitor(QBtSession* session);
50
+    ~TorrentSpeedMonitor();
51
+    qlonglong getETA(const QString &hash, const libtorrent::torrent_status &status) const;
62 52
 
63 53
 private slots:
64
-  void removeSamples(const QString& hash);
65
-  void removeSamples(const QTorrentHandle& h);
54
+    void statsReceived(const libtorrent::stats_alert& stats);
55
+    void removeSamples(const QTorrentHandle& h);
66 56
 
67 57
 private:
68
-  bool m_abort;
69
-  QWaitCondition m_abortCond;
70
-  QHash<QString, SpeedSample> m_samples;
71
-  mutable QMutex m_mutex;
72
-  QBtSession *m_session;
73
-  // Will overflow at 15.9 EiB
74
-  quint64 alltimeUL;
75
-  quint64 alltimeDL;
76
-  qint64 sessionUL;
77
-  qint64 sessionDL;
78
-  mutable qint64 lastWrite;
79
-  mutable bool dirty;
58
+    QHash<QString, SpeedSample> m_samples;
59
+    QBtSession *m_session;
80 60
 };
81 61
 
82 62
 #endif // TORRENTSPEEDMONITOR_H

+ 100
- 0
src/libs/qtlibtorrent/torrentstatistics.cpp View File

@@ -0,0 +1,100 @@
1
+#include "torrentstatistics.h"
2
+
3
+#include <QDateTime>
4
+
5
+#include <libtorrent/session.hpp>
6
+
7
+#include "qbtsession.h"
8
+#include "qinisettings.h"
9
+#include "preferences.h"
10
+
11
+TorrentStatistics::TorrentStatistics(QBtSession* session, QObject* parent)
12
+    : QObject(parent)
13
+    , m_session(session)
14
+    , m_sessionUL(0)
15
+    , m_sessionDL(0)
16
+    , m_lastWrite(0)
17
+    , m_dirty(false)
18
+{
19
+    loadStats();
20
+    connect(&m_timer, SIGNAL(timeout()), this, SLOT(gatherStats()));
21
+    m_timer.start(60 * 1000);
22
+}
23
+
24
+TorrentStatistics::~TorrentStatistics() {
25
+    if (m_dirty)
26
+        m_lastWrite = 0;
27
+    saveStats();
28
+}
29
+
30
+quint64 TorrentStatistics::getAlltimeDL() const {
31
+    return m_alltimeDL + m_sessionDL;
32
+}
33
+
34
+quint64 TorrentStatistics::getAlltimeUL() const {
35
+    return m_alltimeUL + m_sessionUL;
36
+}
37
+
38
+void TorrentStatistics::gatherStats() {
39
+    libtorrent::session_status ss = m_session->getSessionStatus();
40
+    if (ss.total_download > m_sessionDL) {
41
+        m_sessionDL = ss.total_download;
42
+        m_dirty = true;
43
+    }
44
+    if (ss.total_upload > m_sessionUL) {
45
+        m_sessionUL = ss.total_upload;
46
+        m_dirty = true;
47
+    }
48
+
49
+    saveStats();
50
+}
51
+
52
+void TorrentStatistics::saveStats() const {
53
+    if (!(m_dirty && (QDateTime::currentMSecsSinceEpoch() - m_lastWrite >= 15*60*1000) ))
54
+        return;
55
+    QIniSettings s("pcode", "nodecast-data");
56
+    QVariantHash v;
57
+    v.insert("AlltimeDL", m_alltimeDL + m_sessionDL);
58
+    v.insert("AlltimeUL", m_alltimeUL + m_sessionUL);
59
+    s.setValue("Stats/AllStats", v);
60
+    m_dirty = false;
61
+    m_lastWrite = QDateTime::currentMSecsSinceEpoch();
62
+}
63
+
64
+void TorrentStatistics::loadStats() {
65
+    // Temp code. Versions v3.1.4 and v3.1.5 saved the data in the nodecast.ini file.
66
+    // This code reads the data from there, writes it to the new file, and removes the keys
67
+    // from the old file. This code should be removed after some time has passed.
68
+    // e.g. When we reach v3.3.0
69
+    // Don't forget to remove:
70
+    // 1. Preferences::getStats()
71
+    // 2. Preferences::removeStats()
72
+    // 3. #include "preferences.h"
73
+    Preferences* const pref = Preferences::instance();
74
+    QIniSettings s("pcode", "nodecast-data");
75
+    QVariantHash v = pref->getStats();
76
+
77
+    // Let's test if the nodecast.ini holds the key
78
+    if (!v.isEmpty()) {
79
+        m_dirty = true;
80
+
81
+        // If the user has used qbt > 3.1.5 and then reinstalled/used
82
+        // qbt < 3.1.6, there will be stats in nodecast-data.ini too
83
+        // so we need to merge those 2.
84
+        if (s.contains("Stats/AllStats")) {
85
+            QVariantHash tmp = s.value("Stats/AllStats").toHash();
86
+            v["AlltimeDL"] = v["AlltimeDL"].toULongLong() + tmp["AlltimeDL"].toULongLong();
87
+            v["AlltimeUL"] = v["AlltimeUL"].toULongLong() + tmp["AlltimeUL"].toULongLong();
88
+        }
89
+    }
90
+    else
91
+        v = s.value("Stats/AllStats").toHash();
92
+
93
+    m_alltimeDL = v["AlltimeDL"].toULongLong();
94
+    m_alltimeUL = v["AlltimeUL"].toULongLong();
95
+
96
+    if (m_dirty) {
97
+        saveStats();
98
+        pref->removeStats();
99
+    }
100
+}

+ 41
- 0
src/libs/qtlibtorrent/torrentstatistics.h View File

@@ -0,0 +1,41 @@
1
+#ifndef TORRENTSTATISTICS_H
2
+#define TORRENTSTATISTICS_H
3
+
4
+#include <QObject>
5
+#include <QTimer>
6
+
7
+class QBtSession;
8
+
9
+class TorrentStatistics : QObject
10
+{
11
+    Q_OBJECT
12
+    Q_DISABLE_COPY(TorrentStatistics)
13
+
14
+public:
15
+    TorrentStatistics(QBtSession* session, QObject* parent = 0);
16
+    ~TorrentStatistics();
17
+
18
+    quint64 getAlltimeDL() const;
19
+    quint64 getAlltimeUL() const;
20
+
21
+private slots:
22
+    void gatherStats();
23
+
24
+private:
25
+    void saveStats() const;
26
+    void loadStats();
27
+
28
+private:
29
+    QBtSession* m_session;
30
+    // Will overflow at 15.9 EiB
31
+    quint64 m_alltimeUL;
32
+    quint64 m_alltimeDL;
33
+    qint64 m_sessionUL;
34
+    qint64 m_sessionDL;
35
+    mutable qint64 m_lastWrite;
36
+    mutable bool m_dirty;
37
+
38
+    QTimer m_timer;
39
+};
40
+
41
+#endif // TORRENTSTATISTICS_H

+ 2
- 1
src/libs/tracker/qtracker.cpp View File

@@ -71,6 +71,7 @@ QTracker::QTracker(QObject *parent)
71 71
     : Http::ResponseBuilder(parent)
72 72
     , m_server(new Http::Server(this, this))
73 73
 {
74
+    qDebug() << "TRACKER LAUNCH";
74 75
 }
75 76
 
76 77
 QTracker::~QTracker()
@@ -82,7 +83,7 @@ QTracker::~QTracker()
82 83
 
83 84
 bool QTracker::start()
84 85
 {
85
-    const int listen_port = Preferences().getTrackerPort();
86
+    const int listen_port = Preferences::instance()->getTrackerPort();
86 87
     qDebug() << "TRACKER LISTEN PORT : " << listen_port;
87 88
 
88 89
     if (m_server->isListening()) {

+ 127
- 0
src/logger.cpp View File

@@ -0,0 +1,127 @@
1
+#include "logger.h"
2
+
3
+#include <QDateTime>
4
+
5
+namespace Log
6
+{
7
+    Msg::Msg() {}
8
+
9
+    Msg::Msg(int id, MsgType type, const QString &message)
10
+        : id(id)
11
+        , timestamp(QDateTime::currentMSecsSinceEpoch())
12
+        , type(type)
13
+        , message(message)
14
+    {
15
+    }
16
+
17
+    Peer::Peer() {}
18
+
19
+#if LIBTORRENT_VERSION_NUM < 10000
20
+    Peer::Peer(int id, const QString &ip, bool blocked)
21
+#else
22
+    Peer::Peer(int id, const QString &ip, bool blocked, const QString &reason)
23
+#endif
24
+        : id(id)
25
+        , timestamp(QDateTime::currentMSecsSinceEpoch())
26
+        , ip(ip)
27
+        , blocked(blocked)
28
+#if LIBTORRENT_VERSION_NUM >= 10000
29
+        , reason(reason)
30
+#endif
31
+    {
32
+    }
33
+
34
+}
35
+
36
+Logger* Logger::m_instance = 0;
37
+
38
+Logger::Logger()
39
+    : lock(QReadWriteLock::Recursive)
40
+    , msgCounter(0)
41
+    , peerCounter(0)
42
+{
43
+}
44
+
45
+Logger::~Logger() {}
46
+
47
+Logger * Logger::instance()
48
+{
49
+    if (!m_instance)
50
+        m_instance = new Logger;
51
+
52
+    return m_instance;
53
+}
54
+
55
+void Logger::drop()
56
+{
57
+    if (m_instance) {
58
+        delete m_instance;
59
+        m_instance = 0;
60
+    }
61
+}
62
+
63
+void Logger::addMessage(const QString &message, const Log::MsgType &type)
64
+{
65
+    QWriteLocker locker(&lock);
66
+
67
+    Log::Msg temp(msgCounter++, type, message);
68
+    m_messages.push_back(temp);
69
+
70
+    if (m_messages.size() >= MAX_LOG_MESSAGES)
71
+        m_messages.pop_front();
72
+
73
+    emit newLogMessage(temp);
74
+}
75
+
76
+#if LIBTORRENT_VERSION_NUM < 10000
77
+void Logger::addPeer(const QString &ip, bool blocked)
78
+#else
79
+void Logger::addPeer(const QString &ip, bool blocked, const QString &reason)
80
+#endif
81
+{
82
+    QWriteLocker locker(&lock);
83
+
84
+#if LIBTORRENT_VERSION_NUM < 10000
85
+    Log::Peer temp(peerCounter++, ip, blocked);
86
+#else
87
+    Log::Peer temp(peerCounter++, ip, blocked, reason);
88
+#endif
89
+    m_peers.push_back(temp);
90
+
91
+    if (m_peers.size() >= MAX_LOG_MESSAGES)
92
+        m_peers.pop_front();
93
+
94
+    emit newLogPeer(temp);
95
+}
96
+
97
+QVector<Log::Msg> Logger::getMessages(int lastKnownId) const
98
+{
99
+    QReadLocker locker(&lock);
100
+
101
+    int diff = msgCounter - lastKnownId - 1;
102
+    int size = m_messages.size();
103
+
104
+    if ((lastKnownId == -1) || (diff >= size))
105
+        return m_messages;
106
+
107
+    if (diff <= 0)
108
+        return QVector<Log::Msg>();
109
+
110
+    return m_messages.mid(size - diff);
111
+}
112
+
113
+QVector<Log::Peer> Logger::getPeers(int lastKnownId) const
114
+{
115
+    QReadLocker locker(&lock);
116
+
117
+    int diff = peerCounter - lastKnownId - 1;
118
+    int size = m_peers.size();
119
+
120
+    if ((lastKnownId == -1) || (diff >= size))
121
+        return m_peers;
122
+
123
+    if (diff <= 0)
124
+        return QVector<Log::Peer>();
125
+
126
+    return m_peers.mid(size - diff);
127
+}

+ 83
- 0
src/logger.h View File

@@ -0,0 +1,83 @@
1
+#ifndef LOGGER_H
2
+#define LOGGER_H
3
+
4
+#include <QString>
5
+#include <QVector>
6
+#include <QReadWriteLock>
7
+#include <QObject>
8
+#include <libtorrent/version.hpp>
9
+
10
+const int MAX_LOG_MESSAGES = 1000;
11
+
12
+namespace Log
13
+{
14
+    enum MsgType
15
+    {
16
+        NORMAL,
17
+        INFO,
18
+        WARNING,
19
+        CRITICAL //ERROR is defined by libtorrent and results in compiler error
20
+    };
21
+
22
+    struct Msg
23
+    {
24
+        Msg();
25
+        Msg(int id, MsgType type, const QString &message);
26
+        int id;
27
+        qint64 timestamp;
28
+        MsgType type;
29
+        QString message;
30
+    };
31
+
32
+    struct Peer
33
+    {
34
+#if LIBTORRENT_VERSION_NUM < 10000
35
+        Peer(int id, const QString &ip, bool blocked);
36
+#else
37
+        Peer(int id, const QString &ip, bool blocked, const QString &reason);
38
+#endif
39
+        Peer();
40
+        int id;
41
+        qint64 timestamp;
42
+        QString ip;
43
+        bool blocked;
44
+#if LIBTORRENT_VERSION_NUM >= 10000
45
+        QString reason;
46
+#endif
47
+    };
48
+}
49
+
50
+class Logger : public QObject
51
+{
52
+    Q_OBJECT
53
+    Q_DISABLE_COPY(Logger)
54
+
55
+public:
56
+    static Logger* instance();
57
+    static void drop();
58
+    ~Logger();
59
+
60
+    void addMessage(const QString &message, const Log::MsgType &type = Log::NORMAL);
61
+#if LIBTORRENT_VERSION_NUM < 10000
62
+    void addPeer(const QString &ip, bool blocked);
63
+#else
64
+    void addPeer(const QString &ip, bool blocked, const QString &reason = QString());
65
+#endif
66
+    QVector<Log::Msg> getMessages(int lastKnownId = -1) const;
67
+    QVector<Log::Peer> getPeers(int lastKnownId = -1) const;
68
+
69
+signals:
70
+    void newLogMessage(const Log::Msg &message);
71
+    void newLogPeer(const Log::Peer &peer);
72
+
73
+private:
74
+    Logger();
75
+    static Logger* m_instance;
76
+    QVector<Log::Msg> m_messages;
77
+    QVector<Log::Peer> m_peers;
78
+    mutable QReadWriteLock lock;
79
+    int msgCounter;
80
+    int peerCounter;
81
+};
82
+
83
+#endif // LOGGER_H

+ 96
- 0
src/loglistwidget.cpp View File

@@ -0,0 +1,96 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2011  Christophe Dumez
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to
20
+ * link this program with the OpenSSL project's "OpenSSL" library (or with
21
+ * modified versions of it that use the same license as the "OpenSSL" library),
22
+ * and distribute the linked executables. You must obey the GNU General Public
23
+ * License in all respects for all of the code used other than "OpenSSL".  If you
24
+ * modify file(s), you may extend this exception to your version of the file(s),
25
+ * but you are not obligated to do so. If you do not wish to do so, delete this
26
+ * exception statement from your version.
27
+ *
28
+ * Contact : chris@qbittorrent.org
29
+ */
30
+#include <QKeyEvent>
31
+#include <QApplication>
32
+#include <QClipboard>
33
+#include <QListWidgetItem>
34
+#include <QLabel>
35
+#include <QRegExp>
36
+#include <QAction>
37
+#include "loglistwidget.h"
38
+#include "iconprovider.h"
39
+
40
+LogListWidget::LogListWidget(int max_lines, QWidget *parent) :
41
+  QListWidget(parent),
42
+  m_maxLines(max_lines)
43
+{
44
+  // Allow multiple selections
45
+  setSelectionMode(QAbstractItemView::ExtendedSelection);
46
+  // Context menu
47
+  QAction *copyAct = new QAction(IconProvider::instance()->getIcon("edit-copy"), tr("Copy"), this);
48
+  QAction *clearAct = new QAction(IconProvider::instance()->getIcon("edit-clear"), tr("Clear"), this);
49
+  connect(copyAct, SIGNAL(triggered()), SLOT(copySelection()));
50
+  connect(clearAct, SIGNAL(triggered()), SLOT(clearLog()));
51
+  addAction(copyAct);
52
+  addAction(clearAct);
53
+  setContextMenuPolicy(Qt::ActionsContextMenu);
54
+}
55
+
56
+void LogListWidget::keyPressEvent(QKeyEvent *event)
57
+{
58
+  if (event->matches(QKeySequence::Copy)) {
59
+    copySelection();
60
+    return;
61
+  }
62
+  if (event->matches(QKeySequence::SelectAll)) {
63
+    selectAll();
64
+    return;
65
+  }
66
+}
67
+
68
+void LogListWidget::appendLine(const QString &line)
69
+{
70
+  QListWidgetItem *item = new QListWidgetItem;
71
+  // We need to use QLabel here to support rich text
72
+  QLabel *lbl = new QLabel(line);
73
+  lbl->setContentsMargins(4, 2, 4, 2);
74
+  item->setSizeHint(lbl->sizeHint());
75
+  insertItem(0, item);
76
+  setItemWidget(item, lbl);
77
+  const int nbLines = count();
78
+  // Limit log size
79
+  if (nbLines > m_maxLines)
80
+    delete takeItem(nbLines - 1);
81
+}
82
+
83
+void LogListWidget::copySelection()
84
+{
85
+  static QRegExp html_tag("<[^>]+>");
86
+  QList<QListWidgetItem*> items = selectedItems();
87
+  QStringList strings;
88
+  foreach (QListWidgetItem* it, items)
89
+    strings << static_cast<QLabel*>(itemWidget(it))->text().replace(html_tag, "");
90
+
91
+  QApplication::clipboard()->setText(strings.join("\n"));
92
+}
93
+
94
+void LogListWidget::clearLog() {
95
+  clear();
96
+}

+ 61
- 0
src/loglistwidget.h View File

@@ -0,0 +1,61 @@
1
+/*
2
+ * Bittorrent Client using Qt4 and libtorrent.
3
+ * Copyright (C) 2011  Christophe Dumez
4
+ *
5
+ * This program is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU General Public License
7
+ * as published by the Free Software Foundation; either version 2
8
+ * of the License, or (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18
+ *
19
+ * In addition, as a special exception, the copyright holders give permission to