You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
12 KiB
381 lines
12 KiB
/***************************************************************************
|
|
* Copyright (C) 2005 by *
|
|
* Joris Guisson <joris.guisson@gmail.com> *
|
|
* Ivan Vasic <ivasic@gmail.com> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
#include <tdepopupmenu.h>
|
|
#include <tdelocale.h>
|
|
#include <tdeapplication.h>
|
|
#include "ktorrent.h"
|
|
#include "trayicon.h"
|
|
#include <tqtooltip.h>
|
|
#include <kpassivepopup.h>
|
|
#include <interfaces/torrentinterface.h>
|
|
#include "ktorrentcore.h"
|
|
#include <interfaces/functions.h>
|
|
#include <net/socketmonitor.h>
|
|
#include <util/log.h>
|
|
#include "trayhoverpopup.h"
|
|
|
|
|
|
using namespace bt;
|
|
using namespace kt;
|
|
|
|
TrayIcon::TrayIcon( KTorrentCore* tc, TQWidget *parent, const char *name)
|
|
: KSystemTray(parent, name)
|
|
{
|
|
m_core = tc;
|
|
m_kt_pix = loadIcon("ktorrent");
|
|
setPixmap(m_kt_pix);
|
|
paint=new TQPainter( this );
|
|
drawContents ( paint );
|
|
previousDownloadHeight=0;
|
|
previousUploadHeight=0;
|
|
|
|
m_hover_popup = new TrayHoverPopup(m_kt_pix,this);
|
|
|
|
connect(this,TQ_SIGNAL(quitSelected()),kapp,TQ_SLOT(quit()));
|
|
connect(m_core, TQ_SIGNAL(finished(kt::TorrentInterface* )),
|
|
this, TQ_SLOT(finished(kt::TorrentInterface* )));
|
|
connect(m_core,TQ_SIGNAL(torrentStoppedByError(kt::TorrentInterface*, TQString )),
|
|
this,TQ_SLOT(torrentStoppedByError(kt::TorrentInterface*, TQString )));
|
|
connect(m_core,TQ_SIGNAL(maxShareRatioReached( kt::TorrentInterface* )),
|
|
this,TQ_SLOT(maxShareRatioReached( kt::TorrentInterface* )));
|
|
connect(m_core,TQ_SIGNAL(maxSeedTimeReached(kt::TorrentInterface*)),
|
|
this, TQ_SLOT(maxSeedTimeReached(kt::TorrentInterface*)));
|
|
connect(m_core,TQ_SIGNAL(corruptedData( kt::TorrentInterface* )),
|
|
this,TQ_SLOT(corruptedData( kt::TorrentInterface* )));
|
|
connect(m_core, TQ_SIGNAL(queuingNotPossible( kt::TorrentInterface* )),
|
|
this, TQ_SLOT(queuingNotPossible( kt::TorrentInterface* )));
|
|
connect(m_core,TQ_SIGNAL(canNotStart(kt::TorrentInterface*, kt::TorrentStartResponse)),
|
|
this,TQ_SLOT(canNotStart(kt::TorrentInterface*, kt::TorrentStartResponse)));
|
|
connect(m_core, TQ_SIGNAL(lowDiskSpace(kt::TorrentInterface*, bool)),
|
|
this, TQ_SLOT(lowDiskSpace(kt::TorrentInterface*, bool)));
|
|
|
|
connect(this->contextMenu(),TQ_SIGNAL(aboutToShow()),m_hover_popup,TQ_SLOT(contextMenuAboutToShow()));
|
|
connect(this->contextMenu(),TQ_SIGNAL(aboutToHide()),m_hover_popup,TQ_SLOT(contextMenuAboutToHide()));
|
|
}
|
|
|
|
TrayIcon::~TrayIcon()
|
|
{}
|
|
|
|
void TrayIcon::enterEvent(TQEvent* ev)
|
|
{
|
|
KSystemTray::enterEvent(ev);
|
|
m_hover_popup->enterEvent();
|
|
}
|
|
|
|
void TrayIcon::leaveEvent(TQEvent* )
|
|
{
|
|
m_hover_popup->leaveEvent();
|
|
}
|
|
|
|
void TrayIcon::updateStats(const CurrentStats stats, bool showBars,int downloadBandwidth, int uploadBandwidth )
|
|
{
|
|
TQString tip = i18n("<table cellpadding='2' cellspacing='2' align='center'><tr><td><b>Speed:</b></td><td></td></tr><tr><td>Download: <font color='#1c9a1c'>%1</font></td><td>Upload: <font color='#990000'>%2</font></td></tr><tr><td><b>Transfer:</b></td><td></td></tr><tr><td>Download: <font color='#1c9a1c'>%3</font></td><td>Upload: <font color='#990000'>%4</font></td></tr></table>")
|
|
.arg(KBytesPerSecToString((double)stats.download_speed/1024.0))
|
|
.arg(KBytesPerSecToString((double)stats.upload_speed/1024.0))
|
|
.arg(BytesToString(stats.bytes_downloaded))
|
|
.arg(BytesToString(stats.bytes_uploaded));
|
|
m_hover_popup->updateText(tip);
|
|
|
|
if(showBars)
|
|
drawSpeedBar(stats.download_speed/1024,stats.upload_speed/1024, downloadBandwidth, uploadBandwidth);
|
|
else if (previousDownloadHeight > 0 || previousUploadHeight > 0)
|
|
{
|
|
repaint(); // clear the bars if they are disabled
|
|
previousDownloadHeight = previousUploadHeight = 0;
|
|
}
|
|
}
|
|
|
|
void TrayIcon::drawSpeedBar(int downloadSpeed, int uploadSpeed, int downloadBandwidth, int uploadBandwidth )
|
|
{
|
|
//check if need repaint
|
|
if (uploadBandwidth == 0)
|
|
uploadBandwidth = 1;
|
|
if (downloadBandwidth == 0)
|
|
downloadBandwidth = 1;
|
|
|
|
int DownloadHeight=((downloadSpeed*pixmap()->height())/downloadBandwidth);
|
|
int UploadHeight=((uploadSpeed*pixmap()->height())/uploadBandwidth);
|
|
if(previousDownloadHeight==DownloadHeight && previousUploadHeight==UploadHeight)
|
|
return;
|
|
|
|
repaint ();
|
|
|
|
TQBrush brushD(green);
|
|
TQBrush brushU(red);
|
|
paint->fillRect(0,pixmap()->height(),2,-DownloadHeight,brushD);
|
|
paint->fillRect(pixmap()->width()-2,pixmap()->height(),2,-UploadHeight,brushU);
|
|
|
|
previousDownloadHeight=DownloadHeight;
|
|
previousUploadHeight=UploadHeight;
|
|
}
|
|
|
|
void TrayIcon::showPassivePopup(const TQString & msg,const TQString & title)
|
|
{
|
|
KPassivePopup* p = KPassivePopup::message(KPassivePopup::Boxed,title,msg,m_kt_pix, this);
|
|
p->setPalette(TQToolTip::palette());
|
|
p->setLineWidth(1);
|
|
}
|
|
|
|
|
|
void TrayIcon::finished(TorrentInterface* tc)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
double speed_up = (double)s.bytes_uploaded / 1024.0;
|
|
double speed_down = (double)(s.bytes_downloaded - s.imported_bytes)/ 1024.0;
|
|
|
|
TQString msg = i18n("<b>%1</b> has completed downloading."
|
|
"<br>Average speed: %2 DL / %3 UL.")
|
|
.arg(s.torrent_name)
|
|
.arg(KBytesPerSecToString(speed_down / tc->getRunningTimeDL()))
|
|
.arg(KBytesPerSecToString(speed_up / tc->getRunningTimeUL()));
|
|
|
|
showPassivePopup(msg,i18n("Download completed"));
|
|
}
|
|
|
|
void TrayIcon::maxShareRatioReached(kt::TorrentInterface* tc)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
TDELocale* loc = TDEGlobal::locale();
|
|
double speed_up = (double)s.bytes_uploaded / 1024.0;
|
|
|
|
TQString msg = i18n("<b>%1</b> has reached its maximum share ratio of %2 and has been stopped."
|
|
"<br>Uploaded %3 at an average speed of %4.")
|
|
.arg(s.torrent_name)
|
|
.arg(loc->formatNumber(s.max_share_ratio,2))
|
|
.arg(BytesToString(s.bytes_uploaded))
|
|
.arg(KBytesPerSecToString(speed_up / tc->getRunningTimeUL()));
|
|
|
|
showPassivePopup(msg,i18n("Seeding completed"));
|
|
}
|
|
|
|
void TrayIcon::maxSeedTimeReached(kt::TorrentInterface* tc)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
TDELocale* loc = TDEGlobal::locale();
|
|
double speed_up = (double)s.bytes_uploaded / 1024.0;
|
|
|
|
TQString msg = i18n("<b>%1</b> has reached its maximum seed time of %2 hours and has been stopped."
|
|
"<br>Uploaded %3 at an average speed of %4.")
|
|
.arg(s.torrent_name)
|
|
.arg(loc->formatNumber(s.max_seed_time,2))
|
|
.arg(BytesToString(s.bytes_uploaded))
|
|
.arg(KBytesPerSecToString(speed_up / tc->getRunningTimeUL()));
|
|
|
|
showPassivePopup(msg,i18n("Seeding completed"));
|
|
}
|
|
|
|
void TrayIcon::torrentStoppedByError(kt::TorrentInterface* tc, TQString msg)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
TQString err_msg = i18n("<b>%1</b> has been stopped with the following error: <br>%2")
|
|
.arg(s.torrent_name).arg(msg);
|
|
|
|
showPassivePopup(err_msg,i18n("Error"));
|
|
}
|
|
|
|
void TrayIcon::corruptedData(kt::TorrentInterface* tc)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
TQString err_msg = i18n("Corrupted data has been found in the torrent <b>%1</b>"
|
|
"<br>It would be a good idea to do a data integrity check on the torrent.")
|
|
.arg(s.torrent_name);
|
|
showPassivePopup(err_msg,i18n("Error"));
|
|
}
|
|
|
|
void TrayIcon::queuingNotPossible(kt::TorrentInterface* tc)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
TQString msg;
|
|
TDELocale* loc = TDEGlobal::locale();
|
|
|
|
if (tc->overMaxRatio())
|
|
msg = i18n("<b>%1</b> has reached its maximum share ratio of %2 and cannot be enqueued. Remove the limit manually if you want to continue seeding.")
|
|
.arg(s.torrent_name).arg(loc->formatNumber(s.max_share_ratio,2));
|
|
else
|
|
msg = i18n("<b>%1</b> has reached its maximum seed time of %2 hours and cannot be enqueued. Remove the limit manually if you want to continue seeding.")
|
|
.arg(s.torrent_name).arg(loc->formatNumber(s.max_seed_time,2));
|
|
|
|
showPassivePopup(msg,i18n("Torrent cannot be enqueued."));
|
|
}
|
|
|
|
void TrayIcon::canNotStart(kt::TorrentInterface* tc,kt::TorrentStartResponse reason)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
TQString msg = i18n("Cannot start <b>%1</b> : <br>").arg(tc->getStats().torrent_name);
|
|
switch (reason)
|
|
{
|
|
case kt::TQM_LIMITS_REACHED:
|
|
if (tc->getStats().bytes_left_to_download == 0)
|
|
{
|
|
// is a seeder
|
|
msg += i18n("Cannot seed more than 1 torrent. <br>",
|
|
"Cannot seed more than %n torrents. <br>",Settings::maxSeeds());
|
|
}
|
|
else
|
|
{
|
|
msg += i18n("Cannot download more than 1 torrent. <br>",
|
|
"Cannot download more than %n torrents. <br>",Settings::maxDownloads());
|
|
}
|
|
msg += i18n("Go to Settings -> Configure KTorrent, if you want to change the limits.");
|
|
showPassivePopup(msg,i18n("Torrent cannot be started"));
|
|
break;
|
|
case kt::NOT_ENOUGH_DISKSPACE:
|
|
msg += i18n("There is not enough diskspace available.");
|
|
showPassivePopup(msg,i18n("Torrent cannot be started"));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void TrayIcon::lowDiskSpace(kt::TorrentInterface * tc, bool stopped)
|
|
{
|
|
if (!Settings::showPopups())
|
|
return;
|
|
|
|
const TorrentStats & s = tc->getStats();
|
|
|
|
TQString msg = i18n("Your disk is running out of space.<br /><b>%1</b> is being downloaded to '%2'.").arg(s.torrent_name).arg(tc->getDataDir());
|
|
|
|
if(stopped)
|
|
msg.prepend(i18n("Torrent has been stopped.<br />"));
|
|
|
|
showPassivePopup(msg,i18n("Device running out of space"));
|
|
}
|
|
|
|
SetMaxRate::SetMaxRate( KTorrentCore* tc, int t, TQWidget *parent, const char *name):TDEPopupMenu(parent, name)
|
|
{
|
|
m_core = tc;
|
|
type=t;
|
|
makeMenu();
|
|
connect(this,TQ_SIGNAL(activated (int)),this,TQ_SLOT(rateSelected(int )));
|
|
}
|
|
void SetMaxRate::makeMenu()
|
|
{
|
|
|
|
int rate=(type==0) ? m_core->getMaxUploadSpeed() : m_core->getMaxDownloadSpeed();
|
|
int maxBandwidth=(rate > 0) ? rate : (type==0) ? 0 : 20 ;
|
|
int delta = 0;
|
|
int maxBandwidthRounded;
|
|
|
|
setCheckable(true);
|
|
insertTitle(i18n("Speed limit in KB/s"));
|
|
|
|
if(rate == 0)
|
|
setItemChecked(insertItem(i18n("Unlimited")), true);
|
|
else
|
|
insertItem(i18n("Unlimited"));
|
|
|
|
if((maxBandwidth%5)>=3)
|
|
maxBandwidthRounded=maxBandwidth + 5 - (maxBandwidth%5);
|
|
else
|
|
maxBandwidthRounded=maxBandwidth - (maxBandwidth%5);
|
|
|
|
for (int i = 0; i < 15; i++)
|
|
{
|
|
TQValueList<int> valuePair;
|
|
if (delta == 0)
|
|
valuePair.append(maxBandwidth);
|
|
else
|
|
{
|
|
if((maxBandwidth%5)!=0)
|
|
{
|
|
valuePair.append(maxBandwidthRounded - delta);
|
|
valuePair.append(maxBandwidthRounded + delta);
|
|
}
|
|
else
|
|
{
|
|
valuePair.append(maxBandwidth - delta);
|
|
valuePair.append(maxBandwidth + delta);
|
|
}
|
|
}
|
|
|
|
for (int j = 0; j < (int)valuePair.count(); j++)
|
|
{
|
|
if (valuePair[j] >= 1)
|
|
{
|
|
if(rate == valuePair[j] && j==0)
|
|
{
|
|
setItemChecked(insertItem(TQString("%1").arg(valuePair[j]),-1, (j == 0) ? 2 : count()), true);
|
|
}
|
|
else
|
|
insertItem(TQString("%1").arg(valuePair[j]),-1, (j == 0) ? 2 : count());
|
|
}
|
|
}
|
|
|
|
delta += (delta >= 50) ? 50 : (delta >= 20) ? 10 : 5;
|
|
|
|
}
|
|
}
|
|
void SetMaxRate::update()
|
|
{
|
|
clear();
|
|
makeMenu();
|
|
}
|
|
|
|
void SetMaxRate::rateSelected(int id)
|
|
{
|
|
int rate;
|
|
TQString ratestr = text(id).remove('&');
|
|
if (ratestr.contains(i18n("Unlimited")))
|
|
rate = 0;
|
|
else
|
|
rate = ratestr.toInt();
|
|
|
|
if(type==0)
|
|
{
|
|
m_core->setMaxUploadSpeed(rate);
|
|
net::SocketMonitor::setUploadCap( Settings::maxUploadRate() * 1024);
|
|
}
|
|
else
|
|
{
|
|
m_core->setMaxDownloadSpeed(rate);
|
|
net::SocketMonitor::setDownloadCap(Settings::maxDownloadRate()*1024);
|
|
}
|
|
Settings::writeConfig();
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
#include "trayicon.moc"
|