Commit 9c8049af authored by Joris Guisson's avatar Joris Guisson
Browse files

Fix crash due to dangling pointer

BUG: 281196
parent 9572fdaa
......@@ -37,6 +37,7 @@ Changes in 4.2:
- Hide chunkbar when download of stream is complete (259788)
- Suspend/resume queue when middle clicking on tray icon (210027)
- Use dbus to show ktorrent window from plasma applet (287309)
- Fix crash due to dangling pointer (281196)
Changes in 4.1.3:
- Fix statusbar hiding and showing not working (281674)
......
......@@ -21,7 +21,6 @@
#include "chunkdownloadmodel.h"
#include <klocale.h>
#include <interfaces/torrentinterface.h>
#include <interfaces/torrentfileinterface.h>
#include <interfaces/chunkdownloadinterface.h>
#include <util/functions.h>
......@@ -78,7 +77,7 @@ namespace kt
/////////////////////////////////////////////////////////////
ChunkDownloadModel::ChunkDownloadModel ( QObject* parent )
: QAbstractTableModel(parent),tc(0)
: QAbstractTableModel(parent)
{
}
......@@ -97,11 +96,11 @@ namespace kt
cd->getStats(stats);
QString files;
int n = 0;
if (tc->getStats().multi_file_torrent)
if (tc.data()->getStats().multi_file_torrent)
{
for (Uint32 i = 0;i < tc->getNumFiles();i++)
for (Uint32 i = 0;i < tc.data()->getNumFiles();i++)
{
const bt::TorrentFileInterface & tf = tc->getTorrentFile(i);
const bt::TorrentFileInterface & tf = tc.data()->getTorrentFile(i);
if (stats.chunk_index >= tf.getFirstChunk() && stats.chunk_index <= tf.getLastChunk())
{
if (n > 0)
......
......@@ -24,13 +24,9 @@
#include <QVector>
#include <QAbstractTableModel>
#include <interfaces/chunkdownloadinterface.h>
#include <interfaces/torrentinterface.h>
namespace bt
{
class TorrentInterface;
}
namespace kt
{
......@@ -86,7 +82,7 @@ namespace kt
};
private:
QVector<Item*> items;
bt::TorrentInterface* tc;
bt::TorrentInterface::WPtr tc;
};
}
......
......@@ -36,7 +36,7 @@ namespace kt
{
ChunkDownloadView::ChunkDownloadView(QWidget* parent) : QWidget(parent),curr_tc(0)
ChunkDownloadView::ChunkDownloadView(QWidget* parent) : QWidget(parent)
{
setupUi(this);
......@@ -82,7 +82,7 @@ namespace kt
return;
model->update();
const TorrentStats & s = curr_tc->getStats();
const TorrentStats & s = curr_tc.data()->getStats();
m_chunks_downloading->setText(QString::number(s.num_chunks_downloading));
m_chunks_downloaded->setText(QString::number(s.num_chunks_downloaded));
m_excluded_chunks->setText(QString::number(s.num_chunks_excluded));
......@@ -99,7 +99,7 @@ namespace kt
else
{
setEnabled(true);
const TorrentStats & s = curr_tc->getStats();
const TorrentStats & s = curr_tc.data()->getStats();
m_total_chunks->setText(QString::number(s.total_chunks));
m_size_chunks->setText(BytesToString(s.chunk_size));
}
......
......@@ -25,15 +25,10 @@
#include <QSortFilterProxyModel>
#include <ksharedconfig.h>
#include <interfaces/chunkdownloadinterface.h>
#include <interfaces/torrentinterface.h>
#include "ui_chunkdownloadview.h"
namespace bt
{
class TorrentInterface;
}
namespace kt
{
class ChunkDownloadModel;
......@@ -66,8 +61,9 @@ namespace kt
void saveState(KSharedConfigPtr cfg);
void loadState(KSharedConfigPtr cfg);
private:
bt::TorrentInterface* curr_tc;
bt::TorrentInterface::WPtr curr_tc;
ChunkDownloadModel* model;
QSortFilterProxyModel* pm;
};
......
......@@ -54,7 +54,7 @@ using namespace bt;
namespace kt
{
FileView::FileView(QWidget *parent) : QWidget(parent),curr_tc(0),model(0),show_list_of_files(false)
FileView::FileView(QWidget *parent) : QWidget(parent),model(0),show_list_of_files(false)
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
......@@ -149,11 +149,11 @@ namespace kt
void FileView::changeTC(bt::TorrentInterface* tc)
{
if (tc == curr_tc)
if (tc == curr_tc.data())
return;
if (curr_tc)
expanded_state_map[curr_tc] = model->saveExpandedState(proxy_model,view);
expanded_state_map[curr_tc.data()] = model->saveExpandedState(proxy_model,view);
curr_tc = tc;
setEnabled(tc != 0);
......@@ -177,13 +177,17 @@ namespace kt
void FileView::onMissingFileMarkedDND(bt::TorrentInterface* tc)
{
if (curr_tc == tc)
if (curr_tc.data() == tc)
model->missingFilesMarkedDND();
}
void FileView::showContextMenu(const QPoint & p)
{
const TorrentStats & s = curr_tc->getStats();
if (!curr_tc)
return;
bt::TorrentInterface* tc = curr_tc.data();
const TorrentStats & s = tc->getStats();
QModelIndexList sel = view->selectionModel()->selectedRows();
if (sel.count() == 0)
......@@ -220,7 +224,7 @@ namespace kt
open_action->setEnabled(true);
open_with_action->setEnabled(true);
move_files_action->setEnabled(true);
preview_path = curr_tc->getStats().output_path;
preview_path = tc->getStats().output_path;
collapse_action->setEnabled(false);
expand_action->setEnabled(false);
check_data->setEnabled(true);
......@@ -260,7 +264,7 @@ namespace kt
delete_action->setEnabled(true);
open_action->setEnabled(true);
open_with_action->setEnabled(true);
preview_path = curr_tc->getStats().output_path + model->dirPath(item);
preview_path = tc->getStats().output_path + model->dirPath(item);
collapse_action->setEnabled(!show_list_of_files);
expand_action->setEnabled(!show_list_of_files);
}
......@@ -331,7 +335,11 @@ namespace kt
void FileView::moveFiles()
{
if (curr_tc->getStats().multi_file_torrent)
if (!curr_tc)
return;
bt::TorrentInterface* tc = curr_tc.data();
if (tc->getStats().multi_file_torrent)
{
QModelIndexList sel = view->selectionModel()->selectedRows();
QMap<bt::TorrentFileInterface*,QString> moves;
......@@ -352,7 +360,7 @@ namespace kt
if (moves.count() > 0)
{
curr_tc->moveTorrentFiles(moves);
tc->moveTorrentFiles(moves);
}
}
else
......@@ -362,7 +370,7 @@ namespace kt
if (dir.isNull())
return;
curr_tc->changeOutputDir(dir,bt::TorrentInterface::MOVE_FILES);
tc->changeOutputDir(dir,bt::TorrentInterface::MOVE_FILES);
}
}
......@@ -403,7 +411,8 @@ namespace kt
if (!curr_tc)
return;
const TorrentStats & s = curr_tc->getStats();
bt::TorrentInterface* tc = curr_tc.data();
const TorrentStats & s = tc->getStats();
if (s.multi_file_torrent)
{
......@@ -411,7 +420,7 @@ namespace kt
if (!file)
{
// directory
new KRun(KUrl(curr_tc->getDataDir() + model->dirPath(proxy_model->mapToSource(index))), 0, 0, true, true);
new KRun(KUrl(tc->getDataDir() + model->dirPath(proxy_model->mapToSource(index))), 0, 0, true, true);
}
else
{
......@@ -421,7 +430,7 @@ namespace kt
}
else
{
new KRun(KUrl(curr_tc->getStats().output_path), 0, 0, true, true);
new KRun(KUrl(tc->getStats().output_path), 0, 0, true, true);
}
}
......@@ -487,25 +496,26 @@ namespace kt
return;
}
bt::TorrentInterface* tc = curr_tc.data();
if (on)
expanded_state_map[curr_tc] = model->saveExpandedState(proxy_model,view);
expanded_state_map[tc] = model->saveExpandedState(proxy_model,view);
proxy_model->setSourceModel(0);
delete model;
model = 0;
if (show_list_of_files)
model = new IWFileListModel(curr_tc,this);
model = new IWFileListModel(tc,this);
else
model = new IWFileTreeModel(curr_tc,this);
model = new IWFileTreeModel(tc,this);
proxy_model->setSourceModel(model);
view->setRootIsDecorated(!show_list_of_files && curr_tc->getStats().multi_file_torrent);
view->setRootIsDecorated(!show_list_of_files && tc->getStats().multi_file_torrent);
view->header()->restoreState(header_state);
if (!on)
{
QMap<bt::TorrentInterface*,QByteArray>::iterator i = expanded_state_map.find(curr_tc);
QMap<bt::TorrentInterface*,QByteArray>::iterator i = expanded_state_map.find(tc);
if (i != expanded_state_map.end())
model->loadExpandedState(proxy_model,view,i.value());
else
......@@ -553,9 +563,9 @@ namespace kt
if (!curr_tc || sel.isEmpty())
return;
if (curr_tc->getStats().multi_file_torrent)
if (curr_tc.data()->getStats().multi_file_torrent)
{
bt::Uint32 from = curr_tc->getStats().total_chunks;
bt::Uint32 from = curr_tc.data()->getStats().total_chunks;
bt::Uint32 to = 0;
foreach (const QModelIndex &idx,sel)
{
......@@ -568,10 +578,10 @@ namespace kt
if (tfi->getLastChunk() > to)
to = tfi->getLastChunk();
}
curr_tc->startDataCheck(false, from, to);
curr_tc.data()->startDataCheck(false, from, to);
}
else
curr_tc->startDataCheck(false, 0, curr_tc->getStats().total_chunks);
curr_tc.data()->startDataCheck(false, 0, curr_tc.data()->getStats().total_chunks);
}
}
......
......@@ -22,6 +22,7 @@
#include <QTreeView>
#include <util/constants.h>
#include <interfaces/torrentinterface.h>
#include <ksharedconfig.h>
class KLineEdit;
......@@ -31,7 +32,6 @@ class QToolBar;
namespace bt
{
class TorrentInterface;
class TorrentFileInterface;
}
......@@ -88,7 +88,7 @@ namespace kt
void checkFile();
private:
bt::TorrentInterface* curr_tc;
bt::TorrentInterface::WPtr curr_tc;
TorrentFileModel* model;
KMenu* context_menu;
......
......@@ -26,8 +26,6 @@
#include <util/functions.h>
#include <util/log.h>
#include <util/sha1hash.h>
#include <interfaces/torrentinterface.h>
#include "downloadedchunkbar.h"
#include "availabilitychunkbar.h"
#include "statustab.h"
......@@ -40,7 +38,7 @@ using namespace bt;
namespace kt
{
StatusTab::StatusTab(QWidget* parent) : QWidget(parent),curr_tc(0)
StatusTab::StatusTab(QWidget* parent) : QWidget(parent)
{
setupUi(this);
// do not use hardcoded colors
......@@ -95,10 +93,10 @@ namespace kt
void StatusTab::changeTC(bt::TorrentInterface* tc)
{
if (tc == curr_tc)
if (tc == curr_tc.data())
return;
curr_tc = tc;
curr_tc = bt::TorrentInterface::WPtr(tc);
downloaded_bar->setTC(tc);
availability_bar->setTC(tc);
......@@ -126,7 +124,7 @@ namespace kt
comments->setText(words.join(" "));
float ratio = curr_tc->getMaxShareRatio();
float ratio = tc->getMaxShareRatio();
if(ratio > 0)
{
use_ratio_limit->setChecked(true);
......@@ -140,7 +138,7 @@ namespace kt
ratio_limit->setEnabled(false);
}
float hours = curr_tc->getMaxSeedTime();
float hours = tc->getMaxSeedTime();
if (hours > 0)
{
time_limit->setEnabled(true);
......@@ -174,7 +172,8 @@ namespace kt
if (!curr_tc)
return;
const bt::TorrentStats & s = curr_tc->getStats();
bt::TorrentInterface* tc = curr_tc.data();
const bt::TorrentStats & s = tc->getStats();
downloaded_bar->updateBar();
availability_bar->updateBar();
......@@ -188,7 +187,7 @@ namespace kt
share_ratio->setText(QString("<font color=\"%1\">%2</font>").arg(ratio <= Settings::greenRatio() ? "#ff0000" : "#1c9a1c").arg(KGlobal::locale()->formatNumber(ratio,2)));
Uint32 secs = curr_tc->getRunningTimeUL();
Uint32 secs = tc->getRunningTimeUL();
if (secs == 0)
{
avg_up_speed->setText(BytesPerSecToString(0));
......@@ -199,7 +198,7 @@ namespace kt
avg_up_speed->setText(BytesPerSecToString(r / secs));
}
secs = curr_tc->getRunningTimeDL();
secs = tc->getRunningTimeDL();
if (secs == 0)
{
avg_down_speed->setText(BytesPerSecToString(0));
......@@ -221,7 +220,7 @@ namespace kt
if(!curr_tc)
return;
curr_tc->setMaxShareRatio(v);
curr_tc.data()->setMaxShareRatio(v);
}
void StatusTab::useRatioLimitToggled(bool state)
......@@ -229,26 +228,28 @@ namespace kt
if(!curr_tc)
return;
bt::TorrentInterface* tc = curr_tc.data();
ratio_limit->setEnabled(state);
if (!state)
{
curr_tc->setMaxShareRatio(0.00f);
tc->setMaxShareRatio(0.00f);
ratio_limit->setValue(0.00f);
}
else
{
float msr = curr_tc->getMaxShareRatio();
float msr = tc->getMaxShareRatio();
if(msr == 0.00f)
{
curr_tc->setMaxShareRatio(1.00f);
tc->setMaxShareRatio(1.00f);
ratio_limit->setValue(1.00f);
}
float sr = curr_tc->getStats().shareRatio();
float sr = tc->getStats().shareRatio();
if(sr >= 1.00f)
{
//always add 1 to max share ratio to prevent stopping if torrent is running.
curr_tc->setMaxShareRatio(sr + 1.00f);
tc->setMaxShareRatio(sr + 1.00f);
ratio_limit->setValue(sr + 1.00f);
}
}
......@@ -259,7 +260,7 @@ namespace kt
if(!curr_tc)
return;
float ratio = curr_tc->getMaxShareRatio();
float ratio = curr_tc.data()->getMaxShareRatio();
if (ratio > 0.00f)
{
// only update when needed
......@@ -287,7 +288,7 @@ namespace kt
if(!curr_tc)
return;
float time = curr_tc->getMaxSeedTime();
float time = curr_tc.data()->getMaxSeedTime();
if (time > 0.00f)
{
// only update when needed
......@@ -315,25 +316,26 @@ namespace kt
if(!curr_tc)
return;
bt::TorrentInterface* tc = curr_tc.data();
time_limit->setEnabled(on);
if (on)
{
Uint32 dl = curr_tc->getRunningTimeDL();
Uint32 ul = curr_tc->getRunningTimeUL();
Uint32 dl = tc->getRunningTimeDL();
Uint32 ul = tc->getRunningTimeUL();
float hours = (ul - dl) / 3600.0f + 1.0; // add one hour to current seed time to not stop immediatly
time_limit->setValue(hours);
curr_tc->setMaxSeedTime(hours);
tc->setMaxSeedTime(hours);
}
else
{
curr_tc->setMaxSeedTime(0.0f);
tc->setMaxSeedTime(0.0f);
}
}
void StatusTab::maxTimeChanged(double v)
{
if (curr_tc)
curr_tc->setMaxSeedTime(v);
curr_tc.data()->setMaxSeedTime(v);
}
void StatusTab::linkActivated(const QString& link)
......
......@@ -22,11 +22,11 @@
#define STATUSTAB_H
#include <QWidget>
#include <interfaces/torrentinterface.h>
#include "ui_statustab.h"
namespace kt
{
class TorrentInterface;
class StatusTab : public QWidget,public Ui_StatusTab
{
......@@ -51,7 +51,7 @@ namespace kt
void maxSeedTimeUpdate();
private:
bt::TorrentInterface* curr_tc;
bt::TorrentInterface::WPtr curr_tc;
};
}
......
......@@ -42,7 +42,7 @@ namespace kt
TrackerView::TrackerView(QWidget *parent)
: QWidget(parent), tc(0)
: QWidget(parent)
{
setupUi(this);
model = new TrackerModel(this);
......@@ -117,7 +117,7 @@ namespace kt
QList<bt::TrackerInterface*> tl;
foreach (const KUrl & url,urls)
{
bt::TrackerInterface* trk = tc->getTrackersList()->addTracker(url,true);
bt::TrackerInterface* trk = tc.data()->getTrackersList()->addTracker(url,true);
if (!trk)
dupes.append(url);
else
......@@ -145,10 +145,10 @@ namespace kt
void TrackerView::changeClicked()
{
QModelIndex current = m_tracker_list->selectionModel()->currentIndex();
if (!current.isValid())
if (!current.isValid() || tc.isNull())
return;
bt::TrackersList* tlist = tc->getTrackersList();
bt::TrackersList* tlist = tc.data()->getTrackersList();
bt::TrackerInterface* trk = model->tracker(proxy_model->mapToSource(current));
if (trk && trk->isEnabled())
tlist->setCurrentTracker(trk);
......@@ -156,9 +156,12 @@ namespace kt
void TrackerView::restoreClicked()
{
tc->getTrackersList()->restoreDefault();
tc->updateTracker();
model->changeTC(tc); // trigger reset
if (tc)
{
tc.data()->getTrackersList()->restoreDefault();
tc.data()->updateTracker();
model->changeTC(tc.data()); // trigger reset
}
}
void TrackerView::updateClicked()
......@@ -166,7 +169,7 @@ namespace kt
if(!tc)
return;
tc->updateTracker();
tc.data()->updateTracker();
}
void TrackerView::scrapeClicked()
......@@ -174,12 +177,12 @@ namespace kt
if(!tc)
return;
tc->scrapeTracker();
tc.data()->scrapeTracker();
}
void TrackerView::changeTC(TorrentInterface* ti)
{
if (tc == ti)
if (tc.data() == ti)
return;
setEnabled(ti != 0);
......@@ -211,7 +214,7 @@ namespace kt
m_remove_tracker->setEnabled(true);
m_restore_defaults->setEnabled(true);
m_scrape->setEnabled(true);
model->changeTC(tc);
model->changeTC(ti);
currentChanged(m_tracker_list->selectionModel()->currentIndex(),QModelIndex());
}
}
......@@ -226,12 +229,12 @@ namespace kt
return;
}
const TorrentStats & s = tc->getStats();
const TorrentStats & s = tc.data()->getStats();
bt::TrackerInterface* trk = model->tracker(proxy_model->mapToSource(current));
bool enabled = trk ? trk->isEnabled() : false;
m_change_tracker->setEnabled(s.running && model->rowCount(QModelIndex()) > 1 && enabled && s.priv_torrent);
m_remove_tracker->setEnabled(trk && tc->getTrackersList()->canRemoveTracker(trk));
m_remove_tracker->setEnabled(trk && tc.data()->getTrackersList()->canRemoveTracker(trk));
}
void TrackerView::saveState(KSharedConfigPtr cfg)
......
......@@ -23,11 +23,7 @@
#include "ui_trackerview.h"
#include <QSortFilterProxyModel>
namespace bt
{
class TorrentInterface;
}
#include <interfaces/torrentinterface.h>
namespace kt
{
......@@ -61,7 +57,7 @@ namespace kt
void torrentChanged(bt::TorrentInterface* ti);
private:
bt::TorrentInterface* tc;
bt::TorrentInterface::WPtr tc;
TrackerModel* model;
QSortFilterProxyModel* proxy_model;
};
......