You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-11-14 03:17:38 +01:00
Compare commits
17 Commits
release-1.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d02298c7d2 | ||
|
|
e5f9c5b746 | ||
|
|
96f9add49a | ||
|
|
2b9f0ae94f | ||
|
|
76c5c63b50 | ||
|
|
aed4c1f5a4 | ||
|
|
d4fe27e436 | ||
|
|
14567b85bd | ||
|
|
1a5cd45dfc | ||
|
|
a7850a4305 | ||
|
|
02c9b06c77 | ||
|
|
94a8c88bd9 | ||
|
|
7a7fca0d0c | ||
|
|
9dbc3a1540 | ||
|
|
407c384494 | ||
|
|
833f1d8c6a | ||
|
|
51dcd6c93c |
16
Changelog
16
Changelog
@@ -1,3 +1,19 @@
|
||||
* Tue Nov 17 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.6
|
||||
- BUGFIX: RSS feed articles can now be displayed using keyboard arrows
|
||||
- BUGFIX: RSS feed downloader can only process unread articles now
|
||||
- BUGFIX: Fixed memory leak in RSS parser
|
||||
- BUGFIX: Fixed possible crash in search autocompletion
|
||||
- BUGFIX: Improved ETA calculation for big torrents
|
||||
- BUGFIX: Fixed per-torrent speed limiting
|
||||
|
||||
* Wed Nov 4 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.5
|
||||
- BUGFIX: Fixed man page
|
||||
- BUGFIX: Fix crash on torrent addition (if libtorrent-rasterbar has debug enabled)
|
||||
- BUGFIX: Fix trackers addition to torrents (bug introduced in v1.5.4)
|
||||
- BUGFIX: Suppress compilation warning regarding sortNewsList() not being used
|
||||
- BUGFIX: Make sure scan folder is different than qBittorrent backup directory to avoid torrents deletion
|
||||
- BUGFIX: Added safety mecanism which adds the torrents back to the list in case qbittorrent-resume.conf gets deleted or corrupted.
|
||||
|
||||
* Sun Oct 25 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.4
|
||||
- BUGFIX: Updated man page
|
||||
- BUGFIX: Fixed possible crash with torrents containing unicode characters
|
||||
|
||||
9
INSTALL
9
INSTALL
@@ -1,12 +1,6 @@
|
||||
qBittorrent - A BitTorrent client in C++ / Qt4
|
||||
------------------------------------------
|
||||
|
||||
*** Necessary if qt3 is default on your system ***
|
||||
export QTDIR=/usr/include/qt4
|
||||
export PATH=$QTDIR/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib
|
||||
*** End ***
|
||||
|
||||
./configure
|
||||
make && make install
|
||||
qbittorrent
|
||||
@@ -28,9 +22,6 @@ Dependencies:
|
||||
|
||||
- python >= 2.3 (needed by search engine)
|
||||
|
||||
- libmagick++ (advised, not required)
|
||||
* Needed for favicons support (RSS / Search plugins)
|
||||
|
||||
- libzzip (advised, not required)
|
||||
* Needed for zip support (Search plugins)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ qBittorrent \- a Bittorrent client written in C++ / Qt4
|
||||
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
\fBqbittorrent\fR [--no-splash] [TORRENT_FILE | URL]...
|
||||
\fBqbittorrent\fR [\-\-no-splash] [TORRENT_FILE | URL]...
|
||||
|
||||
\fBqbittorrent\fR \-\-help
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Comment=V1.5.4
|
||||
Comment=V1.5.6
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[bg]=Торент клиент
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,8 @@
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
#define MAX_SAMPLES 20
|
||||
|
||||
class downloadThread;
|
||||
class QTimer;
|
||||
class QFileSystemWatcher;
|
||||
@@ -77,6 +79,8 @@ class bittorrent : public QObject {
|
||||
bool queueingEnabled;
|
||||
QStringList url_skippingDlg;
|
||||
QHash<QString, QString> savepath_fromurl;
|
||||
QPointer<QTimer> timerETA;
|
||||
QHash<QString, QList<int> > ETA_samples;
|
||||
|
||||
protected:
|
||||
QString getSavePath(QString hash);
|
||||
@@ -107,7 +111,7 @@ class bittorrent : public QObject {
|
||||
int loadTorrentPriority(QString hash);
|
||||
QStringList getConsoleMessages() const;
|
||||
QStringList getPeerBanMessages() const;
|
||||
qlonglong getETA(QString hash) const;
|
||||
qlonglong getETA(QString hash);
|
||||
bool useTemporaryFolder() const;
|
||||
QString getDefaultSavePath() const;
|
||||
|
||||
@@ -177,6 +181,7 @@ class bittorrent : public QObject {
|
||||
void readAlerts();
|
||||
void loadTrackerFile(QString hash);
|
||||
void deleteBigRatios();
|
||||
void takeETASamples();
|
||||
|
||||
signals:
|
||||
void addedTorrent(QTorrentHandle& h);
|
||||
|
||||
@@ -605,10 +605,10 @@ bool DownloadingTorrents::updateTorrent(QTorrentHandle h) {
|
||||
}
|
||||
if(!downloadList->isColumnHidden(SEEDSLEECH)) {
|
||||
QString tmp = misc::toQString(h.num_seeds(), true);
|
||||
if(h.num_complete() >= 0)
|
||||
if(h.num_complete() >= h.num_seeds())
|
||||
tmp.append(QString("(")+misc::toQString(h.num_complete())+QString(")"));
|
||||
tmp.append(QString("/")+misc::toQString(h.num_peers() - h.num_seeds(), true));
|
||||
if(h.num_incomplete() >= 0)
|
||||
if(h.num_incomplete() >= (h.num_peers()-h.num_seeds()))
|
||||
tmp.append(QString("(")+misc::toQString(h.num_incomplete())+QString(")"));
|
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(tmp));
|
||||
}
|
||||
|
||||
@@ -163,11 +163,6 @@ QString QTorrentHandle::save_path() const {
|
||||
return misc::toQString(h.save_path().string());
|
||||
}
|
||||
|
||||
fs::path QTorrentHandle::save_path_boost() const {
|
||||
Q_ASSERT(h.is_valid());
|
||||
return h.save_path();
|
||||
}
|
||||
|
||||
QStringList QTorrentHandle::url_seeds() const {
|
||||
Q_ASSERT(h.is_valid());
|
||||
QStringList res;
|
||||
@@ -234,9 +229,9 @@ size_type QTorrentHandle::filesize_at(unsigned int index) const {
|
||||
return h.get_torrent_info().file_at(index).size;
|
||||
}
|
||||
|
||||
std::vector<announce_entry> const& QTorrentHandle::trackers() const {
|
||||
std::vector<announce_entry> QTorrentHandle::trackers() const {
|
||||
Q_ASSERT(h.is_valid());
|
||||
return h.get_torrent_info().trackers();
|
||||
return h.trackers();
|
||||
}
|
||||
|
||||
torrent_status::state_t QTorrentHandle::state() const {
|
||||
|
||||
@@ -81,7 +81,6 @@ class QTorrentHandle {
|
||||
int num_incomplete() const;
|
||||
void scrape_tracker() const;
|
||||
QString save_path() const;
|
||||
fs::path save_path_boost() const;
|
||||
QStringList url_seeds() const;
|
||||
size_type actual_size() const;
|
||||
int download_limit() const;
|
||||
@@ -93,7 +92,7 @@ class QTorrentHandle {
|
||||
bool is_queued() const;
|
||||
QString file_at(unsigned int index) const;
|
||||
size_type filesize_at(unsigned int index) const;
|
||||
std::vector<announce_entry> const& trackers() const;
|
||||
std::vector<announce_entry> trackers() const;
|
||||
torrent_status::state_t state() const;
|
||||
QString creator() const;
|
||||
QString comment() const;
|
||||
|
||||
47
src/rss.cpp
47
src/rss.cpp
@@ -561,29 +561,38 @@ short RssStream::readDoc(const QDomDocument& doc) {
|
||||
image = property.text();
|
||||
else if(property.tagName() == "item") {
|
||||
RssItem * item = new RssItem(this, property);
|
||||
if(item->isValid() && !itemAlreadyExists(item->getTitle())) {
|
||||
(*this)[item->getTitle()] = item;
|
||||
if(item->isValid()) {
|
||||
QString title = item->getTitle();
|
||||
bool already_exists = itemAlreadyExists(title);
|
||||
if(!already_exists) {
|
||||
(*this)[title] = item;
|
||||
} else {
|
||||
delete item;
|
||||
item = this->value(title);
|
||||
}
|
||||
if(item->has_attachment()) {
|
||||
has_attachments = true;
|
||||
// Check if the item should be automatically downloaded
|
||||
FeedFilter * matching_filter = FeedFilters::getFeedFilters(url).matches(item->getTitle());
|
||||
if(matching_filter != 0) {
|
||||
// Download the torrent
|
||||
BTSession->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->getTitle()).arg(getName()));
|
||||
if(matching_filter->isValid()) {
|
||||
QString save_path = matching_filter->getSavePath();
|
||||
if(save_path.isEmpty())
|
||||
if(!already_exists || !(*this)[item->getTitle()]->isRead()) {
|
||||
FeedFilter * matching_filter = FeedFilters::getFeedFilters(url).matches(item->getTitle());
|
||||
if(matching_filter != 0) {
|
||||
// Download the torrent
|
||||
BTSession->addConsoleMessage(tr("Automatically downloading %1 torrent from %2 RSS feed...").arg(item->getTitle()).arg(getName()));
|
||||
if(matching_filter->isValid()) {
|
||||
QString save_path = matching_filter->getSavePath();
|
||||
if(save_path.isEmpty())
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
|
||||
else
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl(), save_path);
|
||||
} else {
|
||||
// All torrents are downloaded from this feed
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
|
||||
else
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl(), save_path);
|
||||
} else {
|
||||
// All torrents are downloaded from this feed
|
||||
BTSession->downloadUrlAndSkipDialog(item->getTorrentUrl());
|
||||
}
|
||||
// Item was downloaded, consider it as Read
|
||||
(*this)[item->getTitle()]->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
}
|
||||
// Item was downloaded, consider it as Read
|
||||
item->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -604,7 +613,7 @@ void RssStream::resizeList() {
|
||||
unsigned int max_articles = settings.value(QString::fromUtf8("Preferences/RSS/RSSMaxArticlesPerFeed"), 100).toInt();
|
||||
unsigned int nb_articles = this->size();
|
||||
if(nb_articles > max_articles) {
|
||||
QList<RssItem*> listItem = sortNewsList(this->values());
|
||||
QList<RssItem*> listItem = RssManager::sortNewsList(this->values());
|
||||
int excess = nb_articles - max_articles;
|
||||
for(int i=0; i<excess; ++i){
|
||||
RssItem *lastItem = listItem.takeLast();
|
||||
|
||||
30
src/rss.h
30
src/rss.h
@@ -492,23 +492,25 @@ public slots:
|
||||
public:
|
||||
RssManager(bittorrent *BTSession);
|
||||
~RssManager();
|
||||
static void insertSortElem(QList<RssItem*> &list, RssItem *item) {
|
||||
int i = 0;
|
||||
while(i < list.size() && item->getDate() < list.at(i)->getDate()) {
|
||||
++i;
|
||||
}
|
||||
list.insert(i, item);
|
||||
}
|
||||
|
||||
static QList<RssItem*> sortNewsList(QList<RssItem*> news_list) {
|
||||
QList<RssItem*> new_list;
|
||||
foreach(RssItem *item, news_list) {
|
||||
insertSortElem(new_list, item);
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void insertSortElem(QList<RssItem*> &list, RssItem *item) {
|
||||
int i = 0;
|
||||
while(i < list.size() && item->getDate() < list.at(i)->getDate()) {
|
||||
++i;
|
||||
}
|
||||
list.insert(i, item);
|
||||
}
|
||||
|
||||
static QList<RssItem*> sortNewsList(QList<RssItem*> news_list) {
|
||||
QList<RssItem*> new_list;
|
||||
foreach(RssItem *item, news_list) {
|
||||
insertSortElem(new_list, item);
|
||||
}
|
||||
return new_list;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -431,9 +431,9 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
|
||||
qDebug("Getting the list of news");
|
||||
QList<RssItem*> news;
|
||||
if(rss_item == rssmanager)
|
||||
news = sortNewsList(rss_item->getUnreadNewsList());
|
||||
news = RssManager::sortNewsList(rss_item->getUnreadNewsList());
|
||||
else
|
||||
news = sortNewsList(rss_item->getNewsList());
|
||||
news = RssManager::sortNewsList(rss_item->getNewsList());
|
||||
// Clear the list first
|
||||
textBrowser->clear();
|
||||
previous_news = 0;
|
||||
@@ -460,8 +460,11 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
|
||||
}
|
||||
|
||||
// display a news
|
||||
void RSSImp::refreshTextBrowser(QTreeWidgetItem *item) {
|
||||
if(!item || item == previous_news) return;
|
||||
void RSSImp::refreshTextBrowser() {
|
||||
QList<QTreeWidgetItem*> selection = listNews->selectedItems();
|
||||
if(selection.empty()) return;
|
||||
QTreeWidgetItem *item = selection.first();
|
||||
if(item == previous_news) return;
|
||||
// Stop displaying previous news if necessary
|
||||
if(listStreams->currentFeed() == listStreams->getUnreadItem()) {
|
||||
if(previous_news) {
|
||||
@@ -596,7 +599,7 @@ RSSImp::RSSImp(bittorrent *BTSession) : QWidget(), BTSession(BTSession){
|
||||
connect(listStreams, SIGNAL(foldersAltered(QList<QTreeWidgetItem*>)), this, SLOT(updateItemsInfos(QList<QTreeWidgetItem*>)));
|
||||
connect(listStreams, SIGNAL(overwriteAttempt(QString)), this, SLOT(displayOverwriteError(QString)));
|
||||
|
||||
connect(listNews, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(refreshTextBrowser(QTreeWidgetItem *)));
|
||||
connect(listNews, SIGNAL(itemSelectionChanged()), this, SLOT(refreshTextBrowser()));
|
||||
connect(listNews, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(downloadTorrent()));
|
||||
|
||||
// Refresh all feeds
|
||||
|
||||
@@ -63,7 +63,7 @@ protected slots:
|
||||
void refreshSelectedItems();
|
||||
void copySelectedFeedsURL();
|
||||
void refreshNewsList(QTreeWidgetItem* item);
|
||||
void refreshTextBrowser(QTreeWidgetItem *);
|
||||
void refreshTextBrowser();
|
||||
void updateFeedIcon(QString url, QString icon_path);
|
||||
void updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread);
|
||||
void updateItemsInfos(QList<QTreeWidgetItem*> items);
|
||||
|
||||
@@ -57,7 +57,6 @@ SearchEngine::SearchEngine(bittorrent *BTSession, QSystemTrayIcon *myTrayIcon, b
|
||||
setupUi(this);
|
||||
// new qCompleter to the search pattern
|
||||
startSearchHistory();
|
||||
searchCompleter = 0;
|
||||
createCompleter();
|
||||
// Add close tab button
|
||||
closeTab_button = new QPushButton();
|
||||
@@ -142,8 +141,7 @@ void SearchEngine::displayPatternContextMenu(QPoint) {
|
||||
QAction *act = myMenu.exec(QCursor::pos());
|
||||
if(act != 0) {
|
||||
if(act == &clearHistoryAct) {
|
||||
searchHistory.clear();
|
||||
createCompleter();
|
||||
searchHistory.setStringList(QStringList());
|
||||
} else if (act == &pasteAct) {
|
||||
} else if (act == &pasteAct) {
|
||||
search_pattern->paste();
|
||||
@@ -181,18 +179,13 @@ void SearchEngine::on_enginesButton_clicked() {
|
||||
// get the last searchs from a QSettings to a QStringList
|
||||
void SearchEngine::startSearchHistory(){
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.beginGroup("Search");
|
||||
searchHistory = settings.value("searchHistory",-1).toStringList();
|
||||
settings.endGroup();
|
||||
searchHistory.setStringList(settings.value("Search/searchHistory",QStringList()).toStringList());
|
||||
}
|
||||
|
||||
// Save the history list into the QSettings for the next session
|
||||
void SearchEngine::saveSearchHistory()
|
||||
{
|
||||
void SearchEngine::saveSearchHistory() {
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.beginGroup("Search");
|
||||
settings.setValue("searchHistory",searchHistory);
|
||||
settings.endGroup();
|
||||
settings.setValue("Search/searchHistory",searchHistory.stringList());
|
||||
}
|
||||
|
||||
// Function called when we click on search button
|
||||
@@ -220,13 +213,14 @@ void SearchEngine::on_search_button_clicked(){
|
||||
tabWidget->setCurrentWidget(currentSearchTab);
|
||||
closeTab_button->setEnabled(true);
|
||||
// if the pattern is not in the pattern
|
||||
if(searchHistory.indexOf(pattern) == -1){
|
||||
QStringList wordList = searchHistory.stringList();
|
||||
if(wordList.indexOf(pattern) == -1){
|
||||
//update the searchHistory list
|
||||
searchHistory.append(pattern);
|
||||
wordList.append(pattern);
|
||||
// verify the max size of the history
|
||||
if(searchHistory.size() > SEARCHHISTORY_MAXSIZE)
|
||||
searchHistory = searchHistory.mid(searchHistory.size()/2,searchHistory.size()/2);
|
||||
createCompleter();
|
||||
if(wordList.size() > SEARCHHISTORY_MAXSIZE)
|
||||
wordList = wordList.mid(wordList.size()/2);
|
||||
searchHistory.setStringList(wordList);
|
||||
}
|
||||
|
||||
// Getting checked search engines
|
||||
@@ -252,7 +246,7 @@ void SearchEngine::on_search_button_clicked(){
|
||||
void SearchEngine::createCompleter() {
|
||||
if(searchCompleter)
|
||||
delete searchCompleter;
|
||||
searchCompleter = new QCompleter(searchHistory, this);
|
||||
searchCompleter = new QCompleter(&searchHistory);
|
||||
searchCompleter->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
search_pattern->setCompleter(searchCompleter);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QPointer>
|
||||
#include <QStringListModel>
|
||||
#include "ui_search.h"
|
||||
#include "engineSelectDlg.h"
|
||||
#include "SearchTab.h"
|
||||
@@ -60,7 +61,7 @@ private:
|
||||
QByteArray search_result_line_truncated;
|
||||
unsigned long nb_search_results;
|
||||
QPointer<QCompleter> searchCompleter;
|
||||
QStringList searchHistory;
|
||||
QStringListModel searchHistory;
|
||||
bittorrent *BTSession;
|
||||
QSystemTrayIcon *myTrayIcon;
|
||||
bool systrayIntegration;
|
||||
|
||||
@@ -14,10 +14,10 @@ CONFIG += qt \
|
||||
network
|
||||
|
||||
# Update this VERSION for each release
|
||||
DEFINES += VERSION=\\\"v1.5.4\\\"
|
||||
DEFINES += VERSION=\\\"v1.5.6\\\"
|
||||
DEFINES += VERSION_MAJOR=1
|
||||
DEFINES += VERSION_MINOR=5
|
||||
DEFINES += VERSION_BUGFIX=4
|
||||
DEFINES += VERSION_BUGFIX=6
|
||||
!mac:QMAKE_LFLAGS += -Wl,--as-needed
|
||||
contains(DEBUG_MODE, 1) {
|
||||
CONFIG += debug
|
||||
|
||||
Reference in New Issue
Block a user