You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-10-16 20:32:23 +02:00
Compare commits
1 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3783b11e98 |
16
Changelog
16
Changelog
@@ -1,19 +1,3 @@
|
||||
* 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,6 +1,12 @@
|
||||
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
|
||||
@@ -22,6 +28,9 @@ 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.6
|
||||
Comment=V1.5.4
|
||||
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,8 +42,6 @@
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
#define MAX_SAMPLES 20
|
||||
|
||||
class downloadThread;
|
||||
class QTimer;
|
||||
class QFileSystemWatcher;
|
||||
@@ -79,8 +77,6 @@ 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);
|
||||
@@ -111,7 +107,7 @@ class bittorrent : public QObject {
|
||||
int loadTorrentPriority(QString hash);
|
||||
QStringList getConsoleMessages() const;
|
||||
QStringList getPeerBanMessages() const;
|
||||
qlonglong getETA(QString hash);
|
||||
qlonglong getETA(QString hash) const;
|
||||
bool useTemporaryFolder() const;
|
||||
QString getDefaultSavePath() const;
|
||||
|
||||
@@ -181,7 +177,6 @@ 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() >= h.num_seeds())
|
||||
if(h.num_complete() >= 0)
|
||||
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() >= (h.num_peers()-h.num_seeds()))
|
||||
if(h.num_incomplete() >= 0)
|
||||
tmp.append(QString("(")+misc::toQString(h.num_incomplete())+QString(")"));
|
||||
DLListModel->setData(DLListModel->index(row, SEEDSLEECH), QVariant(tmp));
|
||||
}
|
||||
|
@@ -163,6 +163,11 @@ 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;
|
||||
@@ -229,9 +234,9 @@ size_type QTorrentHandle::filesize_at(unsigned int index) const {
|
||||
return h.get_torrent_info().file_at(index).size;
|
||||
}
|
||||
|
||||
std::vector<announce_entry> QTorrentHandle::trackers() const {
|
||||
std::vector<announce_entry> const& QTorrentHandle::trackers() const {
|
||||
Q_ASSERT(h.is_valid());
|
||||
return h.trackers();
|
||||
return h.get_torrent_info().trackers();
|
||||
}
|
||||
|
||||
torrent_status::state_t QTorrentHandle::state() const {
|
||||
|
@@ -81,6 +81,7 @@ 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;
|
||||
@@ -92,7 +93,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> trackers() const;
|
||||
std::vector<announce_entry> const& trackers() const;
|
||||
torrent_status::state_t state() const;
|
||||
QString creator() const;
|
||||
QString comment() const;
|
||||
|
47
src/rss.cpp
47
src/rss.cpp
@@ -561,38 +561,29 @@ short RssStream::readDoc(const QDomDocument& doc) {
|
||||
image = property.text();
|
||||
else if(property.tagName() == "item") {
|
||||
RssItem * item = new RssItem(this, property);
|
||||
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->isValid() && !itemAlreadyExists(item->getTitle())) {
|
||||
(*this)[item->getTitle()] = item;
|
||||
if(item->has_attachment()) {
|
||||
has_attachments = true;
|
||||
// Check if the item should be automatically downloaded
|
||||
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
|
||||
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());
|
||||
}
|
||||
// Item was downloaded, consider it as Read
|
||||
(*this)[item->getTitle()]->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
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
|
||||
item->setRead();
|
||||
// Clean up
|
||||
delete matching_filter;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -613,7 +604,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 = RssManager::sortNewsList(this->values());
|
||||
QList<RssItem*> listItem = 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,25 +492,23 @@ 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 = RssManager::sortNewsList(rss_item->getUnreadNewsList());
|
||||
news = sortNewsList(rss_item->getUnreadNewsList());
|
||||
else
|
||||
news = RssManager::sortNewsList(rss_item->getNewsList());
|
||||
news = sortNewsList(rss_item->getNewsList());
|
||||
// Clear the list first
|
||||
textBrowser->clear();
|
||||
previous_news = 0;
|
||||
@@ -460,11 +460,8 @@ void RSSImp::refreshNewsList(QTreeWidgetItem* item) {
|
||||
}
|
||||
|
||||
// display a news
|
||||
void RSSImp::refreshTextBrowser() {
|
||||
QList<QTreeWidgetItem*> selection = listNews->selectedItems();
|
||||
if(selection.empty()) return;
|
||||
QTreeWidgetItem *item = selection.first();
|
||||
if(item == previous_news) return;
|
||||
void RSSImp::refreshTextBrowser(QTreeWidgetItem *item) {
|
||||
if(!item || item == previous_news) return;
|
||||
// Stop displaying previous news if necessary
|
||||
if(listStreams->currentFeed() == listStreams->getUnreadItem()) {
|
||||
if(previous_news) {
|
||||
@@ -599,7 +596,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(itemSelectionChanged()), this, SLOT(refreshTextBrowser()));
|
||||
connect(listNews, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(refreshTextBrowser(QTreeWidgetItem *)));
|
||||
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();
|
||||
void refreshTextBrowser(QTreeWidgetItem *);
|
||||
void updateFeedIcon(QString url, QString icon_path);
|
||||
void updateFeedInfos(QString url, QString aliasOrUrl, unsigned int nbUnread);
|
||||
void updateItemsInfos(QList<QTreeWidgetItem*> items);
|
||||
|
@@ -57,6 +57,7 @@ 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();
|
||||
@@ -141,7 +142,8 @@ void SearchEngine::displayPatternContextMenu(QPoint) {
|
||||
QAction *act = myMenu.exec(QCursor::pos());
|
||||
if(act != 0) {
|
||||
if(act == &clearHistoryAct) {
|
||||
searchHistory.setStringList(QStringList());
|
||||
searchHistory.clear();
|
||||
createCompleter();
|
||||
} else if (act == &pasteAct) {
|
||||
} else if (act == &pasteAct) {
|
||||
search_pattern->paste();
|
||||
@@ -179,13 +181,18 @@ void SearchEngine::on_enginesButton_clicked() {
|
||||
// get the last searchs from a QSettings to a QStringList
|
||||
void SearchEngine::startSearchHistory(){
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
searchHistory.setStringList(settings.value("Search/searchHistory",QStringList()).toStringList());
|
||||
settings.beginGroup("Search");
|
||||
searchHistory = settings.value("searchHistory",-1).toStringList();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
// Save the history list into the QSettings for the next session
|
||||
void SearchEngine::saveSearchHistory() {
|
||||
void SearchEngine::saveSearchHistory()
|
||||
{
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
settings.setValue("Search/searchHistory",searchHistory.stringList());
|
||||
settings.beginGroup("Search");
|
||||
settings.setValue("searchHistory",searchHistory);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
// Function called when we click on search button
|
||||
@@ -213,14 +220,13 @@ void SearchEngine::on_search_button_clicked(){
|
||||
tabWidget->setCurrentWidget(currentSearchTab);
|
||||
closeTab_button->setEnabled(true);
|
||||
// if the pattern is not in the pattern
|
||||
QStringList wordList = searchHistory.stringList();
|
||||
if(wordList.indexOf(pattern) == -1){
|
||||
if(searchHistory.indexOf(pattern) == -1){
|
||||
//update the searchHistory list
|
||||
wordList.append(pattern);
|
||||
searchHistory.append(pattern);
|
||||
// verify the max size of the history
|
||||
if(wordList.size() > SEARCHHISTORY_MAXSIZE)
|
||||
wordList = wordList.mid(wordList.size()/2);
|
||||
searchHistory.setStringList(wordList);
|
||||
if(searchHistory.size() > SEARCHHISTORY_MAXSIZE)
|
||||
searchHistory = searchHistory.mid(searchHistory.size()/2,searchHistory.size()/2);
|
||||
createCompleter();
|
||||
}
|
||||
|
||||
// Getting checked search engines
|
||||
@@ -246,7 +252,7 @@ void SearchEngine::on_search_button_clicked(){
|
||||
void SearchEngine::createCompleter() {
|
||||
if(searchCompleter)
|
||||
delete searchCompleter;
|
||||
searchCompleter = new QCompleter(&searchHistory);
|
||||
searchCompleter = new QCompleter(searchHistory, this);
|
||||
searchCompleter->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
search_pattern->setCompleter(searchCompleter);
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QPointer>
|
||||
#include <QStringListModel>
|
||||
#include "ui_search.h"
|
||||
#include "engineSelectDlg.h"
|
||||
#include "SearchTab.h"
|
||||
@@ -61,7 +60,7 @@ private:
|
||||
QByteArray search_result_line_truncated;
|
||||
unsigned long nb_search_results;
|
||||
QPointer<QCompleter> searchCompleter;
|
||||
QStringListModel searchHistory;
|
||||
QStringList searchHistory;
|
||||
bittorrent *BTSession;
|
||||
QSystemTrayIcon *myTrayIcon;
|
||||
bool systrayIntegration;
|
||||
|
@@ -14,10 +14,10 @@ CONFIG += qt \
|
||||
network
|
||||
|
||||
# Update this VERSION for each release
|
||||
DEFINES += VERSION=\\\"v1.5.6\\\"
|
||||
DEFINES += VERSION=\\\"v1.5.4\\\"
|
||||
DEFINES += VERSION_MAJOR=1
|
||||
DEFINES += VERSION_MINOR=5
|
||||
DEFINES += VERSION_BUGFIX=6
|
||||
DEFINES += VERSION_BUGFIX=4
|
||||
!mac:QMAKE_LFLAGS += -Wl,--as-needed
|
||||
contains(DEBUG_MODE, 1) {
|
||||
CONFIG += debug
|
||||
|
Reference in New Issue
Block a user