Fixup recent Qt client changes (#1107)
* Add EDIT_DATE torrent property declaration (Qt client) Switch to static assertion to help avoid similar issues in the future. * Only declare std::hash<QString> for Qt < 5.14 * Pass main window as context when connecting lambdas to torrents model signals (Qt client) This helps to automatically disconnect from signals on main window destruction. If not done, use after free is possible since main window is destroyed before torrents model. Fixes: #1106
This commit is contained in:
parent
34b02bfe34
commit
20119f006c
|
@ -243,16 +243,16 @@ MainWindow::MainWindow(Session& session, Prefs& prefs, TorrentModel& model, bool
|
|||
connect(ui.action_Quit, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
|
||||
auto refreshActionSensitivitySoon = [this]() { refreshSoon(REFRESH_ACTION_SENSITIVITY); };
|
||||
connect(&myFilterModel, &TorrentFilter::rowsInserted, refreshActionSensitivitySoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsRemoved, refreshActionSensitivitySoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsInserted, this, refreshActionSensitivitySoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsRemoved, this, refreshActionSensitivitySoon);
|
||||
|
||||
// torrent view
|
||||
myFilterModel.setSourceModel(&myModel);
|
||||
auto refreshSoonAdapter = [this]() { refreshSoon(); };
|
||||
connect(&myModel, &TorrentModel::modelReset, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::rowsRemoved, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::rowsInserted, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::dataChanged, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::modelReset, this, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::rowsRemoved, this, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::rowsInserted, this, refreshSoonAdapter);
|
||||
connect(&myModel, &TorrentModel::dataChanged, this, refreshSoonAdapter);
|
||||
|
||||
ui.listView->setModel(&myFilterModel);
|
||||
connect(ui.listView->selectionModel(), &QItemSelectionModel::selectionChanged, refreshActionSensitivitySoon);
|
||||
|
@ -313,10 +313,10 @@ MainWindow::MainWindow(Session& session, Prefs& prefs, TorrentModel& model, bool
|
|||
ui.verticalLayout->insertWidget(0, myFilterBar = new FilterBar(myPrefs, myModel, myFilterModel));
|
||||
|
||||
auto refreshHeaderSoon = [this]() { refreshSoon(REFRESH_TORRENT_VIEW_HEADER); };
|
||||
connect(&myModel, &TorrentModel::rowsInserted, refreshHeaderSoon);
|
||||
connect(&myModel, &TorrentModel::rowsRemoved, refreshHeaderSoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsInserted, refreshHeaderSoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsRemoved, refreshHeaderSoon);
|
||||
connect(&myModel, &TorrentModel::rowsInserted, this, refreshHeaderSoon);
|
||||
connect(&myModel, &TorrentModel::rowsRemoved, this, refreshHeaderSoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsInserted, this, refreshHeaderSoon);
|
||||
connect(&myFilterModel, &TorrentFilter::rowsRemoved, this, refreshHeaderSoon);
|
||||
connect(ui.listView, SIGNAL(headerDoubleClicked()), myFilterBar, SLOT(clear()));
|
||||
|
||||
QList<int> initKeys;
|
||||
|
@ -332,7 +332,7 @@ MainWindow::MainWindow(Session& session, Prefs& prefs, TorrentModel& model, bool
|
|||
|
||||
auto refreshStatusSoon = [this]() { refreshSoon(REFRESH_STATUS_BAR); };
|
||||
connect(&mySession, SIGNAL(sourceChanged()), this, SLOT(onSessionSourceChanged()));
|
||||
connect(&mySession, &Session::statsUpdated, refreshStatusSoon);
|
||||
connect(&mySession, &Session::statsUpdated, this, refreshStatusSoon);
|
||||
connect(&mySession, SIGNAL(dataReadProgress()), this, SLOT(dataReadProgress()));
|
||||
connect(&mySession, SIGNAL(dataSendProgress()), this, SLOT(dataSendProgress()));
|
||||
connect(&mySession, SIGNAL(httpAuthenticationRequired()), this, SLOT(wrongAuthentication()));
|
||||
|
|
160
qt/Torrent.cc
160
qt/Torrent.cc
|
@ -23,80 +23,68 @@
|
|||
#include "Torrent.h"
|
||||
#include "Utils.h"
|
||||
|
||||
Torrent::Torrent(Prefs const& prefs, int id) :
|
||||
myId(id),
|
||||
myPrefs(prefs)
|
||||
struct Property
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
int id;
|
||||
tr_quark key;
|
||||
int type;
|
||||
};
|
||||
|
||||
for (int i = 0; i < PROPERTY_COUNT; ++i)
|
||||
{
|
||||
assert(myProperties[i].id == i);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
setIcon(MIME_ICON, Utils::getFileIcon());
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
Torrent::Property Torrent::myProperties[] =
|
||||
Property constexpr myProperties[] =
|
||||
{
|
||||
{ UPLOAD_SPEED, TR_KEY_rateUpload, QVariant::ULongLong } /* Bps */,
|
||||
{ DOWNLOAD_SPEED, TR_KEY_rateDownload, QVariant::ULongLong }, /* Bps */
|
||||
{ DOWNLOAD_DIR, TR_KEY_downloadDir, QVariant::String },
|
||||
{ ACTIVITY, TR_KEY_status, QVariant::Int },
|
||||
{ NAME, TR_KEY_name, QVariant::String },
|
||||
{ ERROR, TR_KEY_error, QVariant::Int },
|
||||
{ ERROR_STRING, TR_KEY_errorString, QVariant::String },
|
||||
{ SIZE_WHEN_DONE, TR_KEY_sizeWhenDone, QVariant::ULongLong },
|
||||
{ LEFT_UNTIL_DONE, TR_KEY_leftUntilDone, QVariant::ULongLong },
|
||||
{ HAVE_UNCHECKED, TR_KEY_haveUnchecked, QVariant::ULongLong },
|
||||
{ HAVE_VERIFIED, TR_KEY_haveValid, QVariant::ULongLong },
|
||||
{ DESIRED_AVAILABLE, TR_KEY_desiredAvailable, QVariant::ULongLong },
|
||||
{ TOTAL_SIZE, TR_KEY_totalSize, QVariant::ULongLong },
|
||||
{ PIECE_SIZE, TR_KEY_pieceSize, QVariant::ULongLong },
|
||||
{ PIECE_COUNT, TR_KEY_pieceCount, QVariant::Int },
|
||||
{ PEERS_GETTING_FROM_US, TR_KEY_peersGettingFromUs, QVariant::Int },
|
||||
{ PEERS_SENDING_TO_US, TR_KEY_peersSendingToUs, QVariant::Int },
|
||||
{ WEBSEEDS_SENDING_TO_US, TR_KEY_webseedsSendingToUs, QVariant::Int },
|
||||
{ PERCENT_DONE, TR_KEY_percentDone, QVariant::Double },
|
||||
{ METADATA_PERCENT_DONE, TR_KEY_metadataPercentComplete, QVariant::Double },
|
||||
{ PERCENT_VERIFIED, TR_KEY_recheckProgress, QVariant::Double },
|
||||
{ DATE_ACTIVITY, TR_KEY_activityDate, QVariant::DateTime },
|
||||
{ DATE_ADDED, TR_KEY_addedDate, QVariant::DateTime },
|
||||
{ DATE_STARTED, TR_KEY_startDate, QVariant::DateTime },
|
||||
{ DATE_CREATED, TR_KEY_dateCreated, QVariant::DateTime },
|
||||
{ PEERS_CONNECTED, TR_KEY_peersConnected, QVariant::Int },
|
||||
{ ETA, TR_KEY_eta, QVariant::Int },
|
||||
{ DOWNLOADED_EVER, TR_KEY_downloadedEver, QVariant::ULongLong },
|
||||
{ UPLOADED_EVER, TR_KEY_uploadedEver, QVariant::ULongLong },
|
||||
{ FAILED_EVER, TR_KEY_corruptEver, QVariant::ULongLong },
|
||||
{ TRACKERSTATS, TR_KEY_trackerStats, CustomVariantType::TrackerStatsList },
|
||||
{ MIME_ICON, TR_KEY_NONE, QVariant::Icon },
|
||||
{ SEED_RATIO_LIMIT, TR_KEY_seedRatioLimit, QVariant::Double },
|
||||
{ SEED_RATIO_MODE, TR_KEY_seedRatioMode, QVariant::Int },
|
||||
{ SEED_IDLE_LIMIT, TR_KEY_seedIdleLimit, QVariant::Int },
|
||||
{ SEED_IDLE_MODE, TR_KEY_seedIdleMode, QVariant::Int },
|
||||
{ DOWN_LIMIT, TR_KEY_downloadLimit, QVariant::Int }, /* KB/s */
|
||||
{ DOWN_LIMITED, TR_KEY_downloadLimited, QVariant::Bool },
|
||||
{ UP_LIMIT, TR_KEY_uploadLimit, QVariant::Int }, /* KB/s */
|
||||
{ UP_LIMITED, TR_KEY_uploadLimited, QVariant::Bool },
|
||||
{ HONORS_SESSION_LIMITS, TR_KEY_honorsSessionLimits, QVariant::Bool },
|
||||
{ PEER_LIMIT, TR_KEY_peer_limit, QVariant::Int },
|
||||
{ HASH_STRING, TR_KEY_hashString, QVariant::String },
|
||||
{ IS_FINISHED, TR_KEY_isFinished, QVariant::Bool },
|
||||
{ IS_PRIVATE, TR_KEY_isPrivate, QVariant::Bool },
|
||||
{ IS_STALLED, TR_KEY_isStalled, QVariant::Bool },
|
||||
{ COMMENT, TR_KEY_comment, QVariant::String },
|
||||
{ CREATOR, TR_KEY_creator, QVariant::String },
|
||||
{ MANUAL_ANNOUNCE_TIME, TR_KEY_manualAnnounceTime, QVariant::DateTime },
|
||||
{ PEERS, TR_KEY_peers, CustomVariantType::PeerList },
|
||||
{ BANDWIDTH_PRIORITY, TR_KEY_bandwidthPriority, QVariant::Int },
|
||||
{ QUEUE_POSITION, TR_KEY_queuePosition, QVariant::Int },
|
||||
{ Torrent::UPLOAD_SPEED, TR_KEY_rateUpload, QVariant::ULongLong } /* Bps */,
|
||||
{ Torrent::DOWNLOAD_SPEED, TR_KEY_rateDownload, QVariant::ULongLong }, /* Bps */
|
||||
{ Torrent::DOWNLOAD_DIR, TR_KEY_downloadDir, QVariant::String },
|
||||
{ Torrent::ACTIVITY, TR_KEY_status, QVariant::Int },
|
||||
{ Torrent::NAME, TR_KEY_name, QVariant::String },
|
||||
{ Torrent::ERROR, TR_KEY_error, QVariant::Int },
|
||||
{ Torrent::ERROR_STRING, TR_KEY_errorString, QVariant::String },
|
||||
{ Torrent::SIZE_WHEN_DONE, TR_KEY_sizeWhenDone, QVariant::ULongLong },
|
||||
{ Torrent::LEFT_UNTIL_DONE, TR_KEY_leftUntilDone, QVariant::ULongLong },
|
||||
{ Torrent::HAVE_UNCHECKED, TR_KEY_haveUnchecked, QVariant::ULongLong },
|
||||
{ Torrent::HAVE_VERIFIED, TR_KEY_haveValid, QVariant::ULongLong },
|
||||
{ Torrent::DESIRED_AVAILABLE, TR_KEY_desiredAvailable, QVariant::ULongLong },
|
||||
{ Torrent::TOTAL_SIZE, TR_KEY_totalSize, QVariant::ULongLong },
|
||||
{ Torrent::PIECE_SIZE, TR_KEY_pieceSize, QVariant::ULongLong },
|
||||
{ Torrent::PIECE_COUNT, TR_KEY_pieceCount, QVariant::Int },
|
||||
{ Torrent::PEERS_GETTING_FROM_US, TR_KEY_peersGettingFromUs, QVariant::Int },
|
||||
{ Torrent::PEERS_SENDING_TO_US, TR_KEY_peersSendingToUs, QVariant::Int },
|
||||
{ Torrent::WEBSEEDS_SENDING_TO_US, TR_KEY_webseedsSendingToUs, QVariant::Int },
|
||||
{ Torrent::PERCENT_DONE, TR_KEY_percentDone, QVariant::Double },
|
||||
{ Torrent::METADATA_PERCENT_DONE, TR_KEY_metadataPercentComplete, QVariant::Double },
|
||||
{ Torrent::PERCENT_VERIFIED, TR_KEY_recheckProgress, QVariant::Double },
|
||||
{ Torrent::DATE_ACTIVITY, TR_KEY_activityDate, QVariant::DateTime },
|
||||
{ Torrent::DATE_ADDED, TR_KEY_addedDate, QVariant::DateTime },
|
||||
{ Torrent::DATE_STARTED, TR_KEY_startDate, QVariant::DateTime },
|
||||
{ Torrent::DATE_CREATED, TR_KEY_dateCreated, QVariant::DateTime },
|
||||
{ Torrent::PEERS_CONNECTED, TR_KEY_peersConnected, QVariant::Int },
|
||||
{ Torrent::ETA, TR_KEY_eta, QVariant::Int },
|
||||
{ Torrent::DOWNLOADED_EVER, TR_KEY_downloadedEver, QVariant::ULongLong },
|
||||
{ Torrent::UPLOADED_EVER, TR_KEY_uploadedEver, QVariant::ULongLong },
|
||||
{ Torrent::FAILED_EVER, TR_KEY_corruptEver, QVariant::ULongLong },
|
||||
{ Torrent::TRACKERSTATS, TR_KEY_trackerStats, CustomVariantType::TrackerStatsList },
|
||||
{ Torrent::MIME_ICON, TR_KEY_NONE, QVariant::Icon },
|
||||
{ Torrent::SEED_RATIO_LIMIT, TR_KEY_seedRatioLimit, QVariant::Double },
|
||||
{ Torrent::SEED_RATIO_MODE, TR_KEY_seedRatioMode, QVariant::Int },
|
||||
{ Torrent::SEED_IDLE_LIMIT, TR_KEY_seedIdleLimit, QVariant::Int },
|
||||
{ Torrent::SEED_IDLE_MODE, TR_KEY_seedIdleMode, QVariant::Int },
|
||||
{ Torrent::DOWN_LIMIT, TR_KEY_downloadLimit, QVariant::Int }, /* KB/s */
|
||||
{ Torrent::DOWN_LIMITED, TR_KEY_downloadLimited, QVariant::Bool },
|
||||
{ Torrent::UP_LIMIT, TR_KEY_uploadLimit, QVariant::Int }, /* KB/s */
|
||||
{ Torrent::UP_LIMITED, TR_KEY_uploadLimited, QVariant::Bool },
|
||||
{ Torrent::HONORS_SESSION_LIMITS, TR_KEY_honorsSessionLimits, QVariant::Bool },
|
||||
{ Torrent::PEER_LIMIT, TR_KEY_peer_limit, QVariant::Int },
|
||||
{ Torrent::HASH_STRING, TR_KEY_hashString, QVariant::String },
|
||||
{ Torrent::IS_FINISHED, TR_KEY_isFinished, QVariant::Bool },
|
||||
{ Torrent::IS_PRIVATE, TR_KEY_isPrivate, QVariant::Bool },
|
||||
{ Torrent::IS_STALLED, TR_KEY_isStalled, QVariant::Bool },
|
||||
{ Torrent::COMMENT, TR_KEY_comment, QVariant::String },
|
||||
{ Torrent::CREATOR, TR_KEY_creator, QVariant::String },
|
||||
{ Torrent::MANUAL_ANNOUNCE_TIME, TR_KEY_manualAnnounceTime, QVariant::DateTime },
|
||||
{ Torrent::PEERS, TR_KEY_peers, CustomVariantType::PeerList },
|
||||
{ Torrent::BANDWIDTH_PRIORITY, TR_KEY_bandwidthPriority, QVariant::Int },
|
||||
{ Torrent::QUEUE_POSITION, TR_KEY_queuePosition, QVariant::Int },
|
||||
{ Torrent::EDIT_DATE, TR_KEY_editDate, QVariant::Int },
|
||||
};
|
||||
|
||||
/***
|
||||
|
@ -184,6 +172,36 @@ Torrent::KeyList const Torrent::detailStatKeys{
|
|||
****
|
||||
***/
|
||||
|
||||
Torrent::Torrent(Prefs const& prefs, int id) :
|
||||
myId(id),
|
||||
myPrefs(prefs)
|
||||
{
|
||||
static_assert(TR_N_ELEMENTS(myProperties) == PROPERTY_COUNT);
|
||||
|
||||
static_assert(([] () constexpr
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (auto const& property : myProperties)
|
||||
{
|
||||
if (property.id != i)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return true;
|
||||
})());
|
||||
|
||||
setIcon(MIME_ICON, Utils::getFileIcon());
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
bool Torrent::setInt(int i, int value)
|
||||
{
|
||||
bool changed = false;
|
||||
|
|
10
qt/Torrent.h
10
qt/Torrent.h
|
@ -591,14 +591,6 @@ public:
|
|||
static KeyList const mainInfoKeys;
|
||||
static KeyList const mainStatKeys;
|
||||
|
||||
private:
|
||||
struct Property
|
||||
{
|
||||
int id;
|
||||
tr_quark key;
|
||||
int type;
|
||||
};
|
||||
|
||||
private:
|
||||
int getInt(int key) const;
|
||||
bool getBool(int key) const;
|
||||
|
@ -627,8 +619,6 @@ private:
|
|||
Prefs const& myPrefs;
|
||||
QVariant myValues[PROPERTY_COUNT];
|
||||
FileList myFiles;
|
||||
|
||||
static Property myProperties[];
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Torrent const*)
|
||||
|
|
|
@ -99,6 +99,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
|
@ -112,3 +114,5 @@ struct hash<QString>
|
|||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue