summaryrefslogtreecommitdiffstats
path: root/src/apps
diff options
context:
space:
mode:
Diffstat (limited to 'src/apps')
-rw-r--r--src/apps/CMakeLists.txt7
-rw-r--r--src/apps/ktcachecheck/CMakeLists.txt16
-rw-r--r--src/apps/ktcachecheck/cachecheck.cpp102
-rw-r--r--src/apps/ktcachecheck/cachechecker.cpp110
-rw-r--r--src/apps/ktcachecheck/cachechecker.h61
-rw-r--r--src/apps/ktcachecheck/multicachechecker.cpp143
-rw-r--r--src/apps/ktcachecheck/multicachechecker.h44
-rw-r--r--src/apps/ktcachecheck/singlecachechecker.cpp110
-rw-r--r--src/apps/ktcachecheck/singlecachechecker.h43
-rw-r--r--src/apps/ktorrent/CMakeLists.txt73
-rw-r--r--src/apps/ktorrent/README81
-rw-r--r--src/apps/ktorrent/addpeerwidget.cpp111
-rw-r--r--src/apps/ktorrent/addpeerwidget.h95
-rw-r--r--src/apps/ktorrent/addpeerwidgetbase.ui159
-rw-r--r--src/apps/ktorrent/advancedpref.ui648
-rw-r--r--src/apps/ktorrent/custom_widgets.cw68
-rw-r--r--src/apps/ktorrent/dcopinterface.h69
-rw-r--r--src/apps/ktorrent/downloadpref.ui716
-rw-r--r--src/apps/ktorrent/fileselectdlg.cpp297
-rw-r--r--src/apps/ktorrent/fileselectdlg.h85
-rw-r--r--src/apps/ktorrent/fileselectdlgbase.ui379
-rw-r--r--src/apps/ktorrent/filterbar.cpp126
-rw-r--r--src/apps/ktorrent/filterbar.h71
-rw-r--r--src/apps/ktorrent/generalpref.ui451
-rw-r--r--src/apps/ktorrent/groups/CMakeLists.txt16
-rw-r--r--src/apps/ktorrent/groups/activedownloadsgroup.cpp49
-rw-r--r--src/apps/ktorrent/groups/activedownloadsgroup.h45
-rw-r--r--src/apps/ktorrent/groups/activegroup.cpp49
-rw-r--r--src/apps/ktorrent/groups/activegroup.h45
-rw-r--r--src/apps/ktorrent/groups/activeuploadsgroup.cpp50
-rw-r--r--src/apps/ktorrent/groups/activeuploadsgroup.h45
-rw-r--r--src/apps/ktorrent/groups/allgroup.cpp41
-rw-r--r--src/apps/ktorrent/groups/allgroup.h43
-rw-r--r--src/apps/ktorrent/groups/downloadgroup.cpp45
-rw-r--r--src/apps/ktorrent/groups/downloadgroup.h43
-rw-r--r--src/apps/ktorrent/groups/group.cpp61
-rw-r--r--src/apps/ktorrent/groups/group.h133
-rw-r--r--src/apps/ktorrent/groups/groupmanager.cpp221
-rw-r--r--src/apps/ktorrent/groups/groupmanager.h133
-rw-r--r--src/apps/ktorrent/groups/groupview.cpp360
-rw-r--r--src/apps/ktorrent/groups/groupview.h126
-rw-r--r--src/apps/ktorrent/groups/inactivedownloadsgroup.cpp50
-rw-r--r--src/apps/ktorrent/groups/inactivedownloadsgroup.h45
-rw-r--r--src/apps/ktorrent/groups/inactivegroup.cpp49
-rw-r--r--src/apps/ktorrent/groups/inactivegroup.h45
-rw-r--r--src/apps/ktorrent/groups/inactiveuploadsgroup.cpp50
-rw-r--r--src/apps/ktorrent/groups/inactiveuploadsgroup.h45
-rw-r--r--src/apps/ktorrent/groups/queueddownloadsgroup.cpp47
-rw-r--r--src/apps/ktorrent/groups/queueddownloadsgroup.h44
-rw-r--r--src/apps/ktorrent/groups/queueduploadsgroup.cpp47
-rw-r--r--src/apps/ktorrent/groups/queueduploadsgroup.h44
-rw-r--r--src/apps/ktorrent/groups/torrentdrag.cpp37
-rw-r--r--src/apps/ktorrent/groups/torrentdrag.h44
-rw-r--r--src/apps/ktorrent/groups/torrentgroup.cpp147
-rw-r--r--src/apps/ktorrent/groups/torrentgroup.h57
-rw-r--r--src/apps/ktorrent/groups/uploadgroup.cpp45
-rw-r--r--src/apps/ktorrent/groups/uploadgroup.h43
-rw-r--r--src/apps/ktorrent/groups/userdownloadsgroup.cpp47
-rw-r--r--src/apps/ktorrent/groups/userdownloadsgroup.h44
-rw-r--r--src/apps/ktorrent/groups/useruploadsgroup.cpp47
-rw-r--r--src/apps/ktorrent/groups/useruploadsgroup.h44
-rw-r--r--src/apps/ktorrent/hi128-app-ktorrent.pngbin0 -> 24064 bytes
-rw-r--r--src/apps/ktorrent/hi128-mime-torrent.pngbin0 -> 18379 bytes
-rw-r--r--src/apps/ktorrent/hi16-app-ktorrent.pngbin0 -> 939 bytes
-rw-r--r--src/apps/ktorrent/hi16-mime-torrent.pngbin0 -> 864 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktencrypted.pngbin0 -> 653 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktremove.pngbin0 -> 1522 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktstart.pngbin0 -> 1221 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktstart_all.pngbin0 -> 1400 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktstop.pngbin0 -> 963 bytes
-rw-r--r--src/apps/ktorrent/hi22-action-ktstop_all.pngbin0 -> 1130 bytes
-rw-r--r--src/apps/ktorrent/hi22-app-ktorrent.pngbin0 -> 1502 bytes
-rw-r--r--src/apps/ktorrent/hi22-mime-torrent.pngbin0 -> 1345 bytes
-rw-r--r--src/apps/ktorrent/hi32-app-ktorrent.pngbin0 -> 2689 bytes
-rw-r--r--src/apps/ktorrent/hi32-mime-torrent.pngbin0 -> 2055 bytes
-rw-r--r--src/apps/ktorrent/hi48-action-ktplugins.pngbin0 -> 3077 bytes
-rw-r--r--src/apps/ktorrent/hi48-app-ktorrent.pngbin0 -> 5224 bytes
-rw-r--r--src/apps/ktorrent/hi48-mime-torrent.pngbin0 -> 3737 bytes
-rw-r--r--src/apps/ktorrent/hi64-action-ktinfowidget.pngbin0 -> 1673 bytes
-rw-r--r--src/apps/ktorrent/hi64-action-ktqueuemanager.pngbin0 -> 5149 bytes
-rw-r--r--src/apps/ktorrent/hi64-action-ktupnp.pngbin0 -> 4730 bytes
-rw-r--r--src/apps/ktorrent/hi64-app-ktorrent.pngbin0 -> 8186 bytes
-rw-r--r--src/apps/ktorrent/hi64-filesys-ktprefdownloads.pngbin0 -> 5711 bytes
-rw-r--r--src/apps/ktorrent/hi64-mime-torrent.pngbin0 -> 5882 bytes
-rw-r--r--src/apps/ktorrent/hisc-app-ktorrent.svgzbin0 -> 6674 bytes
-rw-r--r--src/apps/ktorrent/hisc-mime-torrent.svgzbin0 -> 10113 bytes
-rw-r--r--src/apps/ktorrent/ipfilterwidget.cpp194
-rw-r--r--src/apps/ktorrent/ipfilterwidget.h49
-rw-r--r--src/apps/ktorrent/ipfilterwidgetbase.ui355
-rw-r--r--src/apps/ktorrent/ktorrent.cpp1017
-rw-r--r--src/apps/ktorrent/ktorrent.desktop15
-rw-r--r--src/apps/ktorrent/ktorrent.h239
-rw-r--r--src/apps/ktorrent/ktorrentapp.cpp80
-rw-r--r--src/apps/ktorrent/ktorrentapp.h39
-rw-r--r--src/apps/ktorrent/ktorrentcore.cpp1145
-rw-r--r--src/apps/ktorrent/ktorrentcore.h358
-rw-r--r--src/apps/ktorrent/ktorrentdcop.cpp254
-rw-r--r--src/apps/ktorrent/ktorrentdcop.h76
-rw-r--r--src/apps/ktorrent/ktorrentplugin.desktop5
-rw-r--r--src/apps/ktorrent/ktorrentui.rc44
-rw-r--r--src/apps/ktorrent/ktorrentview.cpp912
-rw-r--r--src/apps/ktorrent/ktorrentview.h217
-rw-r--r--src/apps/ktorrent/ktorrentviewitem.cpp354
-rw-r--r--src/apps/ktorrent/ktorrentviewitem.h58
-rw-r--r--src/apps/ktorrent/ktorrentviewmenu.cpp217
-rw-r--r--src/apps/ktorrent/ktorrentviewmenu.h77
-rw-r--r--src/apps/ktorrent/leaktrace.cpp295
-rw-r--r--src/apps/ktorrent/main.cpp200
-rw-r--r--src/apps/ktorrent/newui/CMakeLists.txt14
-rw-r--r--src/apps/ktorrent/newui/button.cpp351
-rw-r--r--src/apps/ktorrent/newui/button.h109
-rw-r--r--src/apps/ktorrent/newui/buttonbar.cpp346
-rw-r--r--src/apps/ktorrent/newui/buttonbar.h113
-rw-r--r--src/apps/ktorrent/newui/comdefs.h30
-rw-r--r--src/apps/ktorrent/newui/ddockwindow.cpp418
-rw-r--r--src/apps/ktorrent/newui/ddockwindow.h117
-rw-r--r--src/apps/ktorrent/newui/dmainwindow.cpp318
-rw-r--r--src/apps/ktorrent/newui/dmainwindow.h114
-rw-r--r--src/apps/ktorrent/newui/docksplitter.cpp175
-rw-r--r--src/apps/ktorrent/newui/docksplitter.h63
-rw-r--r--src/apps/ktorrent/newui/dtabwidget.cpp111
-rw-r--r--src/apps/ktorrent/newui/dtabwidget.h59
-rw-r--r--src/apps/ktorrent/pastedialog.cpp62
-rw-r--r--src/apps/ktorrent/pastedialog.h45
-rw-r--r--src/apps/ktorrent/pastedlgbase.ui142
-rw-r--r--src/apps/ktorrent/pref.cpp508
-rw-r--r--src/apps/ktorrent/pref.h124
-rw-r--r--src/apps/ktorrent/queuedialog.cpp391
-rw-r--r--src/apps/ktorrent/queuedialog.h84
-rw-r--r--src/apps/ktorrent/queuedlg.ui720
-rw-r--r--src/apps/ktorrent/scandialog.cpp202
-rw-r--r--src/apps/ktorrent/scandialog.h88
-rw-r--r--src/apps/ktorrent/scandlgbase.ui193
-rw-r--r--src/apps/ktorrent/speedlimitsdlg.cpp63
-rw-r--r--src/apps/ktorrent/speedlimitsdlg.h48
-rw-r--r--src/apps/ktorrent/speedlimitsdlgbase.ui192
-rw-r--r--src/apps/ktorrent/torrentcreatordlg.cpp152
-rw-r--r--src/apps/ktorrent/torrentcreatordlg.h40
-rw-r--r--src/apps/ktorrent/torrentcreatordlgbase.ui527
-rw-r--r--src/apps/ktorrent/trayhoverpopup.cpp136
-rw-r--r--src/apps/ktorrent/trayhoverpopup.h72
-rw-r--r--src/apps/ktorrent/trayicon.cpp380
-rw-r--r--src/apps/ktorrent/trayicon.h143
-rw-r--r--src/apps/ktorrent/viewmanager.cpp265
-rw-r--r--src/apps/ktorrent/viewmanager.h115
-rw-r--r--src/apps/ktorrent/x-bittorrent.desktop9
-rw-r--r--src/apps/kttorinfo/CMakeLists.txt13
-rw-r--r--src/apps/kttorinfo/main.cpp54
-rw-r--r--src/apps/ktupnptest/CMakeLists.txt15
-rw-r--r--src/apps/ktupnptest/main.cpp97
-rw-r--r--src/apps/ktupnptest/mainwidget.ui75
-rw-r--r--src/apps/ktupnptest/upnptestapp.cpp87
-rw-r--r--src/apps/ktupnptest/upnptestapp.h59
153 files changed, 20230 insertions, 0 deletions
diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt
new file mode 100644
index 0000000..414640a
--- /dev/null
+++ b/src/apps/CMakeLists.txt
@@ -0,0 +1,7 @@
+
+##### subfolders
+
+add_subdirectory( ktcachecheck )
+add_subdirectory( ktorrent )
+add_subdirectory( kttorinfo )
+add_subdirectory( ktupnptest )
diff --git a/src/apps/ktcachecheck/CMakeLists.txt b/src/apps/ktcachecheck/CMakeLists.txt
new file mode 100644
index 0000000..e1f5b13
--- /dev/null
+++ b/src/apps/ktcachecheck/CMakeLists.txt
@@ -0,0 +1,16 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+##### ktcachecheck (executable)
+
+tde_add_executable( ktcachecheck AUTOMOC
+ SOURCES
+ cachecheck.cpp cachechecker.cpp singlecachechecker.cpp multicachechecker.cpp
+ LINK
+ ktorrent-shared tdecore-shared tdeui-shared tdeio-shared DCOP-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
diff --git a/src/apps/ktcachecheck/cachecheck.cpp b/src/apps/ktcachecheck/cachecheck.cpp
new file mode 100644
index 0000000..191ed7a
--- /dev/null
+++ b/src/apps/ktcachecheck/cachecheck.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <iostream>
+#include <stdlib.h>
+#include <util/log.h>
+#include <util/error.h>
+#include <util/functions.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include "singlecachechecker.h"
+#include "multicachechecker.h"
+
+
+using namespace bt;
+using namespace ktdebug;
+
+void Help()
+{
+ Out() << "Usage : cachecheck <directory_containing_cache>" << endl;
+ Out() << "OR cachecheck <torrent> <cache_file_or_dir> <index_file>" << endl;
+ exit(0);
+}
+
+int main(int argc,char** argv)
+{
+ Globals::instance().setDebugMode(true);
+ Globals::instance().initLog("cachecheck.log");
+ CacheChecker* cc = 0;
+ try
+ {
+ Torrent tor;
+ TQString tor_file,cache,index;
+
+ if (argc == 2)
+ {
+ TQString cache_dir = argv[1];
+ if (!cache_dir.endsWith(bt::DirSeparator()))
+ cache_dir += bt::DirSeparator();
+
+ tor_file = cache_dir + "torrent";
+ cache = cache_dir + "cache";
+ index = cache_dir + "index";
+ }
+ else if (argc == 4)
+ {
+ tor_file = argv[1];
+ cache = argv[2];
+ index = argv[3];
+ }
+ else
+ {
+ Help();
+ }
+
+
+ Out() << "Loading torrent : " << tor_file << " ... " << endl;
+ tor.load(tor_file,false);
+ if (tor.isMultiFile())
+ cc = new MultiCacheChecker(tor);
+ else
+ cc = new SingleCacheChecker(tor);
+
+ cc->check(cache,index);
+ if (cc->foundFailedChunks())
+ {
+ std::string str;
+ std::cout << "Found failed chunks, fix index file ? (y/n) ";
+ std::cin >> str;
+ if (str == "y" || str == "Y")
+ {
+ Out() << "Fixing index file ..." << endl;
+ cc->fixIndex();
+ Out() << "Finished !" << endl;
+ }
+ }
+ }
+ catch (Error & e)
+ {
+ Out() << "Error : " << e.toString() << endl;
+ }
+
+ delete cc;
+ Globals::cleanup();
+ return 0;
+}
diff --git a/src/apps/ktcachecheck/cachechecker.cpp b/src/apps/ktcachecheck/cachechecker.cpp
new file mode 100644
index 0000000..3c3b35e
--- /dev/null
+++ b/src/apps/ktcachecheck/cachechecker.cpp
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <util/log.h>
+#include <util/file.h>
+#include <util/error.h>
+#include <util/array.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include <torrent/chunkmanager.h>
+#include "cachechecker.h"
+
+using namespace bt;
+
+namespace ktdebug
+{
+
+ CacheChecker::CacheChecker(bt::Torrent & tor) : tor(tor)
+ {}
+
+
+ CacheChecker::~CacheChecker()
+ {}
+
+ void CacheChecker::loadIndex(const TQString & index_file)
+ {
+ this->index_file = index_file;
+ File fptr;
+ if (!fptr.open(index_file,"rb"))
+ throw Error(i18n("Cannot open index file %1 : %2").arg(index_file).arg(fptr.errorString()));
+
+ if (fptr.seek(File::END,0) != 0)
+ {
+ fptr.seek(File::BEGIN,0);
+
+ while (!fptr.eof())
+ {
+ NewChunkHeader hdr;
+ fptr.read(&hdr,sizeof(NewChunkHeader));
+ downloaded_chunks.insert(hdr.index);
+ }
+ }
+ }
+
+ struct ChunkHeader
+ {
+ unsigned int index; // the Chunks index
+ unsigned int deprecated; // offset in cache file
+ };
+
+
+ void CacheChecker::fixIndex()
+ {
+ if (failed_chunks.size() == 0 && extra_chunks.size() == 0)
+ return;
+
+ File fptr;
+ if (!fptr.open(index_file,"wb"))
+ throw Error(i18n("Cannot open index file %1 : %2").arg(index_file).arg(fptr.errorString()));
+
+ std::set<bt::Uint32>::iterator i;
+ // first remove failed chunks from downloaded
+ if (failed_chunks.size() > 0)
+ {
+ i = failed_chunks.begin();
+ while (i != failed_chunks.end())
+ {
+ downloaded_chunks.erase(*i);
+ i++;
+ }
+ }
+
+ // add extra chunks to download
+ if (extra_chunks.size() > 0)
+ {
+ i = extra_chunks.begin();
+ while (i != extra_chunks.end())
+ {
+ downloaded_chunks.insert(*i);
+ i++;
+ }
+ }
+
+ // write remaining chunks
+ i = downloaded_chunks.begin();
+ while (i != downloaded_chunks.end())
+ {
+ ChunkHeader ch = {*i,0};
+ fptr.write(&ch,sizeof(ChunkHeader));
+ i++;
+ }
+ }
+}
diff --git a/src/apps/ktcachecheck/cachechecker.h b/src/apps/ktcachecheck/cachechecker.h
new file mode 100644
index 0000000..27d58ac
--- /dev/null
+++ b/src/apps/ktcachecheck/cachechecker.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef DEBUGCACHECHECKER_H
+#define DEBUGCACHECHECKER_H
+
+#include <set>
+#include <tqstring.h>
+#include <util/functions.h>
+
+namespace bt
+{
+ class Torrent;
+}
+
+namespace ktdebug
+{
+
+ /**
+ * @author Joris Guisson
+ */
+ class CacheChecker
+ {
+ public:
+ CacheChecker(bt::Torrent & tor);
+ virtual ~CacheChecker();
+
+ void loadIndex(const TQString & index_file);
+ void fixIndex();
+ bool foundFailedChunks() const {return failed_chunks.size() > 0;}
+ bool foundExtraChunks() const {return extra_chunks.size() > 0;}
+
+ virtual void check(const TQString & cache,const TQString & index) = 0;
+ protected:
+ bt::Torrent & tor;
+ TQString index_file;
+ std::set<bt::Uint32> downloaded_chunks;
+ std::set<bt::Uint32> failed_chunks;
+ std::set<bt::Uint32> extra_chunks;
+ };
+
+
+}
+
+#endif
diff --git a/src/apps/ktcachecheck/multicachechecker.cpp b/src/apps/ktcachecheck/multicachechecker.cpp
new file mode 100644
index 0000000..53e8fee
--- /dev/null
+++ b/src/apps/ktcachecheck/multicachechecker.cpp
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <util/log.h>
+#include <util/file.h>
+#include <util/error.h>
+#include <util/array.h>
+#include <util/functions.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include <torrent/chunkmanager.h>
+#include "multicachechecker.h"
+
+using namespace bt;
+
+namespace ktdebug
+{
+
+ MultiCacheChecker::MultiCacheChecker(bt::Torrent& tor): CacheChecker(tor)
+ {}
+
+
+ MultiCacheChecker::~MultiCacheChecker()
+ {}
+
+
+ void MultiCacheChecker::check(const TQString& cache_dir, const TQString& index)
+ {
+ loadIndex(index);
+ TQString cache = cache_dir;
+ if (!cache.endsWith(bt::DirSeparator()))
+ cache += bt::DirSeparator();
+
+ Uint32 num_chunks = tor.getNumChunks();
+ Uint64 curr_file_off = 0;
+ Uint32 curr_file = 0;
+ Uint64 chunk_size = tor.getChunkSize();
+
+ Array<Uint8> buf((Uint32)tor.getChunkSize());
+ Uint32 num_ok = 0,num_not_ok = 0,num_not_downloaded = 0,extra_ok = 0;
+
+ for (Uint32 i = 0;i < num_chunks;i++)
+ {
+ if (i % 100 == 0)
+ Out() << "Checked " << i << " chunks" << endl;
+
+
+
+ Uint64 size = chunk_size;
+ if (i == tor.getNumChunks() - 1 && tor.getFileLength() % chunk_size != 0)
+ size = tor.getFileLength() % chunk_size;
+
+ //Out() << "Loading chunk (size = " << size << ")" << endl;
+ Uint64 bytes_offset = 0;
+ while (bytes_offset < size)
+ {
+ TorrentFile & tf = tor.getFile(curr_file);
+// Out() << "Current file : " << tf.getPath() << " (" << curr_file << ")" << endl;
+ Uint64 to_read = size - bytes_offset;
+// Out() << "to_read = " << to_read << endl;
+ if (to_read <= tf.getSize() - curr_file_off)
+ {
+ // we can read the chunk from this file
+ File fptr;
+ if (!fptr.open(cache + tf.getPath(),"rb"))
+ throw Error(TQString("Cannot open %1 : %2").arg(cache + tf.getPath()).arg(fptr.errorString()));
+
+ fptr.seek(File::BEGIN,curr_file_off);
+ fptr.read(buf + bytes_offset,to_read);
+ bytes_offset += to_read;
+ curr_file_off += to_read;
+ }
+ else
+ {
+
+ // read partially the data which can be read
+ to_read = tf.getSize() - curr_file_off;
+// Out() << "Partially reading " << to_read << endl;
+ File fptr;
+ if (!fptr.open(cache + tf.getPath(),"rb"))
+ throw Error(TQString("Cannot open %1 : %2").arg(cache + tf.getPath()).arg(fptr.errorString()));
+
+ fptr.seek(File::BEGIN,curr_file_off);
+ fptr.read(buf + bytes_offset,to_read);
+ bytes_offset += to_read;
+ // update curr_file and offset
+ curr_file++;
+ curr_file_off = 0;
+ }
+ } // end file reading while
+
+ // calculate hash and check it
+ SHA1Hash h = SHA1Hash::generate(buf,size);
+ if (h != tor.getHash(i))
+ {
+ if (downloaded_chunks.count(i) == 0)
+ {
+ num_not_downloaded++;
+ continue;
+ }
+ Out() << "Chunk " << i << " Failed :" << endl;
+ Out() << "\tShould be : " << tor.getHash(i).toString() << endl;
+ Out() << "\tIs : " << h.toString() << endl;
+ num_not_ok++;
+ failed_chunks.insert(i);
+ }
+ else
+ {
+ if (downloaded_chunks.count(i) == 0)
+ {
+ extra_ok++;
+ extra_chunks.insert(i);
+ continue;
+ }
+ num_ok++;
+ }
+ }
+
+ Out() << "Cache Check Summary" << endl;
+ Out() << "===================" << endl;
+ Out() << "Extra Chunks : " << extra_ok << endl;
+ Out() << "Chunks OK : " << num_ok << endl;
+ Out() << "Chunks Not Downloaded : " << num_not_downloaded << endl;
+ Out() << "Chunks Failed : " << num_not_ok << endl;
+ }
+
+}
diff --git a/src/apps/ktcachecheck/multicachechecker.h b/src/apps/ktcachecheck/multicachechecker.h
new file mode 100644
index 0000000..fc57792
--- /dev/null
+++ b/src/apps/ktcachecheck/multicachechecker.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef DEBUGMULTICACHECHECKER_H
+#define DEBUGMULTICACHECHECKER_H
+
+#include "cachechecker.h"
+
+namespace ktdebug
+{
+
+ /**
+ @author Joris Guisson
+ */
+ class MultiCacheChecker : public CacheChecker
+ {
+ public:
+ MultiCacheChecker(bt::Torrent& tor);
+
+ ~MultiCacheChecker();
+
+ virtual void check(const TQString& cache, const TQString& index);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktcachecheck/singlecachechecker.cpp b/src/apps/ktcachecheck/singlecachechecker.cpp
new file mode 100644
index 0000000..ab64fc3
--- /dev/null
+++ b/src/apps/ktcachecheck/singlecachechecker.cpp
@@ -0,0 +1,110 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <util/log.h>
+#include <util/file.h>
+#include <util/error.h>
+#include <util/array.h>
+#include <util/functions.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include <torrent/chunkmanager.h>
+#include "singlecachechecker.h"
+
+using namespace bt;
+
+namespace ktdebug
+{
+
+ SingleCacheChecker::SingleCacheChecker(bt::Torrent& tor): CacheChecker(tor)
+ {}
+
+
+ SingleCacheChecker::~SingleCacheChecker()
+ {}
+
+
+ void SingleCacheChecker::check(const TQString& cache, const TQString& index)
+ {
+ loadIndex(index);
+ Uint32 num_chunks = tor.getNumChunks();
+ File fptr;
+ if (!fptr.open(cache,"rb"))
+ {
+ throw Error(TQString("Cannot open file : %1 : %2")
+ .arg(cache).arg( fptr.errorString()));
+ }
+
+ Uint32 num_ok = 0,num_not_ok = 0,num_not_downloaded = 0,extra_ok = 0;
+
+ Array<Uint8> buf((Uint32)tor.getChunkSize());
+ for (Uint32 i = 0;i < num_chunks;i++)
+ {
+ if (i % 100 == 0)
+ Out(SYS_GEN|LOG_DEBUG) << "Checked " << i << " chunks" << endl;
+ // Out() << "Chunk " << i << " : ";
+ if (!fptr.eof())
+ {
+ Uint32 size = i == num_chunks - 1 && tor.getFileLength() % tor.getChunkSize() > 0 ?
+ tor.getFileLength() % tor.getChunkSize() : (Uint32)tor.getChunkSize();
+ fptr.seek(File::BEGIN,(Int64)i*tor.getChunkSize());
+ fptr.read(buf,size);
+ SHA1Hash h = SHA1Hash::generate(buf,size);
+ bool ok = (h == tor.getHash(i));
+ if (ok)
+ {
+ if (downloaded_chunks.count(i) == 0)
+ {
+ extra_ok++;
+ extra_chunks.insert(i);
+ continue;
+ }
+ num_ok++;
+ // Out() << "OK" << endl;
+ }
+ else
+ {
+ if (downloaded_chunks.count(i) == 0)
+ {
+ num_not_downloaded++;
+ continue;
+ }
+ Out() << "Chunk " << i << " Failed :" << endl;
+ Out() << "\tShould be : " << tor.getHash(i).toString() << endl;
+ Out() << "\tIs : " << h.toString() << endl;
+ num_not_ok++;
+ failed_chunks.insert(i);
+ }
+
+ }
+ else
+ {
+ num_not_downloaded++;
+ //Out() << "Not Downloaded" << endl;
+ }
+ }
+ Out() << "Cache Check Summary" << endl;
+ Out() << "===================" << endl;
+ Out() << "Extra Chunks : " << extra_ok << endl;
+ Out() << "Chunks OK : " << num_ok << endl;
+ Out() << "Chunks Not Downloaded : " << num_not_downloaded << endl;
+ Out() << "Chunks Failed : " << num_not_ok << endl;
+ }
+
+}
diff --git a/src/apps/ktcachecheck/singlecachechecker.h b/src/apps/ktcachecheck/singlecachechecker.h
new file mode 100644
index 0000000..fdec69d
--- /dev/null
+++ b/src/apps/ktcachecheck/singlecachechecker.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef DEBUGSINGLECACHECHECKER_H
+#define DEBUGSINGLECACHECHECKER_H
+
+#include "cachechecker.h"
+
+namespace ktdebug
+{
+
+ /**
+ @author Joris Guisson
+ */
+ class SingleCacheChecker : public CacheChecker
+ {
+ public:
+ SingleCacheChecker(bt::Torrent& tor);
+ virtual ~SingleCacheChecker();
+
+ virtual void check(const TQString& cache, const TQString& index);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/CMakeLists.txt b/src/apps/ktorrent/CMakeLists.txt
new file mode 100644
index 0000000..0966c29
--- /dev/null
+++ b/src/apps/ktorrent/CMakeLists.txt
@@ -0,0 +1,73 @@
+
+##### subfolders
+
+add_subdirectory( groups )
+add_subdirectory( newui )
+
+
+##### current folder
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+ ${CMAKE_BINARY_DIR}/src/libktorrent
+)
+
+
+##### check for memory leakage tracing
+
+if( WITH_MEMLEAK_TRACING )
+ add_definitions(-DKT_LEAKTRACE )
+endif( )
+
+
+##### ktorrent (executable)
+
+tde_add_executable( ktorrent AUTOMOC
+ SOURCES
+ addpeerwidget.cpp addpeerwidget.h addpeerwidgetbase.ui
+ advancedpref.ui dcopinterface.skel downloadpref.ui fileselectdlg.cpp
+ fileselectdlgbase.ui generalpref.ui ipfilterwidget.cpp ipfilterwidgetbase.ui ktorrent.cpp
+ ktorrentapp.cpp ktorrentcore.cpp ktorrentdcop.cpp ktorrentview.cpp ktorrentviewitem.cpp
+ ktorrentviewmenu.cpp leaktrace.cpp main.cpp pastedialog.cpp pastedlgbase.ui pref.cpp
+ queuedialog.cpp queuedialog.h queuedlg.ui scandialog.cpp scandlgbase.ui
+ speedlimitsdlg.cpp speedlimitsdlgbase.ui torrentcreatordlg.cpp torrentcreatordlg.h
+ torrentcreatordlgbase.ui trayhoverpopup.cpp trayicon.cpp viewmanager.cpp filterbar.cpp
+ LINK
+ groups-static newui-static
+ ktorrent-shared tdecore-shared tdeui-shared tdeio-shared DCOP-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
+
+
+##### other files
+
+install(
+ FILES ktorrentui.rc
+ DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}
+)
+
+tde_create_translated_desktop(
+ SOURCE ktorrentplugin.desktop
+ DESTINATION ${SERVICETYPES_INSTALL_DIR}
+)
+
+tde_create_translated_desktop(
+ SOURCE ktorrent.desktop
+ DESTINATION ${XDG_APPS_INSTALL_DIR}
+)
+
+if( WITH_TORRENT_MIMETYPE )
+ tde_create_translated_desktop(
+ SOURCE x-bittorrent.desktop
+ DESTINATION ${MIME_INSTALL_DIR}/application
+ )
+endif()
+
+tde_install_icons( ktorrent torrent DESTINATION ${SHARE_INSTALL_PREFIX}/icons )
+tde_install_icons(
+ ktencrypted ktinfowidget ktplugins ktprefdownloads ktqueuemanager
+ ktremove ktstart ktstart_all ktstop ktstop_all ktupnp
+ DESTINATION ${DATA_INSTALL_DIR}/${PROJECT_NAME}/icons
+)
diff --git a/src/apps/ktorrent/README b/src/apps/ktorrent/README
new file mode 100644
index 0000000..39de8b2
--- /dev/null
+++ b/src/apps/ktorrent/README
@@ -0,0 +1,81 @@
+-----------------------------------------------
+Kde application framework template quickstart
+Author: Thomas Nagy
+Date: 2004-03-22
+-----------------------------------------------
+
+This README file explains you basic things for starting with
+this application template.
+
+
+** Building and installing **
+
+* Build the configure script by "make -f Makefile.cvs"
+
+* To clean, use "make clean", and to clean everything
+(remove the makefiles, etc), use "make distclean"
+
+* To distribute your program, try "make dist".
+This will make a compact tarball archive of your release with the
+necessary scripts inside.
+
+* Modifying the auto-tools scripts
+for automake scripts there is an excellent tutorial there :
+http://developer.kde.org/documentation/other/makefile_am_howto.html
+
+* Simplify your life : install the project in your home directory for
+testing purposes.
+./configure --prefix=/home/user/dummyfolder/
+In the end when you finished the development you can
+rm -rf /home/user/dummyfolder/
+without fear.
+
+
+** Technologies **
+
+* Build the menus of your application easily
+kde applications now use an xml file (*ui.rc file) to build the menus.
+This allow a great customization of the application. However, when
+programming the menu is shown only after a "make install"
+
+For more details, consult :
+http://devel-home.kde.org/~larrosa/tutorial/p9.html
+http://developer.kde.org/documentation/tutorials/xmlui/preface.html
+
+* Use TDEConfig XT to create your configuration dialogs and make
+them more maintainable.
+
+For more details, consult :
+http://developer.kde.org/documentation/tutorials/tdeconfigxt/tdeconfigxt.html
+
+* With KParts, you can embed other kde components in your program, or make your program
+embeddable in other apps. For example, the kmplayer kpart can be called to play videos
+in your app.
+
+For more details, consult :
+http://www-106.ibm.com/developerworks/library/l-tdeparts/
+http://developer.kde.org/documentation/tutorials/dot/writing-plugins.html
+http://developer.kde.org/documentation/tutorials/developing-a-plugin-structure/index.html
+
+* With dcop, you can control your app from other applications
+Make sure to include K_DCOP and a kdcop: section in your .h file
+http://developer.kde.org/documentation/tutorials/dot/dcopiface/dcop-interface.html
+
+
+** Documentation **
+
+* For the translations :
+1. Download a patched gettext which can be found at:
+ http://public.kde.planetmirror.com/pub/kde/devel/gettext-kde/
+2. Install that gettext in ~/bin/
+3. cd ~/yourproject, export PATH=~/bin:$PATH, export
+TDEDIR=/where_your_KDE3_is
+4. make -f admin/Makefile.common package-messages
+5. make package-messages
+6. Translate the po files (not the pot!!) with kbabel or xemacs
+
+* Do not forget to write the documentation for your kde app
+edit the documentation template index.docbook in doc/
+
+
+
diff --git a/src/apps/ktorrent/addpeerwidget.cpp b/src/apps/ktorrent/addpeerwidget.cpp
new file mode 100644
index 0000000..063a6a9
--- /dev/null
+++ b/src/apps/ktorrent/addpeerwidget.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "addpeerwidget.h"
+
+#include <util/constants.h>
+#include <interfaces/torrentinterface.h>
+
+#include <tdelocale.h>
+#include <ksqueezedtextlabel.h>
+#include <klineedit.h>
+#include <knuminput.h>
+#include <tdemessagebox.h>
+
+#include <tqstring.h>
+#include <tqstringlist.h>
+#include <tqregexp.h>
+#include <tqvalidator.h>
+
+using namespace kt;
+using bt::Uint16;
+
+//PeerSource
+
+ManualPeerSource::ManualPeerSource()
+{}
+
+void ManualPeerSource::start()
+{}
+
+void ManualPeerSource::stop(bt::WaitJob* )
+{}
+
+ManualPeerSource::~ ManualPeerSource()
+{}
+
+void ManualPeerSource::signalPeersReady()
+{
+ peersReady(this);
+}
+
+
+//AddPeerWidget
+
+AddPeerWidget::AddPeerWidget(kt::TorrentInterface* tc, TQWidget *parent, const char *name)
+ :AddPeerWidgetBase(parent, name), m_tc(tc)
+{
+ if(!tc)
+ {
+ //oops, something went wrong...
+ m_status->setText(i18n("Torrent does not exist. Report this bug to KTorrent developers."));
+ m_ip->setEnabled(false);
+ m_port->setEnabled(false);
+ return;
+ }
+
+ m_peerSource = new ManualPeerSource();
+
+ //Register this peer source with ps manager.
+ m_tc->addPeerSource(m_peerSource);
+}
+
+AddPeerWidget::~ AddPeerWidget()
+{
+ //Unregister this peer source with ps manager.
+ m_tc->removePeerSource(m_peerSource);
+
+ delete m_peerSource;
+}
+
+void AddPeerWidget::btnAdd_clicked()
+{
+ int var=0;
+
+ TQRegExp rx("[0-9]{1,3}(.[0-9]{1,3}){3,3}");
+ TQRegExpValidator v( rx,0);
+
+ TQString ip = m_ip->text();
+
+ if(v.validate( ip, var ) == TQValidator::Acceptable)
+ {
+ m_peerSource->addPeer(ip, m_port->value());
+
+ m_peerSource->signalPeersReady();
+
+ m_status->setText(i18n("Potential peer added."));
+ }
+ else
+ {
+ KMessageBox::sorry(0, i18n("Malformed IP address."));
+ m_status->setText("");
+ }
+}
+
+#include "addpeerwidget.moc"
diff --git a/src/apps/ktorrent/addpeerwidget.h b/src/apps/ktorrent/addpeerwidget.h
new file mode 100644
index 0000000..ed394a8
--- /dev/null
+++ b/src/apps/ktorrent/addpeerwidget.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef ADDPEERWIDGET_H
+#define ADDPEERWIDGET_H
+
+#include "addpeerwidgetbase.h"
+
+#include <tqobject.h>
+#include <interfaces/peersource.h>
+
+namespace kt
+{
+ class TorrentInterface;
+}
+
+namespace bt
+{
+ class WaitJob;
+}
+
+/**
+ * @author Ivan Vasic <ivasic@gmail.com>
+ * @brief PeerSource to allow peers to be added manually.
+ *
+ * Start/Stop() do nothing. Use this class only to manually add peers.
+ */
+class ManualPeerSource: public kt::PeerSource
+{
+ TQ_OBJECT
+
+
+ public:
+ ManualPeerSource();
+ virtual ~ManualPeerSource();
+
+ /**
+ * @brief Emits peersReady signal.
+ * Use this when there are peers available in this peer source.
+ */
+ void signalPeersReady();
+
+ public slots:
+
+ /**
+ * Start gathering peers.
+ * Had to be defined but won't be used here.
+ */
+ void start();
+
+ /**
+ * Stop gathering peers.
+ * Had to be defined but won't be used here.
+ */
+ void stop(bt::WaitJob* wjob = 0);
+};
+
+
+/**
+ * @author Ivan Vasic <ivasic@gmail.com>
+ * @brief GUI dialog for adding peers.
+ */
+class AddPeerWidget: public AddPeerWidgetBase
+{
+ TQ_OBJECT
+
+ public:
+ AddPeerWidget(kt::TorrentInterface* tc, TQWidget *parent = 0, const char *name = 0);
+ ~AddPeerWidget();
+
+ public slots:
+ virtual void btnAdd_clicked();
+
+ private:
+ ManualPeerSource* m_peerSource;
+ kt::TorrentInterface* m_tc;
+};
+
+#endif
diff --git a/src/apps/ktorrent/addpeerwidgetbase.ui b/src/apps/ktorrent/addpeerwidgetbase.ui
new file mode 100644
index 0000000..fbd148b
--- /dev/null
+++ b/src/apps/ktorrent/addpeerwidgetbase.ui
@@ -0,0 +1,159 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AddPeerWidgetBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>AddPeerWidgetBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>380</width>
+ <height>89</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Add potential peer</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Peer IP:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_ip</cstring>
+ </property>
+ <property name="text">
+ <string>127.0.0.1</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>m_port</cstring>
+ </property>
+ <property name="value">
+ <number>6881</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLayoutWidget" row="2" column="0">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KSqueezedTextLabel">
+ <property name="name">
+ <cstring>m_status</cstring>
+ </property>
+ <property name="text">
+ <string>Enter peer IP and port.</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnAdd</cstring>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>27</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnClose</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>13</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>btnClose</sender>
+ <signal>clicked()</signal>
+ <receiver>AddPeerWidgetBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>btnAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>AddPeerWidgetBase</receiver>
+ <slot>btnAdd_clicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>btnClose</tabstop>
+ <tabstop>m_ip</tabstop>
+ <tabstop>m_port</tabstop>
+ <tabstop>btnAdd</tabstop>
+</tabstops>
+<slots>
+ <slot>btnAdd_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">ksqueezedtextlabel.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/advancedpref.ui b/src/apps/ktorrent/advancedpref.ui
new file mode 100644
index 0000000..0d8c387
--- /dev/null
+++ b/src/apps/ktorrent/advancedpref.ui
@@ -0,0 +1,648 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>AdvancedPref</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>AdvancedPref</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>743</width>
+ <height>683</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Advanced Preferences</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Advanced Options</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout15</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_5</cstring>
+ </property>
+ <property name="text">
+ <string>Time left estimation algorithm:</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>&lt;b&gt;KTorrent algorithm:&lt;/b&gt; Default algorithm using combination of other algorithms based on our tests.&lt;br&gt;
+&lt;b&gt;Current speed algorithm:&lt;/b&gt; Simplest algorithm - BytesLeft/CurrentSpeed&lt;br&gt;
+&lt;b&gt;Global average speed algorithm:&lt;/b&gt; BytesLeft/AverageSpeed&lt;br&gt;
+&lt;b&gt;Window of X algorithm:&lt;/b&gt; ET calculated from X speed samples&lt;br&gt;
+&lt;b&gt;Moving average algorithm:&lt;/b&gt; Moving average speed calculated from X samples</string>
+ </property>
+ </widget>
+ <widget class="TQComboBox">
+ <item>
+ <property name="text">
+ <string>KTorrent</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Current speed</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Global average speed</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Window of X</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Moving average</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>eta</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>&lt;b&gt;KTorrent algorithm:&lt;/b&gt; Default algorithm using combination of other algorithms based on our tests.&lt;br&gt;
+&lt;b&gt;Current speed algorithm:&lt;/b&gt; Simplest algorithm - BytesLeft/CurrentSpeed&lt;br&gt;
+&lt;b&gt;Global average speed algorithm:&lt;/b&gt; BytesLeft/AverageSpeed&lt;br&gt;
+&lt;b&gt;Window of X algorithm:&lt;/b&gt; ET calculated from X speed samples&lt;br&gt;
+&lt;b&gt;Moving average algorithm:&lt;/b&gt; Moving average speed calculated from X samples</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>(takes effect after restart)</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>148</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>prealloc_disabled</cstring>
+ </property>
+ <property name="text">
+ <string>Disa&amp;ble diskspace preallocation</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout25</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>full_prealloc</cstring>
+ </property>
+ <property name="text">
+ <string>F&amp;ully preallocate diskspace (avoids fragmentation)</string>
+ </property>
+ </widget>
+ <widget class="TQComboBox">
+ <item>
+ <property name="text">
+ <string>Basic (slow)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Filesystem specific</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>full_prealloc_method</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="duplicatesEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Performance</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Memory usage:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <item>
+ <property name="text">
+ <string>Low</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Medium</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>High</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>mem_usage</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>111</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout5_2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>GUI update interval:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <item>
+ <property name="text">
+ <string>500ms</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1s</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2s</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>5s</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>gui_interval</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>111</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_6</cstring>
+ </property>
+ <property name="text">
+ <string>Fast CPU</string>
+ </property>
+ </widget>
+ <widget class="TQSlider">
+ <property name="name">
+ <cstring>cpu_usage</cstring>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="tickmarks">
+ <enum>Below</enum>
+ </property>
+ <property name="tickInterval">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Slow CPU</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Data Checking</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>no_recheck</cstring>
+ </property>
+ <property name="text">
+ <string>During uploading, do &amp;not recheck chunks bigger than</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>recheck_size</cstring>
+ </property>
+ <property name="value">
+ <number>512</number>
+ </property>
+ <property name="minValue">
+ <number>16</number>
+ </property>
+ <property name="maxValue">
+ <number>8192</number>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>KB</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>auto_recheck</cstring>
+ </property>
+ <property name="text">
+ <string>Do a data integrit&amp;y check after</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>num_corrupted</cstring>
+ </property>
+ <property name="value">
+ <number>3</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>corrupted chunks</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Networking</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout33</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout32</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_7</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum number of connection setups:</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput" row="1" column="1">
+ <property name="name">
+ <cstring>max_con_setups</cstring>
+ </property>
+ <property name="value">
+ <number>50</number>
+ </property>
+ <property name="minValue">
+ <number>10</number>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>DSCP for IP packets:</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput" row="0" column="1">
+ <property name="name">
+ <cstring>dscp</cstring>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>63</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>383</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>do_not_use_kde_proxy</cstring>
+ </property>
+ <property name="text">
+ <string>Do not use the TDE pro&amp;xy settings for HTTP tracker connections</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>HTTP tracker proxy:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>http_proxy</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>full_prealloc</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>full_prealloc_method</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kcombobox.h</include>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/custom_widgets.cw b/src/apps/ktorrent/custom_widgets.cw
new file mode 100644
index 0000000..9e8426d
--- /dev/null
+++ b/src/apps/ktorrent/custom_widgets.cw
@@ -0,0 +1,68 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>PeerView</class>
+ <header location="local">peerview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="PNG" length="1125">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042c49444154388db5954f6c14551cc73fefcd7476b65bdaae4bb78bb5502a14d404e4801c88182d1c4c2c693da847400f9c24c68b878684238660e2b1e01f12c19493012ef2478c814412d354a46017a8a564bb6da5bbedccee767776e63d0ffb073751d483bfe49799974c3eeffb7ebf37df9fd05a530b2184040cc0042420aaf9a4d0d554800f045a6b256ae0e1e1e1d6bebebe838ee31c48a7d39b5cd7fd075e251cc7617272f2ded8d8d819cff33e0316819259537aead4a9839d5dd6d1784f91f55b0a94830242088404d304292bef68a89f520802a598fecddaa04f1a876f5c250c7c0a64cdeac686e33807e23d45e6b297c8b877f1831542614550b6599835c83c2a81b6786a75134faf2f1169f12997350881d9021d0903e06de0745d3160a6d3e94dbd5b0a64dcbb94b5831d0e3375ab892b1772dcf9790528543f8dd0d367b36768153b5e31503a0f1aecb004580b44ffac58baae8b1714f0833c7638cc8dab303a320f4822ab4c7a37c69196203de3319d5ce1c4d13c733331dedc67a129a154fd128401ab0616d55a130ac3d42d93d1913940d13fd0c9ee0183685c60da01c5421bd72f7a8c8efccef9afd374267ad93d642365be0636a0d28ec7600941d9e6f23917f0e97f23ce5bef35d19ec863da0ed9059b2be70bec196c66dfa10ec0e49b338f7017258651bf95021035c595429bb0903248fe52a2b5b595dd7b4d945cc2340cdca536be389ee3f67886c5798f773fe8e0dac508c989659277a2180da4ca4ff07821058b8b251445d63d6b13ed1098a6417e39cac85197dbe31962ab9bd9f1f22a226d45366f6d0620fdb08c900d281af6110284b20085b414861d905d88f2e52739ee8cbb8022143259d3dd84691730aa2d52da441a8de0c6958068870022a41e9629ad3473fd3b8fdbe319dadb9b4924da994d2d716c7896fbe35152f78b48245d6b2da4507faf582be8eaf159b721cc837b05ae7debb1f79d08cb8b515edad942a22bc4b1c33eb3d34b1c797f06af90a72d16e2f96d9a74aa11dca8586b222d01af0fb60070f6c402d72f15d97f28c6f6d7027a5f5ce6c3233dc4e2ede496b278be4fff608cee8d3e1add806aeca51094cbb06397c1ecc328e746537c7e3ccdb5cb1136bf60635882d4d41c6ec6836ab37efa214f72208ed9f4d7cdd38ee310280542e38b1c43fb6de26b3672e1ec3cc99bcb246f66a938a3241ab3e91f7c861fbf77710b1e5e49915bae974203ba0e9e9c9cbc373d6d6d305a040a89c2a77f50b27d5782bbbf7acccf28349235dd16cf6dd374f7295e1de8a45c02d37499182b01cc0201a085d61a2144d8b2ac8fb6ed340e77240c4261890e04c250185262546d534a032154b59e0ad394e41c98182bf268ce6721ed9f064e0253356f6da2e24c1f030f783c15fe6da680af8021602bd051532ca9b8521488559f61aa86c29343578fbf0264a94c906c7d3409214c20043457a116ff6de6795578012889ff6b98fe016ea0ce1c6a2573410000000049454e44ae426082</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>ChunkDownloadView</class>
+ <header location="local">chunkdownloadview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="PNG" length="1125">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042c49444154388db5954f6c14551cc73fefcd7476b65bdaae4bb78bb5502a14d404e4801c88182d1c4c2c693da847400f9c24c68b878684238660e2b1e01f12c19493012ef2478c814412d354a46017a8a564bb6da5bbedccee767776e63d0ffb073751d483bfe49799974c3eeffb7ebf37df9fd05a530b2184040cc0042420aaf9a4d0d554800f045a6b256ae0e1e1e1d6bebebe838ee31c48a7d39b5cd7fd075e251cc7617272f2ded8d8d819cff33e0316819259537aead4a9839d5dd6d1784f91f55b0a94830242088404d304292bef68a89f520802a598fecddaa04f1a876f5c250c7c0a64cdeac686e33807e23d45e6b297c8b877f1831542614550b6599835c83c2a81b6786a75134faf2f1169f12997350881d9021d0903e06de0745d3160a6d3e94dbd5b0a64dcbb94b5831d0e3375ab892b1772dcf9790528543f8dd0d367b36768153b5e31503a0f1aecb004580b44ffac58baae8b1714f0833c7638cc8dab303a320f4822ab4c7a37c69196203de3319d5ce1c4d13c733331dedc67a129a154fd128401ab0616d55a130ac3d42d93d1913940d13fd0c9ee0183685c60da01c5421bd72f7a8c8efccef9afd374267ad93d642365be0636a0d28ec7600941d9e6f23917f0e97f23ce5bef35d19ec863da0ed9059b2be70bec196c66dfa10ec0e49b338f7017258651bf95021035c595429bb0903248fe52a2b5b595dd7b4d945cc2340cdca536be389ee3f67886c5798f773fe8e0dac508c989659277a2180da4ca4ff07821058b8b251445d63d6b13ed1098a6417e39cac85197dbe31962ab9bd9f1f22a226d45366f6d0620fdb08c900d281af6110284b20085b414861d905d88f2e52739ee8cbb8022143259d3dd84691730aa2d52da441a8de0c6958068870022a41e9629ad3473fd3b8fdbe319dadb9b4924da994d2d716c7896fbe35152f78b48245d6b2da4507faf582be8eaf159b721cc837b05ae7debb1f79d08cb8b515edad942a22bc4b1c33eb3d34b1c797f06af90a72d16e2f96d9a74aa11dca8586b222d01af0fb60070f6c402d72f15d97f28c6f6d7027a5f5ce6c3233dc4e2ede496b278be4fff608cee8d3e1add806aeca51094cbb06397c1ecc328e746537c7e3ccdb5cb1136bf60635882d4d41c6ec6836ab37efa214f72208ed9f4d7cdd38ee310280542e38b1c43fb6de26b3672e1ec3cc99bcb246f66a938a3241ab3e91f7c861fbf77710b1e5e49915bae974203ba0e9e9c9cbc373d6d6d305a040a89c2a77f50b27d5782bbbf7acccf28349235dd16cf6dd374f7295e1de8a45c02d37499182b01cc0201a085d61a2144d8b2ac8fb6ed340e77240c4261890e04c250185262546d534a032154b59e0ad394e41c98182bf268ce6721ed9f064e0253356f6da2e24c1f030f783c15fe6da680af8021602bd051532ca9b8521488559f61aa86c29343578fbf0264a94c906c7d3409214c20043457a116ff6de6795578012889ff6b98fe016ea0ce1c6a2573410000000049454e44ae426082</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>DownloadedChunkBar</class>
+ <header location="local">downloadedchunkbar.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>20</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="PNG" length="1125">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042c49444154388db5954f6c14551cc73fefcd7476b65bdaae4bb78bb5502a14d404e4801c88182d1c4c2c693da847400f9c24c68b878684238660e2b1e01f12c19493012ef2478c814412d354a46017a8a564bb6da5bbedccee767776e63d0ffb073751d483bfe49799974c3eeffb7ebf37df9fd05a530b2184040cc0042420aaf9a4d0d554800f045a6b256ae0e1e1e1d6bebebe838ee31c48a7d39b5cd7fd075e251cc7617272f2ded8d8d819cff33e0316819259537aead4a9839d5dd6d1784f91f55b0a94830242088404d304292bef68a89f520802a598fecddaa04f1a876f5c250c7c0a64cdeac686e33807e23d45e6b297c8b877f1831542614550b6599835c83c2a81b6786a75134faf2f1169f12997350881d9021d0903e06de0745d3160a6d3e94dbd5b0a64dcbb94b5831d0e3375ab892b1772dcf9790528543f8dd0d367b36768153b5e31503a0f1aecb004580b44ffac58baae8b1714f0833c7638cc8dab303a320f4822ab4c7a37c69196203de3319d5ce1c4d13c733331dedc67a129a154fd128401ab0616d55a130ac3d42d93d1913940d13fd0c9ee0183685c60da01c5421bd72f7a8c8efccef9afd374267ad93d642365be0636a0d28ec7600941d9e6f23917f0e97f23ce5bef35d19ec863da0ed9059b2be70bec196c66dfa10ec0e49b338f7017258651bf95021035c595429bb0903248fe52a2b5b595dd7b4d945cc2340cdca536be389ee3f67886c5798f773fe8e0dac508c989659277a2180da4ca4ff07821058b8b251445d63d6b13ed1098a6417e39cac85197dbe31962ab9bd9f1f22a226d45366f6d0620fdb08c900d281af6110284b20085b414861d905d88f2e52739ee8cbb8022143259d3dd84691730aa2d52da441a8de0c6958068870022a41e9629ad3473fd3b8fdbe319dadb9b4924da994d2d716c7896fbe35152f78b48245d6b2da4507faf582be8eaf159b721cc837b05ae7debb1f79d08cb8b515edad942a22bc4b1c33eb3d34b1c797f06af90a72d16e2f96d9a74aa11dca8586b222d01af0fb60070f6c402d72f15d97f28c6f6d7027a5f5ce6c3233dc4e2ede496b278be4fff608cee8d3e1add806aeca51094cbb06397c1ecc328e746537c7e3ccdb5cb1136bf60635882d4d41c6ec6836ab37efa214f72208ed9f4d7cdd38ee310280542e38b1c43fb6de26b3672e1ec3cc99bcb246f66a938a3241ab3e91f7c861fbf77710b1e5e49915bae974203ba0e9e9c9cbc373d6d6d305a040a89c2a77f50b27d5782bbbf7acccf28349235dd16cf6dd374f7295e1de8a45c02d37499182b01cc0201a085d61a2144d8b2ac8fb6ed340e77240c4261890e04c250185262546d534a032154b59e0ad394e41c98182bf268ce6721ed9f064e0253356f6da2e24c1f030f783c15fe6da680af8021602bd051532ca9b8521488559f61aa86c29343578fbf0264a94c906c7d3409214c20043457a116ff6de6795578012889ff6b98fe016ea0ce1c6a2573410000000049454e44ae426082</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>AvailabilityChunkBar</class>
+ <header location="local">availabilitychunkbar.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>20</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="PNG" length="1125">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000042c49444154388db5954f6c14551cc73fefcd7476b65bdaae4bb78bb5502a14d404e4801c88182d1c4c2c693da847400f9c24c68b878684238660e2b1e01f12c19493012ef2478c814412d354a46017a8a564bb6da5bbedccee767776e63d0ffb073751d483bfe49799974c3eeffb7ebf37df9fd05a530b2184040cc0042420aaf9a4d0d554800f045a6b256ae0e1e1e1d6bebebe838ee31c48a7d39b5cd7fd075e251cc7617272f2ded8d8d819cff33e0316819259537aead4a9839d5dd6d1784f91f55b0a94830242088404d304292bef68a89f520802a598fecddaa04f1a876f5c250c7c0a64cdeac686e33807e23d45e6b297c8b877f1831542614550b6599835c83c2a81b6786a75134faf2f1169f12997350881d9021d0903e06de0745d3160a6d3e94dbd5b0a64dcbb94b5831d0e3375ab892b1772dcf9790528543f8dd0d367b36768153b5e31503a0f1aecb004580b44ffac58baae8b1714f0833c7638cc8dab303a320f4822ab4c7a37c69196203de3319d5ce1c4d13c733331dedc67a129a154fd128401ab0616d55a130ac3d42d93d1913940d13fd0c9ee0183685c60da01c5421bd72f7a8c8efccef9afd374267ad93d642365be0636a0d28ec7600941d9e6f23917f0e97f23ce5bef35d19ec863da0ed9059b2be70bec196c66dfa10ec0e49b338f7017258651bf95021035c595429bb0903248fe52a2b5b595dd7b4d945cc2340cdca536be389ee3f67886c5798f773fe8e0dac508c989659277a2180da4ca4ff07821058b8b251445d63d6b13ed1098a6417e39cac85197dbe31962ab9bd9f1f22a226d45366f6d0620fdb08c900d281af6110284b20085b414861d905d88f2e52739ee8cbb8022143259d3dd84691730aa2d52da441a8de0c6958068870022a41e9629ad3473fd3b8fdbe319dadb9b4924da994d2d716c7896fbe35152f78b48245d6b2da4507faf582be8eaf159b721cc837b05ae7debb1f79d08cb8b515edad942a22bc4b1c33eb3d34b1c797f06af90a72d16e2f96d9a74aa11dca8586b222d01af0fb60070f6c402d72f15d97f28c6f6d7027a5f5ce6c3233dc4e2ede496b278be4fff608cee8d3e1add806aeca51094cbb06397c1ecc328e746537c7e3ccdb5cb1136bf60635882d4d41c6ec6836ab37efa214f72208ed9f4d7cdd38ee310280542e38b1c43fb6de26b3672e1ec3cc99bcb246f66a938a3241ab3e91f7c861fbf77710b1e5e49915bae974203ba0e9e9c9cbc373d6d6d305a040a89c2a77f50b27d5782bbbf7acccf28349235dd16cf6dd374f7295e1de8a45c02d37499182b01cc0201a085d61a2144d8b2ac8fb6ed340e77240c4261890e04c250185262546d534a032154b59e0ad394e41c98182bf268ce6721ed9f064e0253356f6da2e24c1f030f783c15fe6da680af8021602bd051532ca9b8521488559f61aa86c29343578fbf0264a94c906c7d3409214c20043457a116ff6de6795578012889ff6b98fe016ea0ce1c6a2573410000000049454e44ae426082</data>
+ </pixmap>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/src/apps/ktorrent/dcopinterface.h b/src/apps/ktorrent/dcopinterface.h
new file mode 100644
index 0000000..af00593
--- /dev/null
+++ b/src/apps/ktorrent/dcopinterface.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef DCOPINTERFACE_H
+#define DCOPINTERFACE_H
+
+#include <dcopobject.h>
+
+/**
+@author Joris Guisson
+*/
+class DCOPInterface : virtual public DCOPObject
+{
+ K_DCOP
+k_dcop:
+ virtual void startAll(int type = 3) = 0;
+ virtual void stopAll(int type = 3) = 0;
+ virtual void setMaxDownloads(int max) = 0;
+ virtual void setMaxSeeds(int max) = 0;
+ virtual void setKeepSeeding(bool ks) = 0;
+ virtual void setMaxUploadSpeed(int kbytes_per_sec) = 0;
+ virtual void setMaxDownloadSpeed(int kbytes_per_sec) = 0;
+ virtual void setMaxConnectionsPerDownload(int max) = 0;
+ virtual void setShowSysTrayIcon(bool yes) = 0;
+ virtual bool changeDataDir(const TQString & new_dir) = 0;
+ virtual void openTorrent(const TQString & file) = 0;
+ virtual void openTorrentSilently(const TQString & file) = 0;
+ virtual TQValueList<int> getTorrentNumbers(int type = 3) = 0;
+ virtual QCStringList getTorrentInfo(int tornumber) = 0;
+ virtual int getFileCount(int tornumber) = 0;
+ virtual QCStringList getInfo() = 0;
+ virtual QCStringList getFileNames(int tornumber) = 0;
+ virtual TQValueList<int> getFilePriorities(int tornumber) = 0;
+ virtual void setFilePriority(int tornumber, int index, int priority) = 0;
+ virtual void start(int tornumber) = 0;
+ virtual void stop(int tornumber, bool user) = 0;
+ virtual void remove(int tornumber, bool del_data) = 0;
+ virtual void announce(int tornumber) = 0;
+ virtual TQCString dataDir() = 0;
+ virtual int maxDownloads() = 0;
+ virtual int maxSeeds() = 0;
+ virtual int maxConnections() = 0;
+ virtual int maxUploadRate() = 0;
+ virtual int maxDownloadRate() = 0;
+ virtual bool keepSeeding() = 0;
+ virtual bool showSystemTrayIcon() = 0;
+ virtual TQValueList<int> intSettings() = 0;
+ virtual bool isBlockedIP(TQString ip) = 0;
+ virtual void openTorrentSilentlyDir(const TQString & file, const TQString & savedir) = 0;
+};
+
+
+#endif
diff --git a/src/apps/ktorrent/downloadpref.ui b/src/apps/ktorrent/downloadpref.ui
new file mode 100644
index 0000000..091aa6d
--- /dev/null
+++ b/src/apps/ktorrent/downloadpref.ui
@@ -0,0 +1,716 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>DownloadPref</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>DownloadPref</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>575</width>
+ <height>706</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Queue Manager</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout49</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout42</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout16</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum downloads:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_5</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum seeds:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_8</cstring>
+ </property>
+ <property name="text">
+ <string>Start download on low disk space :</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_9</cstring>
+ </property>
+ <property name="text">
+ <string>Minimum disk space:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout46</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_downloads</cstring>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_seeds</cstring>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="TQComboBox">
+ <item>
+ <property name="text">
+ <string>Don't start</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Always ask</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Force start</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>cmbDiskSpace</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout45</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQSpinBox">
+ <property name="name">
+ <cstring>intMinDiskSpace</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maxValue">
+ <number>10000</number>
+ </property>
+ <property name="minValue">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>MB</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout48</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout14</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>(0 is no limit)</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>(0 is no limit)</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer36</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>191</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer>
+ <property name="name">
+ <cstring>spacer17</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>207</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Preferences</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout42</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum download rate:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_7</cstring>
+ </property>
+ <property name="text">
+ <string>Global connection limit:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="8" column="0">
+ <property name="name">
+ <cstring>textLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Max seed time:</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout18</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum connections per torrent:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQLabel" row="6" column="0">
+ <property name="name">
+ <cstring>textLabel1_6</cstring>
+ </property>
+ <property name="text">
+ <string>Number of upload slots:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>UDP tracker port:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="7" column="0">
+ <property name="name">
+ <cstring>textLabel1_6_2</cstring>
+ </property>
+ <property name="text">
+ <string>Max share ratio:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum upload rate:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout41</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_conns</cstring>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_total_conns</cstring>
+ </property>
+ <property name="value">
+ <number>800</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_upload_rate</cstring>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>max_download_rate</cstring>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>port</cstring>
+ </property>
+ <property name="value">
+ <number>6881</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>udp_tracker_port</cstring>
+ </property>
+ <property name="value">
+ <number>4444</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>num_upload_slots</cstring>
+ </property>
+ <property name="value">
+ <number>2</number>
+ </property>
+ <property name="minValue">
+ <number>2</number>
+ </property>
+ <property name="maxValue">
+ <number>100</number>
+ </property>
+ <property name="referencePoint">
+ <number>2</number>
+ </property>
+ </widget>
+ <widget class="KDoubleSpinBox">
+ <property name="name">
+ <cstring>num_max_ratio</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="precision">
+ <number>2</number>
+ </property>
+ </widget>
+ <widget class="KDoubleSpinBox">
+ <property name="name">
+ <cstring>max_seed_time</cstring>
+ </property>
+ <property name="maxValue">
+ <number>1e+07</number>
+ </property>
+ <property name="lineStep">
+ <number>0.05</number>
+ </property>
+ <property name="precision">
+ <number>2</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout40</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>(0 is no limit)</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>(0 is no limit)</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>KB/sec (0 is no limit)</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>KB/sec (0 is no limit)</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>208</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>208</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>208</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>(0 is no limit)</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Hours (0 is no limit)</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>keep_seeding</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Keep seeding after download is finished</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Attention</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KActiveLabel">
+ <property name="name">
+ <cstring>kActiveLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>The above ports must also be forwarded if you are behind a router. The UPnP plugin can do this for you.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kactivelabel.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/fileselectdlg.cpp b/src/apps/ktorrent/fileselectdlg.cpp
new file mode 100644
index 0000000..a6dec27
--- /dev/null
+++ b/src/apps/ktorrent/fileselectdlg.cpp
@@ -0,0 +1,297 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <tdemessagebox.h>
+#include <tdelistview.h>
+#include <kstdguiitem.h>
+#include <kpushbutton.h>
+#include <kurlrequester.h>
+#include <kiconloader.h>
+#include <kmimetype.h>
+#include <kurl.h>
+
+#include <tqlabel.h>
+#include <tqstring.h>
+#include <tqbuttongroup.h>
+#include <tqcombobox.h>
+#include <tqcheckbox.h>
+#include <tqdir.h>
+
+#include <interfaces/torrentfileinterface.h>
+#include <interfaces/torrentinterface.h>
+#include "fileselectdlg.h"
+#include <interfaces/filetreediritem.h>
+#include <interfaces/filetreeitem.h>
+#include <interfaces/functions.h>
+#include <settings.h>
+#include <util/functions.h>
+#include <util/fileops.h>
+
+#include <groups/group.h>
+#include <groups/groupmanager.h>
+
+using namespace kt;
+
+FileSelectDlg::FileSelectDlg(GroupManager* gm, bool* user, bool* start, TQWidget* parent, const char* name, bool modal, WFlags fl)
+ : FileSelectDlgBase(parent, name, modal, fl), m_gman(gm), m_user(user), m_start(start)
+{
+ root = 0;
+ connect(m_select_all, TQ_SIGNAL(clicked()), this, TQ_SLOT(selectAll()));
+ connect(m_select_none, TQ_SIGNAL(clicked()), this, TQ_SLOT(selectNone()));
+ connect(m_invert_selection, TQ_SIGNAL(clicked()), this, TQ_SLOT(invertSelection()));
+ connect(m_ok, TQ_SIGNAL(clicked()), this, TQ_SLOT(accept()));
+ connect(m_cancel, TQ_SIGNAL(clicked()), this, TQ_SLOT(reject()));
+ connect(m_downloadLocation, TQ_SIGNAL(textChanged (const TQString &)), this, TQ_SLOT(updateSizeLabels()));
+
+ m_downloadLocation->setMode(KFile::Directory);
+}
+
+FileSelectDlg::~FileSelectDlg()
+
+{}
+
+int FileSelectDlg::execute(kt::TorrentInterface* tc)
+{
+ this->tc = tc;
+
+ if (tc)
+ {
+ populateFields();
+
+ if(tc->getStats().multi_file_torrent)
+ setupMultifileTorrent();
+ else
+ setupSinglefileTorrent();
+
+ return exec();
+ }
+
+ return TQDialog::Rejected;
+}
+
+void FileSelectDlg::reject()
+{
+ TQDialog::reject();
+}
+
+void FileSelectDlg::accept()
+{
+ TQStringList pe_ex;
+
+ TQString dn = m_downloadLocation->url();
+ if (!dn.endsWith(bt::DirSeparator()))
+ dn += bt::DirSeparator();
+
+ for (Uint32 i = 0;i < tc->getNumFiles();i++)
+ {
+ kt::TorrentFileInterface & file = tc->getTorrentFile(i);
+
+ // check for preexsting files
+ TQString path = dn + tc->getStats().torrent_name + bt::DirSeparator() + file.getPath();
+ if (bt::Exists(path))
+ file.setPreExisting(true);
+
+ if (file.doNotDownload() && file.isPreExistingFile())
+ {
+ // we have excluded a preexsting file
+ pe_ex.append(file.getPath());
+ }
+ }
+
+ if (pe_ex.count() > 0)
+ {
+ TQString msg = i18n("You have deselected the following existing files. "
+ "You will lose all data in these files, are you sure you want to do this ?");
+ // better ask the user if (s)he wants to delete the already existing data
+ int ret = KMessageBox::warningYesNoList(0, msg, pe_ex, TQString(),
+ KGuiItem(i18n("Yes, delete the files")),
+ KGuiItem(i18n("No, keep the files")));
+
+ if (ret == KMessageBox::No)
+ {
+ for (Uint32 i = 0;i < tc->getNumFiles();i++)
+ {
+ kt::TorrentFileInterface & file = tc->getTorrentFile(i);
+
+ if (file.doNotDownload() && file.isPreExistingFile())
+ file.setDoNotDownload(false);
+ }
+ }
+ }
+
+ for (Uint32 i = 0;i < tc->getNumFiles();i++)
+ {
+ kt::TorrentFileInterface & file = tc->getTorrentFile(i);
+ file.setEmitDownloadStatusChanged(true);
+ // we don't need to emit the downloadStatusChanged signal,
+ // because tc->createFiles() in ktorrentcore.cpp will take care of everything
+ }
+
+ //Setup custom download location
+ TQString ddir = tc->getDataDir();
+ if (!ddir.endsWith(bt::DirSeparator()))
+ ddir += bt::DirSeparator();
+
+ if (dn != ddir) // only change when absolutely necessary
+ tc->changeOutputDir(dn, false);
+
+ //Make it user controlled if needed
+ *m_user = m_chkUserControlled->isChecked();
+ *m_start = m_chkUserControlled->isChecked() && m_chkStartTorrent->isChecked();
+
+ //Now add torrent to selected group
+ if(m_cmbGroups->currentItem() != 0)
+ {
+ TQString groupName = m_cmbGroups->currentText();
+
+ Group* group = m_gman->find(groupName);
+ if(group)
+ {
+ group->addTorrent(tc);
+ }
+ }
+
+ // update the last save directory
+ Settings::setLastSaveDir(dn);
+ TQDialog::accept();
+}
+
+void FileSelectDlg::selectAll()
+{
+ if (root)
+ root->setAllChecked(true);
+}
+
+void FileSelectDlg::selectNone()
+{
+ if (root)
+ root->setAllChecked(false);
+}
+
+void FileSelectDlg::invertSelection()
+{
+ if (root)
+ root->invertChecked();
+}
+
+void FileSelectDlg::updateSizeLabels()
+{
+ //calculate free disk space
+
+ KURL sdir = KURL(m_downloadLocation -> url());
+ while( sdir.isValid() && sdir.isLocalFile() && (!sdir.isEmpty()) && (! TQDir(sdir.path()).exists()) )
+ {
+ sdir = sdir.upURL();
+ }
+
+ Uint64 bytes_free = 0;
+ if (!FreeDiskSpace(sdir.path(),bytes_free))
+ {
+ FreeDiskSpace(tc->getDataDir(),bytes_free);
+ }
+
+ Uint64 bytes_to_download = 0;
+ if (root)
+ bytes_to_download = root->bytesToDownload();
+ else
+ bytes_to_download = tc->getStats().total_bytes;
+
+ lblFree->setText(kt::BytesToString(bytes_free));
+ lblRequired->setText(kt::BytesToString(bytes_to_download));
+
+ if (bytes_to_download > bytes_free)
+ lblStatus->setText("<font color=\"#ff0000\">" + kt::BytesToString(-1*(long long)(bytes_free - bytes_to_download)) + i18n(" short!"));
+ else
+ lblStatus->setText(kt::BytesToString(bytes_free - bytes_to_download));
+}
+
+void FileSelectDlg::treeItemChanged()
+{
+ updateSizeLabels();
+}
+
+void FileSelectDlg::setupMultifileTorrent()
+{
+ m_file_view->clear();
+ root = new kt::FileTreeDirItem(m_file_view, tc->getStats().torrent_name, this);
+
+ for (Uint32 i = 0;i < tc->getNumFiles();i++)
+ {
+ kt::TorrentFileInterface & file = tc->getTorrentFile(i);
+ file.setEmitDownloadStatusChanged(false);
+ root->insert(file.getPath(), file);
+ }
+
+ root->setOpen(true);
+ m_file_view->setRootIsDecorated(true);
+
+ updateSizeLabels();
+}
+
+void FileSelectDlg::setupSinglefileTorrent()
+{
+ m_file_view->clear();
+ TDEListViewItem* single_root = new TDEListViewItem(m_file_view);
+ single_root->setText(0,tc->getStats().torrent_name);
+ single_root->setText(1,BytesToString(tc->getStats().total_bytes));
+ single_root->setText(2,i18n("Yes"));
+ single_root->setPixmap(0,KMimeType::findByPath(tc->getStats().torrent_name)->pixmap(TDEIcon::Small));
+ root = 0;
+ updateSizeLabels();
+ m_select_all->setEnabled(false);
+ m_select_none->setEnabled(false);
+ m_invert_selection->setEnabled(false);
+}
+
+void FileSelectDlg::populateFields()
+{
+ TQString dir = Settings::saveDir();
+ if (!Settings::useSaveDir() || dir.isNull())
+ {
+ dir = Settings::lastSaveDir();
+ if (dir.isNull())
+ dir = TQDir::homeDirPath();
+ }
+
+ m_downloadLocation->setURL(dir);
+ loadGroups();
+}
+
+void FileSelectDlg::loadGroups()
+{
+ GroupManager::iterator it = m_gman->begin();
+
+ TQStringList grps;
+
+ //First default group
+ grps << i18n("All Torrents");
+
+ //now custom ones
+ while(it != m_gman->end())
+ {
+ grps << it->first;
+ ++it;
+ }
+
+ m_cmbGroups->insertStringList(grps);
+}
+
+#include "fileselectdlg.moc"
+
diff --git a/src/apps/ktorrent/fileselectdlg.h b/src/apps/ktorrent/fileselectdlg.h
new file mode 100644
index 0000000..3a941c2
--- /dev/null
+++ b/src/apps/ktorrent/fileselectdlg.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+
+#ifndef FILESELECTDLG_H
+#define FILESELECTDLG_H
+
+#include <interfaces/filetreediritem.h>
+#include "fileselectdlgbase.h"
+
+
+
+namespace kt
+{
+
+ class TorrentInterface;
+ class FileTreeDirItem;
+ class GroupManager;
+}
+
+/**
+ * @author Joris Guisson
+ *
+ * Dialog to select which files to download from a multifile torrent.
+ */
+
+class FileSelectDlg : public FileSelectDlgBase, public kt::FileTreeRootListener
+{
+ TQ_OBJECT
+
+
+ kt::TorrentInterface* tc;
+ kt::FileTreeDirItem* root;
+
+ kt::GroupManager* m_gman;
+
+ bool* m_user;
+ bool* m_start;
+
+ public:
+ FileSelectDlg(kt::GroupManager* gm, bool* user, bool* start, TQWidget* parent = 0, const char* name = 0,
+ bool modal = true, WFlags fl = 0);
+
+ virtual ~FileSelectDlg();
+ int execute(kt::TorrentInterface* tc);
+
+ void loadGroups();
+
+ void populateFields();
+
+ void setupMultifileTorrent();
+ void setupSinglefileTorrent();
+
+ protected slots:
+ virtual void reject();
+ virtual void accept();
+ void selectAll();
+ void selectNone();
+ void invertSelection();
+
+ private:
+ virtual void treeItemChanged();
+
+ private slots:
+ void updateSizeLabels();
+};
+
+#endif
+
diff --git a/src/apps/ktorrent/fileselectdlgbase.ui b/src/apps/ktorrent/fileselectdlgbase.ui
new file mode 100644
index 0000000..9c27cd7
--- /dev/null
+++ b/src/apps/ktorrent/fileselectdlgbase.ui
@@ -0,0 +1,379 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>FileSelectDlgBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>FileSelectDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>491</width>
+ <height>500</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Select Which Files You Want to Download</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Download to:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>m_downloadLocation</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Group:</string>
+ </property>
+ </widget>
+ <widget class="TQComboBox">
+ <property name="name">
+ <cstring>m_cmbGroups</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>m_chkUserControlled</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;User controlled</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>m_chkStartTorrent</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Start torrent</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQButtonGroup" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>pnlFiles</cstring>
+ </property>
+ <property name="title">
+ <string>Files</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TDEListView" row="0" column="0" rowspan="4" colspan="1">
+ <column>
+ <property name="text">
+ <string>File</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Size</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Download</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>m_file_view</cstring>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="0" column="1">
+ <property name="name">
+ <cstring>m_select_all</cstring>
+ </property>
+ <property name="text">
+ <string>Select &amp;All</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>m_select_none</cstring>
+ </property>
+ <property name="text">
+ <string>Select &amp;None</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>m_invert_selection</cstring>
+ </property>
+ <property name="text">
+ <string>Invert Selection</string>
+ </property>
+ </widget>
+ <spacer row="3" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>135</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="TQGroupBox" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Disk space</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="0" column="2">
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout33</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Required disk space:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Free disk space:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>After download:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout34</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>lblRequired</cstring>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>lblFree</cstring>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>lblStatus</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="4" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>220</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>m_ok</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>m_cancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>m_chkUserControlled</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_chkStartTorrent</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>m_ok</tabstop>
+ <tabstop>m_cancel</tabstop>
+ <tabstop>m_downloadLocation</tabstop>
+ <tabstop>m_cmbGroups</tabstop>
+ <tabstop>m_chkUserControlled</tabstop>
+ <tabstop>m_chkStartTorrent</tabstop>
+ <tabstop>m_file_view</tabstop>
+ <tabstop>m_select_all</tabstop>
+ <tabstop>m_select_none</tabstop>
+ <tabstop>m_invert_selection</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">kurlrequester.h</include>
+ <include location="global" impldecl="in implementation">tdelistview.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/filterbar.cpp b/src/apps/ktorrent/filterbar.cpp
new file mode 100644
index 0000000..d83895b
--- /dev/null
+++ b/src/apps/ktorrent/filterbar.cpp
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Lukasz Fibinger <lucke@o2.pl> *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "filterbar.h"
+
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqcheckbox.h>
+
+#include <kdialog.h>
+#include <tdelocale.h>
+#include <kpushbutton.h>
+#include <tdetoolbarbutton.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <tdeconfig.h>
+#include <interfaces/torrentinterface.h>
+
+
+
+FilterBar::FilterBar(TQWidget *parent, const char *name) :
+ TQWidget(parent, name)
+{
+ const int gap = 3;
+
+ TQVBoxLayout* foo = new TQVBoxLayout(this);
+ foo->addSpacing(gap);
+
+ TQHBoxLayout* layout = new TQHBoxLayout(foo);
+ layout->addSpacing(gap);
+
+ m_close = new TDEToolBarButton("window-close",0,this);
+ connect(m_close,TQ_SIGNAL(clicked()),this,TQ_SLOT(hide()));
+ layout->addWidget(m_close);
+
+ m_filter = new TQLabel(i18n("Find:"), this);
+ layout->addWidget(m_filter);
+ layout->addSpacing(KDialog::spacingHint());
+
+ m_filterInput = new KLineEdit(this);
+ layout->addWidget(m_filterInput);
+
+ m_clear = new KPushButton(this);
+ m_clear->setIconSet(SmallIcon("clear_left"));
+ m_clear->setFlat(true);
+ layout->addWidget(m_clear);
+ layout->addSpacing(gap);
+
+ m_case_sensitive = new TQCheckBox(i18n("Case sensitive"),this);
+ m_case_sensitive->setChecked(true);
+ layout->addWidget(m_case_sensitive);
+ layout->addItem(new TQSpacerItem(10,10,TQSizePolicy::Expanding));
+
+ connect(m_filterInput, TQ_SIGNAL(textChanged(const TQString&)),
+ this, TQ_SLOT(slotChangeFilter(const TQString&)));
+ connect(m_clear, TQ_SIGNAL(clicked()), m_filterInput, TQ_SLOT(clear()));
+}
+
+FilterBar::~FilterBar()
+{
+}
+
+void FilterBar::saveSettings(TDEConfig* cfg)
+{
+ cfg->writeEntry("filter_bar_hidden",isHidden());
+ cfg->writeEntry("filter_bar_text",m_name_filter);
+ cfg->writeEntry("filter_bar_case_sensitive",m_case_sensitive->isChecked());
+}
+
+void FilterBar::loadSettings(TDEConfig* cfg)
+{
+ setHidden(cfg->readBoolEntry("filter_bar_hidden",true));
+ m_case_sensitive->setChecked(cfg->readBoolEntry("filter_bar_case_sensitive",true));
+ m_name_filter = cfg->readEntry("filter_bar_text",TQString());
+ m_filterInput->setText(m_name_filter);
+}
+
+bool FilterBar::matchesFilter(kt::TorrentInterface* tc)
+{
+ bool cs = m_case_sensitive->isChecked();
+ if (m_name_filter.length() == 0)
+ return true;
+ else
+ return tc->getStats().torrent_name.contains(m_name_filter,cs);
+}
+
+void FilterBar::slotChangeFilter(const TQString& nameFilter)
+{
+ m_name_filter = nameFilter;
+}
+
+void FilterBar::keyPressEvent(TQKeyEvent* event)
+{
+ if ((event->key() == TQt::Key_Escape))
+ {
+ m_filterInput->clear();
+ m_name_filter = TQString();
+ //hide();
+ }
+ else
+ TQWidget::keyPressEvent(event);
+}
+
+void FilterBar::hideEvent(TQHideEvent* event)
+{
+ m_filterInput->releaseKeyboard();
+ TQWidget::hideEvent(event);
+}
+
+#include "filterbar.moc"
diff --git a/src/apps/ktorrent/filterbar.h b/src/apps/ktorrent/filterbar.h
new file mode 100644
index 0000000..151fa73
--- /dev/null
+++ b/src/apps/ktorrent/filterbar.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Lukasz Fibinger <lucke@o2.pl> *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef FILTERBAR_H
+#define FILTERBAR_H
+
+#include <tqwidget.h>
+
+class TQLabel;
+class TQCheckBox;
+class TDEConfig;
+class KLineEdit;
+class KPushButton;
+class TDEToolBarButton;
+
+namespace kt
+{
+ class TorrentInterface;
+}
+
+/**
+ * Provides a filterbar allowing to show only select items
+ *
+ * based on dolphin's one (made by Gregor Kališnik)
+ */
+class FilterBar : public TQWidget
+{
+ TQ_OBJECT
+
+
+public:
+ FilterBar ( TQWidget *parent = 0, const char *name = 0 );
+ virtual ~FilterBar();
+
+ bool matchesFilter(kt::TorrentInterface* tc);
+ void saveSettings(TDEConfig* cfg);
+ void loadSettings(TDEConfig* cfg);
+
+private slots:
+ void slotChangeFilter(const TQString& nameFilter);
+
+protected:
+ virtual void keyPressEvent ( TQKeyEvent* event );
+ virtual void hideEvent(TQHideEvent* event);
+
+private:
+ TQLabel* m_filter;
+ KLineEdit* m_filterInput;
+ KPushButton* m_clear;
+ TQCheckBox* m_case_sensitive;
+ TDEToolBarButton* m_close;
+ TQString m_name_filter;
+};
+
+#endif
diff --git a/src/apps/ktorrent/generalpref.ui b/src/apps/ktorrent/generalpref.ui
new file mode 100644
index 0000000..452c1df
--- /dev/null
+++ b/src/apps/ktorrent/generalpref.ui
@@ -0,0 +1,451 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>GeneralPref</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>GeneralPref</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>603</width>
+ <height>657</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>General Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="5" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQGroupBox" row="4" column="0">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Encryption</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>use_encryption</cstring>
+ </property>
+ <property name="text">
+ <string>Use protocol encryption</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Protocol encryption is used to prevent ISP's from slowing down bittorrent connections.</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>allow_unencrypted</cstring>
+ </property>
+ <property name="text">
+ <string>Allow unencrypted connections</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>If unchecked, you'll be able to connect only to clients supporting encryption.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>DHT</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>&lt;b&gt;D&lt;/b&gt;istributed &lt;b&gt;H&lt;/b&gt;ash &lt;b&gt;T&lt;/b&gt;able protocol.&lt;br&gt;Decentralized peers exchange protocol. See manual for more info.</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>use_dht</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Use DHT to get additional peers</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>dht_port_label</cstring>
+ </property>
+ <property name="text">
+ <string>UDP port for DHT communication:</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>dht_port</cstring>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>6881</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Custom IP</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>custom_ip_check</cstring>
+ </property>
+ <property name="text">
+ <string>Se&amp;nd the tracker a custom IP address or hostname</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>custom_ip_label</cstring>
+ </property>
+ <property name="text">
+ <string>Custom IP address or hostname:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>custom_ip</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox3_2</cstring>
+ </property>
+ <property name="title">
+ <string>System Tray Icon</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>show_systray_icon</cstring>
+ </property>
+ <property name="text">
+ <string>Show s&amp;ystem tray icon</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>show_speedbar</cstring>
+ </property>
+ <property name="text">
+ <string>Show speed &amp;bar in tray icon</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>show_popups</cstring>
+ </property>
+ <property name="text">
+ <string>Show system tray popup messages</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Upload bandwidth (in KB/sec):</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>uploadBandwidth</cstring>
+ </property>
+ <property name="buttonSymbols">
+ <enum>UpDownArrows</enum>
+ </property>
+ <property name="maxValue">
+ <number>1000000</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ </widget>
+ <widget class="TQLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Download bandwidth (in KB/sec):</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>downloadBandwidth</cstring>
+ </property>
+ <property name="buttonSymbols">
+ <enum>UpDownArrows</enum>
+ </property>
+ <property name="maxValue">
+ <number>1000000</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Folders</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout24</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Folder to store temporary files:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>temp_dir</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>temp_dir</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>checkCompletedDir</cstring>
+ </property>
+ <property name="text">
+ <string>Move completed downloads to:</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>autosave_downloads_check</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Automatically save downloads to:</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget" row="1" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout14</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>autosave_location</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>urlCompletedDir</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>urlTorrentDir</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>checkTorrentDir</cstring>
+ </property>
+ <property name="text">
+ <string>Copy .torrent files to:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>show_speedbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel1_3_2_2_2</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>show_speedbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel1_3_2_2_2_2</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>show_speedbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>downloadBandwidth</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>show_speedbar</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>uploadBandwidth</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkCompletedDir</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>urlCompletedDir</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>autosave_downloads_check</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>autosave_location</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkTorrentDir</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>urlTorrentDir</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>autosave_downloads_check</tabstop>
+ <tabstop>show_systray_icon</tabstop>
+</tabstops>
+<pixmapinproject/>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">kurlrequester.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/groups/CMakeLists.txt b/src/apps/ktorrent/groups/CMakeLists.txt
new file mode 100644
index 0000000..9f7b273
--- /dev/null
+++ b/src/apps/ktorrent/groups/CMakeLists.txt
@@ -0,0 +1,16 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+##### groups library (static)
+
+tde_add_library( groups STATIC_PIC AUTOMOC
+ SOURCES
+ activedownloadsgroup.cpp activegroup.cpp groupview.cpp useruploadsgroup.cpp
+ activeuploadsgroup.cpp allgroup.cpp downloadgroup.cpp group.cpp groupmanager.cpp
+ inactivedownloadsgroup.cpp inactivegroup.cpp inactiveuploadsgroup.cpp queueddownloadsgroup.cpp
+ queueduploadsgroup.cpp torrentdrag.cpp torrentgroup.cpp uploadgroup.cpp userdownloadsgroup.cpp
+)
diff --git a/src/apps/ktorrent/groups/activedownloadsgroup.cpp b/src/apps/ktorrent/groups/activedownloadsgroup.cpp
new file mode 100644
index 0000000..a260f5a
--- /dev/null
+++ b/src/apps/ktorrent/groups/activedownloadsgroup.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "activedownloadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+ ActiveDownloadsGroup::ActiveDownloadsGroup()
+ : Group(i18n("Active downloads"),DOWNLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-down");
+ }
+
+
+ ActiveDownloadsGroup::~ActiveDownloadsGroup()
+ {}
+
+}
+
+bool kt::ActiveDownloadsGroup::isMember(TorrentInterface * tor)
+{
+ if (!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return s.running && !s.completed;
+}
+
+
diff --git a/src/apps/ktorrent/groups/activedownloadsgroup.h b/src/apps/ktorrent/groups/activedownloadsgroup.h
new file mode 100644
index 0000000..de62493
--- /dev/null
+++ b/src/apps/ktorrent/groups/activedownloadsgroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef ACTIVEDOWNLOADSGROUP_H
+#define ACTIVEDOWNLOADSGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for active downloads.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class ActiveDownloadsGroup : public Group
+ {
+
+ public:
+ ActiveDownloadsGroup();
+ virtual ~ActiveDownloadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/activegroup.cpp b/src/apps/ktorrent/groups/activegroup.cpp
new file mode 100644
index 0000000..7a5e640
--- /dev/null
+++ b/src/apps/ktorrent/groups/activegroup.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "activegroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ActiveGroup::ActiveGroup()
+ : Group(i18n("Active torrents"),MIXED_GROUP)
+{
+ setIconByName("metacontact_online");
+}
+
+
+ActiveGroup::~ActiveGroup()
+{}
+
+}
+
+bool kt::ActiveGroup::isMember(TorrentInterface * tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+ return s.running;
+}
+
+
diff --git a/src/apps/ktorrent/groups/activegroup.h b/src/apps/ktorrent/groups/activegroup.h
new file mode 100644
index 0000000..73e2aef
--- /dev/null
+++ b/src/apps/ktorrent/groups/activegroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef ACTIVEGROUP_H
+#define ACTIVEGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for active torrents.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class ActiveGroup : public Group
+ {
+
+ public:
+ ActiveGroup();
+ virtual ~ActiveGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/activeuploadsgroup.cpp b/src/apps/ktorrent/groups/activeuploadsgroup.cpp
new file mode 100644
index 0000000..6415eb9
--- /dev/null
+++ b/src/apps/ktorrent/groups/activeuploadsgroup.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "activeuploadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ ActiveUploadsGroup::ActiveUploadsGroup()
+ : Group(i18n("Active uploads"), UPLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-up");
+ }
+
+
+ ActiveUploadsGroup::~ActiveUploadsGroup()
+ {}
+
+}
+
+bool kt::ActiveUploadsGroup::isMember(TorrentInterface * tor)
+{
+ if (!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return s.running && s.completed;
+}
+
+
diff --git a/src/apps/ktorrent/groups/activeuploadsgroup.h b/src/apps/ktorrent/groups/activeuploadsgroup.h
new file mode 100644
index 0000000..02fd468
--- /dev/null
+++ b/src/apps/ktorrent/groups/activeuploadsgroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef ACTIVEUPLOADSGROUP_H
+#define ACTIVEUPLOADSGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for active uploads.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class ActiveUploadsGroup : public Group
+ {
+
+ public:
+ ActiveUploadsGroup();
+ virtual ~ActiveUploadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/allgroup.cpp b/src/apps/ktorrent/groups/allgroup.cpp
new file mode 100644
index 0000000..6b8ffb5
--- /dev/null
+++ b/src/apps/ktorrent/groups/allgroup.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include "allgroup.h"
+
+namespace kt
+{
+
+ AllGroup::AllGroup() : Group(i18n("All Torrents"),MIXED_GROUP)
+ {
+ setIconByName("folder");
+ }
+
+
+ AllGroup::~AllGroup()
+ {}
+
+
+ bool AllGroup::isMember(TorrentInterface* tor)
+ {
+ return tor != 0;
+ }
+
+}
diff --git a/src/apps/ktorrent/groups/allgroup.h b/src/apps/ktorrent/groups/allgroup.h
new file mode 100644
index 0000000..399691b
--- /dev/null
+++ b/src/apps/ktorrent/groups/allgroup.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTALLGROUP_H
+#define KTALLGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class AllGroup : public Group
+ {
+ public:
+ AllGroup();
+ virtual ~AllGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/downloadgroup.cpp b/src/apps/ktorrent/groups/downloadgroup.cpp
new file mode 100644
index 0000000..2dfcf0d
--- /dev/null
+++ b/src/apps/ktorrent/groups/downloadgroup.cpp
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+#include "downloadgroup.h"
+
+namespace kt
+{
+
+ DownloadGroup::DownloadGroup() : Group(i18n("Downloads"),DOWNLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-down");
+ }
+
+
+ DownloadGroup::~DownloadGroup()
+ {}
+
+
+ bool DownloadGroup::isMember(TorrentInterface* tor)
+ {
+ if (!tor)
+ return false;
+
+ return !tor->getStats().completed;
+ }
+
+}
diff --git a/src/apps/ktorrent/groups/downloadgroup.h b/src/apps/ktorrent/groups/downloadgroup.h
new file mode 100644
index 0000000..959f74b
--- /dev/null
+++ b/src/apps/ktorrent/groups/downloadgroup.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTDOWNLOADGROUP_H
+#define KTDOWNLOADGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class DownloadGroup : public Group
+ {
+ public:
+ DownloadGroup();
+ virtual ~DownloadGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/group.cpp b/src/apps/ktorrent/groups/group.cpp
new file mode 100644
index 0000000..7a3cbf2
--- /dev/null
+++ b/src/apps/ktorrent/groups/group.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <kiconloader.h>
+#include <tdeglobal.h>
+#include "group.h"
+
+namespace kt
+{
+
+ Group::Group(const TQString & name,int flags) : name(name),flags(flags)
+ {}
+
+
+ Group::~Group()
+ {}
+
+ void Group::save(bt::BEncoder*)
+ {
+ }
+
+ void Group::load(bt::BDictNode* )
+ {
+ }
+
+ void Group::setIconByName(const TQString & in)
+ {
+ icon_name = in;
+ icon = TDEGlobal::iconLoader()->loadIcon(in,TDEIcon::Small);
+ }
+
+ void Group::rename(const TQString & nn)
+ {
+ name = nn;
+ }
+
+ void Group::torrentRemoved(TorrentInterface* )
+ {}
+
+ void Group::removeTorrent(TorrentInterface* )
+ {}
+
+ void Group::addTorrent(TorrentInterface* )
+ {}
+}
diff --git a/src/apps/ktorrent/groups/group.h b/src/apps/ktorrent/groups/group.h
new file mode 100644
index 0000000..9f4775d
--- /dev/null
+++ b/src/apps/ktorrent/groups/group.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTGROUP_H
+#define KTGROUP_H
+
+#include <tqstring.h>
+#include <tqpixmap.h>
+
+namespace bt
+{
+ class BEncoder;
+ class BDictNode;
+}
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * Base class for all groups. Subclasses should only implement the
+ * isMember function, but can also provide save and load
+ * functionality.
+ */
+ class Group
+ {
+ protected:
+ TQString name;
+ TQPixmap icon;
+ TQString icon_name;
+ int flags;
+ public:
+ enum Properties
+ {
+ UPLOADS_ONLY_GROUP = 1,
+ DOWNLOADS_ONLY_GROUP = 2,
+ MIXED_GROUP = 3,
+ CUSTOM_GROUP = 4
+ };
+ /**
+ * Create a new group.
+ * @param name The name of the group
+ * @param flags Properties of the group
+ */
+ Group(const TQString & name,int flags);
+ virtual ~Group();
+
+ /// See if this is a standard group.
+ bool isStandardGroup() const {return !(flags & CUSTOM_GROUP);}
+
+ /// Get the group flags
+ int groupFlags() const {return flags;}
+
+ /**
+ * Rename the group.
+ * @param nn The new name
+ */
+ void rename(const TQString & nn);
+
+ /**
+ * Set the group icon by name.
+ * @param in The icon name
+ */
+ void setIconByName(const TQString & in);
+
+ /// Get the name of the group
+ const TQString & groupName() const {return name;}
+
+ /// Get the icon of the group
+ const TQPixmap & groupIcon() const {return icon;}
+
+ /**
+ * Save the torrents.The torrents should be save in a bencoded file.
+ * @param enc The BEncoder
+ */
+ virtual void save(bt::BEncoder* enc);
+
+
+ /**
+ * Load the torrents of the group from a BDictNode.
+ * @param n The BDictNode
+ */
+ virtual void load(bt::BDictNode* n);
+
+
+ /**
+ * Test if a torrent is a member of this group.
+ * @param tor The torrent
+ */
+ virtual bool isMember(TorrentInterface* tor) = 0;
+
+ /**
+ * The torrent has been removed and is about to be deleted.
+ * Subclasses should make sure that they don't have dangling
+ * pointers to this torrent.
+ * @param tor The torrent
+ */
+ virtual void torrentRemoved(TorrentInterface* tor);
+
+ /**
+ * Subclasses should implement this, if they want to have torrents added to them.
+ * @param tor The torrent
+ */
+ virtual void addTorrent(TorrentInterface* tor);
+
+ /**
+ * Subclasses should implement this, if they want to have torrents removed from them.
+ * @param tor The torrent
+ */
+ virtual void removeTorrent(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/groupmanager.cpp b/src/apps/ktorrent/groups/groupmanager.cpp
new file mode 100644
index 0000000..6cfd193
--- /dev/null
+++ b/src/apps/ktorrent/groups/groupmanager.cpp
@@ -0,0 +1,221 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <util/log.h>
+#include <util/file.h>
+#include <util/fileops.h>
+#include <util/error.h>
+#include <torrent/bnode.h>
+#include <torrent/bdecoder.h>
+#include <torrent/bencoder.h>
+#include "groupmanager.h"
+#include "torrentgroup.h"
+#include "allgroup.h"
+#include "downloadgroup.h"
+#include "uploadgroup.h"
+#include "torrentgroup.h"
+#include "queueddownloadsgroup.h"
+#include "queueduploadsgroup.h"
+#include "userdownloadsgroup.h"
+#include "useruploadsgroup.h"
+#include "inactivegroup.h"
+#include "inactivedownloadsgroup.h"
+#include "inactiveuploadsgroup.h"
+#include "activegroup.h"
+#include "activedownloadsgroup.h"
+#include "activeuploadsgroup.h"
+
+using namespace bt;
+
+namespace kt
+{
+
+ GroupManager::GroupManager()
+ {
+ setAutoDelete(true);
+ default_groups.setAutoDelete(true);
+
+ Group* g = new AllGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new UploadGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new DownloadGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new QueuedDownloadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new QueuedUploadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new UserDownloadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new UserUploadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new ActiveGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new ActiveUploadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new ActiveDownloadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new InactiveGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new InactiveUploadsGroup();
+ default_groups.insert(g->groupName(),g);
+
+ g = new InactiveDownloadsGroup();
+ default_groups.insert(g->groupName(),g);
+ }
+
+
+ GroupManager::~GroupManager()
+ {
+ }
+
+
+ Group* GroupManager::newGroup(const TQString & name)
+ {
+ if (find(name))
+ return 0;
+
+ Group* g = new TorrentGroup(name);
+ insert(name,g);
+ return g;
+ }
+
+ bool GroupManager::canRemove(const Group* g) const
+ {
+ return default_groups.find(g->groupName()) == 0;
+ }
+
+
+ void GroupManager::saveGroups(const TQString & fn)
+ {
+ bt::File fptr;
+ if (!fptr.open(fn,"wb"))
+ {
+ bt::Out() << "Cannot open " << fn << " : " << fptr.errorString() << bt::endl;
+ return;
+ }
+
+ try
+ {
+ bt::BEncoder enc(&fptr);
+
+ enc.beginList();
+ for (iterator i = begin();i != end();i++)
+ {
+ i->second->save(&enc);
+ }
+ enc.end();
+ }
+ catch (bt::Error & err)
+ {
+ bt::Out() << "Error : " << err.toString() << endl;
+ return;
+ }
+ }
+
+
+
+ void GroupManager::loadGroups(const TQString & fn)
+ {
+ bt::File fptr;
+ if (!fptr.open(fn,"rb"))
+ {
+ bt::Out() << "Cannot open " << fn << " : " << fptr.errorString() << bt::endl;
+ return;
+ }
+ try
+ {
+ Uint32 fs = bt::FileSize(fn);
+ TQByteArray data(fs);
+ fptr.read(data.data(),fs);
+
+ BDecoder dec(data,false);
+ bt::BNode* n = dec.decode();
+ if (!n || n->getType() != bt::BNode::LIST)
+ throw bt::Error("groups file corrupt");
+
+ BListNode* ln = (BListNode*)n;
+ for (Uint32 i = 0;i < ln->getNumChildren();i++)
+ {
+ BDictNode* dn = ln->getDict(i);
+ if (!dn)
+ continue;
+
+ TorrentGroup* g = new TorrentGroup("dummy");
+
+ try
+ {
+ g->load(dn);
+ }
+ catch (...)
+ {
+ delete g;
+ throw;
+ }
+
+ if (!find(g->groupName()))
+ insert(g->groupName(),g);
+ else
+ delete g;
+ }
+ }
+ catch (bt::Error & err)
+ {
+ bt::Out() << "Error : " << err.toString() << endl;
+ return;
+ }
+ }
+
+ void GroupManager::torrentRemoved(TorrentInterface* ti)
+ {
+ for (iterator i = begin(); i != end();i++)
+ {
+ i->second->torrentRemoved(ti);
+ }
+ }
+
+ void GroupManager::renameGroup(const TQString & old_name,const TQString & new_name)
+ {
+ Group* g = find(old_name);
+ if (!g)
+ return;
+
+ setAutoDelete(false);
+ erase(old_name);
+ g->rename(new_name);
+ insert(new_name,g);
+ setAutoDelete(true);
+ }
+
+ Group* GroupManager::findDefault(const TQString & name)
+ {
+ return default_groups.find(name);
+ }
+}
diff --git a/src/apps/ktorrent/groups/groupmanager.h b/src/apps/ktorrent/groups/groupmanager.h
new file mode 100644
index 0000000..a2fa4fd
--- /dev/null
+++ b/src/apps/ktorrent/groups/groupmanager.h
@@ -0,0 +1,133 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTGROUPMANAGER_H
+#define KTGROUPMANAGER_H
+
+#include <tqstring.h>
+#include <tdelocale.h>
+#include <util/ptrmap.h>
+#include <libktorrent_export.h>
+
+
+namespace kt
+{
+ class Group;
+ class TorrentInterface;
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * Manages all user created groups and the standard groups.
+ */
+ class LIBKTORRENT_EXPORT GroupManager : public bt::PtrMap<TQString,Group>
+ {
+ bt::PtrMap<TQString,Group> default_groups;
+
+ public:
+ GroupManager();
+ virtual ~GroupManager();
+
+ /**
+ * Create a new user created group.
+ * @param name Name of the group
+ * @return Pointer to the group or NULL, if another group already exists with the same name.
+ */
+ Group* newGroup(const TQString & name);
+
+ /// Get the group off all torrents
+ Group* allGroup() {return findDefault(i18n("All Torrents"));}
+
+ /// Get the group of downloads
+ Group* downloadGroup() {return findDefault(i18n("Downloads"));}
+
+ /// Get the group of seeds
+ Group* uploadGroup() {return findDefault(i18n("Uploads"));}
+
+ /// Get the group of queued downloads
+ Group* queuedDownloadsGroup() { return findDefault(i18n("Queued downloads")); }
+
+ /// Get the group of queued seeds
+ Group* queuedUploadsGroup() { return findDefault(i18n("Queued uploads")); }
+
+ /// Get the group of user controlled downloads
+ Group* userDownloadsGroup() { return findDefault(i18n("User downloads")); }
+
+ /// Get the group of user controlled seeds
+ Group* userUploadsGroup() { return findDefault(i18n("User uploads")); }
+
+ /// Get the group of inactive torrents
+ Group* inactiveGroup() { return findDefault(i18n("Inactive torrents")); }
+
+ /// Get the group of inactive downloads
+ Group* inactiveDownloadsGroup() { return findDefault(i18n("Inactive downloads")); }
+
+ /// Get the group of inactive uploads
+ Group* inactiveUploadsGroup() { return findDefault(i18n("Inactive uploads")); }
+
+ /// Get the group of inactive torrents
+ Group* activeGroup() { return findDefault(i18n("Active torrents")); }
+
+ /// Get the group of inactive downloads
+ Group* activeDownloadsGroup() { return findDefault(i18n("Active downloads")); }
+
+ /// Get the group of inactive uploads
+ Group* activeUploadsGroup() { return findDefault(i18n("Active uploads")); }
+
+ /// Find a default group by the given name
+ Group* findDefault(const TQString & name);
+
+ /**
+ * Save the groups to a file.
+ * @param fn The filename
+ */
+ void saveGroups(const TQString & fn);
+
+ /**
+ * Load the groups from a file
+ * @param fn The filename
+ */
+ void loadGroups(const TQString & fn);
+
+ /**
+ * See if we can remove a group.
+ * @param g The group
+ * @return true on any user created group, false on the standard ones
+ */
+ bool canRemove(const Group* g) const;
+
+ /**
+ * A torrent has been removed. This function checks all groups and
+ * removes the torrent from it.
+ * @param ti The torrent
+ */
+ void torrentRemoved(TorrentInterface* ti);
+
+ /**
+ * Rename a group.
+ * @param old_name The old name
+ * @param new_name The new name
+ */
+ void renameGroup(const TQString & old_name,const TQString & new_name);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/groupview.cpp b/src/apps/ktorrent/groups/groupview.cpp
new file mode 100644
index 0000000..eeef28b
--- /dev/null
+++ b/src/apps/ktorrent/groups/groupview.cpp
@@ -0,0 +1,360 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <tdeglobal.h>
+#include <kiconloader.h>
+#include <tdepopupmenu.h>
+#include <tdeaction.h>
+#include <tdemessagebox.h>
+#include <kinputdialog.h>
+#include <tdestandarddirs.h>
+#include <tdepopupmenu.h>
+#include <tqheader.h>
+#include <util/log.h>
+#include <interfaces/torrentinterface.h>
+#include "groupview.h"
+#include "group.h"
+#include "groupmanager.h"
+#include "torrentgroup.h"
+#include "../viewmanager.h"
+#include "../ktorrentview.h"
+
+
+using namespace bt;
+
+namespace kt
+{
+ GroupViewItem::GroupViewItem(GroupView* parent,Group* g) : TDEListViewItem(parent),gview(parent)
+ {
+ setText(0,g->groupName());
+ setPixmap(0,g->groupIcon());
+ }
+
+ GroupViewItem::GroupViewItem(GroupView* gview,TDEListViewItem* parent,Group* g) : TDEListViewItem(parent),gview(gview)
+ {
+ setText(0,g->groupName());
+ setPixmap(0,g->groupIcon());
+ }
+
+ GroupViewItem::~GroupViewItem()
+ {
+ }
+
+ int GroupViewItem::compare(TQListViewItem* i,int ,bool ) const
+ {
+ if (text(1).isNull() && i->text(1).isNull())
+ return TQString::compare(text(0),i->text(0));
+ else
+ return TQString::compare(text(1),i->text(1));
+ }
+
+ GroupView::GroupView(ViewManager* view,TDEActionCollection* col,TQWidget *parent, const char *name)
+ : TDEListView(parent, name),view(view),custom_root(0)
+ {
+ setFullWidth(true);
+ setRootIsDecorated(true);
+ setAcceptDrops(true);
+ setDropHighlighter(true);
+ setDropVisualizer(true);
+ addColumn(i18n("Groups"));
+ header()->hide();
+
+ gman = new GroupManager();
+
+ current = gman->allGroup();
+
+ connect(this,TQ_SIGNAL(clicked(TQListViewItem*)),this,TQ_SLOT(onExecuted( TQListViewItem* )));
+ connect(this,TQ_SIGNAL(contextMenu(TDEListView*,TQListViewItem*,const TQPoint & )),
+ this,TQ_SLOT(showContextMenu( TDEListView*, TQListViewItem*, const TQPoint& )));
+ connect(this,TQ_SIGNAL(dropped(TQDropEvent*,TQListViewItem*)),
+ this,TQ_SLOT(onDropped( TQDropEvent*, TQListViewItem* )));
+
+ current_item = 0;
+ menu = 0;
+ createMenu(col);
+ save_file = TDEGlobal::dirs()->saveLocation("data","ktorrent") + "groups";
+ GroupViewItem* all = addGroup(gman->allGroup(),0);
+ GroupViewItem* dwnld = addGroup(gman->downloadGroup(),all);
+ GroupViewItem* upld = addGroup(gman->uploadGroup(),all);
+ GroupViewItem* inactive = addGroup(gman->inactiveGroup(), all);
+ GroupViewItem* active = addGroup(gman->activeGroup(), all);
+ addGroup(gman->queuedDownloadsGroup(), dwnld);
+ addGroup(gman->queuedUploadsGroup(), upld);
+ addGroup(gman->userDownloadsGroup(), dwnld);
+ addGroup(gman->userUploadsGroup(), upld);
+ addGroup(gman->inactiveDownloadsGroup(), inactive);
+ addGroup(gman->inactiveUploadsGroup(), inactive);
+ addGroup(gman->activeDownloadsGroup(), active);
+ addGroup(gman->activeUploadsGroup(), active);
+
+ custom_root = new TDEListViewItem(all,i18n("Custom Groups"));
+ custom_root->setPixmap(0,TDEGlobal::iconLoader()->loadIcon("folder",TDEIcon::Small));
+ setOpen(custom_root,true);
+ }
+
+
+ GroupView::~GroupView()
+ {
+ delete gman;
+ }
+
+ void GroupView::saveGroups()
+ {
+ gman->saveGroups(save_file);
+ }
+
+ void GroupView::loadGroups()
+ {
+ // load the groups from the groups file
+ gman->loadGroups(save_file);
+ for (GroupManager::iterator i = gman->begin();i != gman->end();i++)
+ {
+ addGroup(i->second,custom_root);
+ }
+ sort();
+ }
+
+ void GroupView::createMenu(TDEActionCollection* col)
+ {
+ menu = new TDEPopupMenu(this);
+
+ new_group = new TDEAction(i18n("New Group"),"document-new",0,
+ this, TQ_SLOT(addGroup()),col, "New Group");
+
+ edit_group = new TDEAction(i18n("Edit Name"),"edit",0,
+ this, TQ_SLOT(editGroupName()),col,"Edit Group Name");
+
+ remove_group = new TDEAction(i18n("Remove Group"),"remove",0,
+ this, TQ_SLOT(removeGroup()),col,"Remove Group");
+
+ open_in_new_tab = new TDEAction(i18n("Open Tab"),"document-open",0,
+ this ,TQ_SLOT(openView()),col,"Open Tab");
+
+ open_in_new_tab->plug(menu);
+ menu->insertSeparator();
+ new_group->plug(menu);
+ edit_group->plug(menu);
+ remove_group->plug(menu);
+ }
+
+ void GroupView::addGroup()
+ {
+ TQString name = KInputDialog::getText(TQString(),i18n("Please enter the group name."));
+
+ if (name.isNull() || name.length() == 0)
+ return;
+
+ if (gman->find(name))
+ {
+ KMessageBox::error(this,i18n("The group %1 already exists.").arg(name));
+ return;
+ }
+
+ addGroup(gman->newGroup(name),custom_root);
+ saveGroups();
+ sort();
+ }
+
+ void GroupView::removeGroup()
+ {
+ if (!current_item)
+ return;
+
+ Group* g = groups.find(current_item);
+ if (!g)
+ return;
+
+ groupRemoved(g);
+ if (g == current)
+ {
+ current = gman->allGroup();
+ currentGroupChanged(current);
+ }
+
+ groups.erase(current_item);
+ gman->erase(g->groupName());
+ delete current_item;
+ current_item = 0;
+ saveGroups();
+ }
+
+ void GroupView::editGroupName()
+ {
+ if (!current_item)
+ return;
+
+ Group* g = groups.find(current_item);
+ if (!g)
+ return;
+
+ TQString name = KInputDialog::getText(TQString(),i18n("Please enter the new group name."),g->groupName());
+
+ if (name.isNull() || name.length() == 0)
+ return;
+
+ if (g->groupName() == name)
+ return;
+
+ if (gman->find(name))
+ {
+ KMessageBox::error(this,i18n("The group %1 already exists.").arg(name));
+ }
+ else
+ {
+ gman->renameGroup(g->groupName(),name);
+ current_item->setText(0,name);
+ groupRenamed(g);
+ saveGroups();
+ sort();
+ }
+ }
+
+ GroupViewItem* GroupView::addGroup(Group* g,TDEListViewItem* parent)
+ {
+ GroupViewItem* li = 0;
+ if (parent)
+ {
+ li = new GroupViewItem(this,parent,g);
+ }
+ else
+ {
+ li = new GroupViewItem(this,g);
+ li->setText(1,g->groupName());
+ }
+
+ groups.insert(li,g);
+ if (custom_root && custom_root->childCount() == 1 && custom_root == parent)
+ setOpen(custom_root,true);
+
+ return li;
+ }
+
+ void GroupView::showContextMenu(TDEListView* ,TQListViewItem* item,const TQPoint & p)
+ {
+ current_item = dynamic_cast<GroupViewItem*>(item);
+
+ Group* g = 0;
+ if (current_item)
+ g = groups.find(current_item);
+
+ if (!g ||!gman->canRemove(g))
+ {
+ edit_group->setEnabled(false);
+ remove_group->setEnabled(false);
+ }
+ else
+ {
+ edit_group->setEnabled(true);
+ remove_group->setEnabled(true);
+ }
+
+ open_in_new_tab->setEnabled(g != 0);
+
+ menu->popup(p);
+ }
+
+ void GroupView::onExecuted(TQListViewItem* item)
+ {
+ if (!item) return;
+
+ GroupViewItem* li = dynamic_cast<GroupViewItem*>(item);
+ if (!li)
+ return;
+
+ Group* g = groups.find(li);
+ if (g)
+ {
+ current = g;
+ currentGroupChanged(g);
+ }
+ }
+
+ void GroupView::onDropped(TQDropEvent* e,TQListViewItem *after)
+ {
+ GroupViewItem* li = dynamic_cast<GroupViewItem*>(after);
+ if (!li)
+ return;
+
+ TorrentGroup* g = dynamic_cast<TorrentGroup*>(groups.find(li));
+ if (g)
+ {
+ TQValueList<TorrentInterface*> sel;
+ view->getSelection(sel);
+ TQValueList<TorrentInterface*>::iterator i = sel.begin();
+ while (i != sel.end())
+ {
+ g->add(*i);
+ i++;
+ }
+ saveGroups();
+ }
+ }
+
+ bool GroupView::acceptDrag(TQDropEvent* event) const
+ {
+ return event->provides("application/x-ktorrent-drag-object");
+ }
+
+ void GroupView::onTorrentRemoved(kt::TorrentInterface* tc)
+ {
+ gman->torrentRemoved(tc);
+ saveGroups();
+ }
+
+ void GroupView::updateGroupsSubMenu(TDEPopupMenu* gsm)
+ {
+ gsm->clear();
+ for (GroupManager::iterator i = gman->begin();i != gman->end();i++)
+ {
+ gsm->insertItem(i->first);
+ }
+ }
+
+ void GroupView::onGroupsSubMenuItemActivated(KTorrentView* v,const TQString & group)
+ {
+ Group* g = gman->find(group);
+ if (g)
+ {
+ v->addSelectionToGroup(g);
+ saveGroups();
+ }
+ }
+
+ const Group* GroupView::findGroup(const TQString & name) const
+ {
+ Group* g = gman->find(name);
+ if (!g)
+ g = gman->findDefault(name);
+
+ return g;
+ }
+
+ void GroupView::openView()
+ {
+ if (!current_item)
+ return;
+
+ Group* g = groups.find(current_item);
+ if (g)
+ openNewTab(g);
+ }
+}
+
+#include "groupview.moc"
diff --git a/src/apps/ktorrent/groups/groupview.h b/src/apps/ktorrent/groups/groupview.h
new file mode 100644
index 0000000..00a47ed
--- /dev/null
+++ b/src/apps/ktorrent/groups/groupview.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTGROUPVIEW_H
+#define KTGROUPVIEW_H
+
+#include <tdelistview.h>
+#include <util/ptrmap.h>
+
+class TDEPopupMenu;
+class TDEActionCollection;
+class ViewManager;
+class KTorrentView;
+
+namespace kt
+{
+ class Group;
+ class GroupView;
+ class GroupManager;
+ class TorrentInterface;
+
+ class GroupViewItem : public TDEListViewItem
+ {
+ Group* g;
+ GroupView* gview;
+ public:
+ GroupViewItem(GroupView* parent,Group* g);
+ GroupViewItem(GroupView* gview,TDEListViewItem* parent,Group* g);
+ virtual ~GroupViewItem();
+
+ virtual int compare(TQListViewItem* i,int col,bool ascending) const;
+ };
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class GroupView : public TDEListView
+ {
+ TQ_OBJECT
+
+ public:
+ GroupView(ViewManager* view,TDEActionCollection* col,TQWidget *parent = 0, const char *name = 0);
+ virtual ~GroupView();
+
+ /// Get the current group
+ Group* currentGroup() {return current;}
+
+ /// Save all groups
+ void saveGroups();
+
+ /// Load groups
+ void loadGroups();
+
+ /// Find a group by its name
+ const Group* findGroup(const TQString & name) const;
+
+ GroupManager* groupManager() const { return gman; }
+
+ public slots:
+ void onTorrentRemoved(kt::TorrentInterface* tc);
+
+ /// Update a groups sub menu
+ void updateGroupsSubMenu(TDEPopupMenu* gsm);
+
+ /// An item was activated in the groups sub menu of a KTorrentView
+ void onGroupsSubMenuItemActivated(KTorrentView* v,const TQString & group);
+
+ private slots:
+ void onExecuted(TQListViewItem* item);
+ void showContextMenu(TDEListView* ,TQListViewItem* item,const TQPoint & p);
+ void addGroup();
+ void removeGroup();
+ void editGroupName();
+ void onDropped(TQDropEvent* e,TQListViewItem *after);
+ virtual bool acceptDrag(TQDropEvent* event) const;
+ void openView();
+
+
+ signals:
+ void currentGroupChanged(kt::Group* g);
+ void groupRenamed(kt::Group* g);
+ void openNewTab(kt::Group* g);
+ void groupRemoved(kt::Group* g);
+
+ private:
+ void createMenu(TDEActionCollection* col);
+ GroupViewItem* addGroup(Group* g,TDEListViewItem* parent);
+
+ private:
+ ViewManager* view;
+ TDEListViewItem* custom_root;
+ bt::PtrMap<GroupViewItem*,Group> groups;
+ GroupManager* gman;
+ TQString save_file;
+
+ Group* current;
+
+ GroupViewItem* current_item;
+ TDEPopupMenu* menu;
+ TDEAction* new_group;
+ TDEAction* edit_group;
+ TDEAction* remove_group;
+ TDEAction* open_in_new_tab;
+
+ friend class GroupViewItem;
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/inactivedownloadsgroup.cpp b/src/apps/ktorrent/groups/inactivedownloadsgroup.cpp
new file mode 100644
index 0000000..c6b37bc
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactivedownloadsgroup.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "inactivedownloadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ InactiveDownloadsGroup::InactiveDownloadsGroup()
+ : Group(i18n("Inactive downloads"), DOWNLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-down");
+ }
+
+
+ InactiveDownloadsGroup::~InactiveDownloadsGroup()
+ {}
+
+}
+
+bool kt::InactiveDownloadsGroup::isMember(TorrentInterface * tor)
+{
+ if (!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return !s.running && !s.completed;
+}
+
+
diff --git a/src/apps/ktorrent/groups/inactivedownloadsgroup.h b/src/apps/ktorrent/groups/inactivedownloadsgroup.h
new file mode 100644
index 0000000..4b80ca6
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactivedownloadsgroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef INACTIVEDOWNLOADSGROUP_H
+#define INACTIVEDOWNLOADSGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for inactive downloads.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class InactiveDownloadsGroup : public Group
+ {
+
+ public:
+ InactiveDownloadsGroup();
+ virtual ~InactiveDownloadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/inactivegroup.cpp b/src/apps/ktorrent/groups/inactivegroup.cpp
new file mode 100644
index 0000000..326436f
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactivegroup.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "inactivegroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+InactiveGroup::InactiveGroup()
+ : Group(i18n("Inactive torrents"),MIXED_GROUP)
+{
+ setIconByName("metacontact_offline");
+}
+
+
+InactiveGroup::~InactiveGroup()
+{}
+
+}
+
+bool kt::InactiveGroup::isMember(TorrentInterface * tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+ return !s.running;
+}
+
+
diff --git a/src/apps/ktorrent/groups/inactivegroup.h b/src/apps/ktorrent/groups/inactivegroup.h
new file mode 100644
index 0000000..027138f
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactivegroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef INACTIVEGROUP_H
+#define INACTIVEGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for inactive torrents.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class InactiveGroup : public Group
+ {
+
+ public:
+ InactiveGroup();
+ virtual ~InactiveGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/inactiveuploadsgroup.cpp b/src/apps/ktorrent/groups/inactiveuploadsgroup.cpp
new file mode 100644
index 0000000..967dc9c
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactiveuploadsgroup.cpp
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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 "inactiveuploadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ InactiveUploadsGroup::InactiveUploadsGroup()
+ : Group(i18n("Inactive uploads"), UPLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-up");
+ }
+
+
+ InactiveUploadsGroup::~InactiveUploadsGroup()
+ {}
+
+}
+
+bool kt::InactiveUploadsGroup::isMember(TorrentInterface * tor)
+{
+ if (!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return !s.running && s.completed;
+}
+
+
diff --git a/src/apps/ktorrent/groups/inactiveuploadsgroup.h b/src/apps/ktorrent/groups/inactiveuploadsgroup.h
new file mode 100644
index 0000000..78e1840
--- /dev/null
+++ b/src/apps/ktorrent/groups/inactiveuploadsgroup.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2007 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef INACTIVEUPLOADSGROUP_H
+#define INACTIVEUPLOADSGROUP_H
+
+#include "group.h"
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Group for inactive uploads.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+
+ class InactiveUploadsGroup : public Group
+ {
+
+ public:
+ InactiveUploadsGroup();
+ virtual ~InactiveUploadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+}
+#endif
diff --git a/src/apps/ktorrent/groups/queueddownloadsgroup.cpp b/src/apps/ktorrent/groups/queueddownloadsgroup.cpp
new file mode 100644
index 0000000..36fab9f
--- /dev/null
+++ b/src/apps/ktorrent/groups/queueddownloadsgroup.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "queueddownloadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ QueuedDownloadsGroup::QueuedDownloadsGroup()
+ : Group(i18n("Queued downloads"),DOWNLOADS_ONLY_GROUP)
+ {
+ setIconByName("ktqueuemanager");
+ }
+
+
+ QueuedDownloadsGroup::~QueuedDownloadsGroup()
+ {}
+}
+
+bool kt::QueuedDownloadsGroup::isMember(TorrentInterface* tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return !s.user_controlled && !s.completed;
+}
diff --git a/src/apps/ktorrent/groups/queueddownloadsgroup.h b/src/apps/ktorrent/groups/queueddownloadsgroup.h
new file mode 100644
index 0000000..019a69c
--- /dev/null
+++ b/src/apps/ktorrent/groups/queueddownloadsgroup.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef KQUEUEDDOWNLOADSGROUP_H
+#define KQUEUEDDOWNLOADSGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Torrents that are queued and in downloading phase.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+ class QueuedDownloadsGroup : public Group
+ {
+ public:
+ QueuedDownloadsGroup();
+ virtual ~QueuedDownloadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/queueduploadsgroup.cpp b/src/apps/ktorrent/groups/queueduploadsgroup.cpp
new file mode 100644
index 0000000..c51ab42
--- /dev/null
+++ b/src/apps/ktorrent/groups/queueduploadsgroup.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "queueduploadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ QueuedUploadsGroup::QueuedUploadsGroup()
+ : Group(i18n("Queued uploads"),UPLOADS_ONLY_GROUP)
+ {
+ setIconByName("ktqueuemanager");
+ }
+
+
+ QueuedUploadsGroup::~QueuedUploadsGroup()
+ {}
+}
+
+bool kt::QueuedUploadsGroup::isMember(TorrentInterface* tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return !s.user_controlled && s.completed;
+}
diff --git a/src/apps/ktorrent/groups/queueduploadsgroup.h b/src/apps/ktorrent/groups/queueduploadsgroup.h
new file mode 100644
index 0000000..601e02f
--- /dev/null
+++ b/src/apps/ktorrent/groups/queueduploadsgroup.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef KQUEUEDUPLOADSGROUP_H
+#define KQUEUEDUPLOADSGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Torrents that are queued and in seeding phase.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+ class QueuedUploadsGroup : public Group
+ {
+ public:
+ QueuedUploadsGroup();
+ virtual ~QueuedUploadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/torrentdrag.cpp b/src/apps/ktorrent/groups/torrentdrag.cpp
new file mode 100644
index 0000000..c7296fe
--- /dev/null
+++ b/src/apps/ktorrent/groups/torrentdrag.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <kiconloader.h>
+#include <tdeglobal.h>
+#include "torrentdrag.h"
+
+namespace kt
+{
+
+ TorrentDrag::TorrentDrag(TQWidget* src, const char *name) : TQStoredDrag("application/x-ktorrent-drag-object",src, name)
+ {
+ setPixmap(TDEGlobal::iconLoader()->loadIcon("player_playlist",TDEIcon::Small));
+ }
+
+
+ TorrentDrag::~TorrentDrag()
+ {}
+
+}
+#include "torrentdrag.moc"
diff --git a/src/apps/ktorrent/groups/torrentdrag.h b/src/apps/ktorrent/groups/torrentdrag.h
new file mode 100644
index 0000000..6943d18
--- /dev/null
+++ b/src/apps/ktorrent/groups/torrentdrag.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTTORRENTDRAG_H
+#define KTTORRENTDRAG_H
+
+#include <tqdragobject.h>
+
+namespace kt
+{
+
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class TorrentDrag : public TQStoredDrag
+ {
+ TQ_OBJECT
+
+ public:
+ TorrentDrag(TQWidget* src,const char *name = 0);
+ virtual ~TorrentDrag();
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/torrentgroup.cpp b/src/apps/ktorrent/groups/torrentgroup.cpp
new file mode 100644
index 0000000..d44b744
--- /dev/null
+++ b/src/apps/ktorrent/groups/torrentgroup.cpp
@@ -0,0 +1,147 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <util/log.h>
+#include <util/error.h>
+#include <util/sha1hash.h>
+#include <torrent/bencoder.h>
+#include <torrent/bnode.h>
+#include <interfaces/torrentinterface.h>
+#include "torrentgroup.h"
+
+using namespace bt;
+
+namespace kt
+{
+
+ TorrentGroup::TorrentGroup(const TQString& name): Group(name,MIXED_GROUP|CUSTOM_GROUP)
+ {
+ setIconByName("player_playlist");
+ }
+
+
+ TorrentGroup::~TorrentGroup()
+ {}
+
+
+ bool TorrentGroup::isMember(TorrentInterface* tor)
+ {
+ if (torrents.count(tor) > 0)
+ return true;
+
+
+ if (!hashes.empty())
+ {
+ if (hashes.count(tor->getInfoHash()))
+ {
+ /* bt::Out(SYS_GEN|LOG_DEBUG) <<
+ TQString("TG %1 : Torrent %2 from hashes list").arg(groupName()).arg(tor->getStats().torrent_name) << endl;
+ */
+ hashes.erase(tor->getInfoHash());
+ torrents.insert(tor);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void TorrentGroup::add(TorrentInterface* tor)
+ {
+ torrents.insert(tor);
+ }
+
+ void TorrentGroup::remove(TorrentInterface* tor)
+ {
+ torrents.erase(tor);
+ }
+
+ void TorrentGroup::save(bt::BEncoder* enc)
+ {
+ enc->beginDict();
+ enc->write(TQString("name")); enc->write(name.local8Bit());
+ enc->write(TQString("icon")); enc->write(icon_name.local8Bit());
+ enc->write(TQString("hashes")); enc->beginList();
+ std::set<TorrentInterface*>::iterator i = torrents.begin();
+ while (i != torrents.end())
+ {
+ TorrentInterface* tc = *i;
+ // write the info hash, because that will be unique for each torrent
+ const bt::SHA1Hash & h = tc->getInfoHash();
+ enc->write(h.getData(),20);
+ i++;
+ }
+ std::set<bt::SHA1Hash>::iterator j = hashes.begin();
+ while (j != hashes.end())
+ {
+ enc->write(j->getData(),20);
+ j++;
+ }
+ enc->end();
+ enc->end();
+ }
+
+ void TorrentGroup::load(bt::BDictNode* dn)
+ {
+ BValueNode* vn = dn->getValue("name");
+ if (!vn || vn->data().getType() != bt::Value::STRING)
+ throw bt::Error("invalid or missing name");
+
+ TQByteArray tmp = vn->data().toByteArray();
+ name = TQString::fromLocal8Bit(tmp.data(),tmp.size());
+
+ vn = dn->getValue("icon");
+ if (!vn || vn->data().getType() != bt::Value::STRING)
+ throw bt::Error("invalid or missing icon");
+
+ tmp = vn->data().toByteArray();
+ setIconByName(TQString::fromLocal8Bit(tmp.data(),tmp.size()));
+
+ BListNode* ln = dn->getList("hashes");
+ if (!ln)
+ return;
+
+ for (Uint32 i = 0;i < ln->getNumChildren();i++)
+ {
+ vn = ln->getValue(i);
+ if (!vn || vn->data().getType() != bt::Value::STRING)
+ continue;
+
+ TQByteArray ba = vn->data().toByteArray();
+ if (ba.size() != 20)
+ continue;
+
+ hashes.insert(SHA1Hash((const Uint8*)ba.data()));
+ }
+ }
+
+ void TorrentGroup::torrentRemoved(TorrentInterface* tor)
+ {
+ torrents.erase(tor);
+ }
+
+ void TorrentGroup::removeTorrent(TorrentInterface* tor)
+ {
+ torrents.erase(tor);
+ }
+
+ void TorrentGroup::addTorrent(TorrentInterface* tor)
+ {
+ torrents.insert(tor);
+ }
+}
diff --git a/src/apps/ktorrent/groups/torrentgroup.h b/src/apps/ktorrent/groups/torrentgroup.h
new file mode 100644
index 0000000..432cffb
--- /dev/null
+++ b/src/apps/ktorrent/groups/torrentgroup.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTTORRENTGROUP_H
+#define KTTORRENTGROUP_H
+
+#include <set>
+#include <group.h>
+#include <util/sha1hash.h>
+#include <libktorrent_export.h>
+
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class LIBKTORRENT_EXPORT TorrentGroup : public Group
+ {
+ std::set<TorrentInterface*> torrents;
+ std::set<bt::SHA1Hash> hashes;
+ public:
+ TorrentGroup(const TQString& name);
+ virtual ~TorrentGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+ virtual void save(bt::BEncoder* enc);
+ virtual void load(bt::BDictNode* n);
+ virtual void torrentRemoved(TorrentInterface* tor);
+ virtual void removeTorrent(TorrentInterface* tor);
+ virtual void addTorrent(TorrentInterface* tor);
+
+ void add(TorrentInterface* tor);
+ void remove(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/uploadgroup.cpp b/src/apps/ktorrent/groups/uploadgroup.cpp
new file mode 100644
index 0000000..3a320b5
--- /dev/null
+++ b/src/apps/ktorrent/groups/uploadgroup.cpp
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+#include "uploadgroup.h"
+
+namespace kt
+{
+
+ UploadGroup::UploadGroup() : Group(i18n("Uploads"),UPLOADS_ONLY_GROUP)
+ {
+ setIconByName("go-up");
+ }
+
+
+ UploadGroup::~UploadGroup()
+ {}
+
+
+ bool UploadGroup::isMember(TorrentInterface* tor)
+ {
+ if (!tor)
+ return false;
+
+ return tor->getStats().completed;
+ }
+
+}
diff --git a/src/apps/ktorrent/groups/uploadgroup.h b/src/apps/ktorrent/groups/uploadgroup.h
new file mode 100644
index 0000000..f90a5bd
--- /dev/null
+++ b/src/apps/ktorrent/groups/uploadgroup.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTUPLOADGROUP_H
+#define KTUPLOADGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class UploadGroup : public Group
+ {
+ public:
+ UploadGroup();
+ virtual ~UploadGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/userdownloadsgroup.cpp b/src/apps/ktorrent/groups/userdownloadsgroup.cpp
new file mode 100644
index 0000000..ff1b13b
--- /dev/null
+++ b/src/apps/ktorrent/groups/userdownloadsgroup.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "userdownloadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ UserDownloadsGroup::UserDownloadsGroup()
+ : Group(i18n("User downloads"),DOWNLOADS_ONLY_GROUP)
+ {
+ setIconByName("userconfig");
+ }
+
+
+ UserDownloadsGroup::~UserDownloadsGroup()
+ {}
+}
+
+bool kt::UserDownloadsGroup::isMember(TorrentInterface* tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return s.user_controlled && !s.completed;
+}
diff --git a/src/apps/ktorrent/groups/userdownloadsgroup.h b/src/apps/ktorrent/groups/userdownloadsgroup.h
new file mode 100644
index 0000000..a77e7ac
--- /dev/null
+++ b/src/apps/ktorrent/groups/userdownloadsgroup.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef KTUSERDOWNLOADSGROUP_H
+#define KTUSERDOWNLOADSGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Torrents that are user controlled and in downloading phase.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+ class UserDownloadsGroup : public Group
+ {
+ public:
+ UserDownloadsGroup();
+ virtual ~UserDownloadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/groups/useruploadsgroup.cpp b/src/apps/ktorrent/groups/useruploadsgroup.cpp
new file mode 100644
index 0000000..f8c9d96
--- /dev/null
+++ b/src/apps/ktorrent/groups/useruploadsgroup.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "useruploadsgroup.h"
+
+#include <tdelocale.h>
+#include <interfaces/torrentinterface.h>
+
+namespace kt
+{
+
+ UserUploadsGroup::UserUploadsGroup()
+ : Group(i18n("User uploads"),UPLOADS_ONLY_GROUP)
+ {
+ setIconByName("userconfig");
+ }
+
+
+ UserUploadsGroup::~UserUploadsGroup()
+ {}
+}
+
+bool kt::UserUploadsGroup::isMember(TorrentInterface* tor)
+{
+ if(!tor)
+ return false;
+
+ const kt::TorrentStats& s = tor->getStats();
+
+ return s.user_controlled && s.completed;
+}
diff --git a/src/apps/ktorrent/groups/useruploadsgroup.h b/src/apps/ktorrent/groups/useruploadsgroup.h
new file mode 100644
index 0000000..9286c88
--- /dev/null
+++ b/src/apps/ktorrent/groups/useruploadsgroup.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef KTUSERUPLOADSGROUP_H
+#define KTUSERUPLOADSGROUP_H
+
+#include <group.h>
+
+namespace kt
+{
+ class TorrentInterface;
+
+ /**
+ * Torrents that are user controlled and in seeding phase.
+ * @author Ivan Vasic <ivasic@gmail.com>
+ */
+ class UserUploadsGroup : public Group
+ {
+ public:
+ UserUploadsGroup();
+ virtual ~UserUploadsGroup();
+
+ virtual bool isMember(TorrentInterface* tor);
+ };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/hi128-app-ktorrent.png b/src/apps/ktorrent/hi128-app-ktorrent.png
new file mode 100644
index 0000000..fbe2294
--- /dev/null
+++ b/src/apps/ktorrent/hi128-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi128-mime-torrent.png b/src/apps/ktorrent/hi128-mime-torrent.png
new file mode 100644
index 0000000..f8ee4f1
--- /dev/null
+++ b/src/apps/ktorrent/hi128-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi16-app-ktorrent.png b/src/apps/ktorrent/hi16-app-ktorrent.png
new file mode 100644
index 0000000..6956852
--- /dev/null
+++ b/src/apps/ktorrent/hi16-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi16-mime-torrent.png b/src/apps/ktorrent/hi16-mime-torrent.png
new file mode 100644
index 0000000..36c11bf
--- /dev/null
+++ b/src/apps/ktorrent/hi16-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktencrypted.png b/src/apps/ktorrent/hi22-action-ktencrypted.png
new file mode 100644
index 0000000..cb66fb9
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktencrypted.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktremove.png b/src/apps/ktorrent/hi22-action-ktremove.png
new file mode 100644
index 0000000..7df1928
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktremove.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktstart.png b/src/apps/ktorrent/hi22-action-ktstart.png
new file mode 100644
index 0000000..a55e49c
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktstart.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktstart_all.png b/src/apps/ktorrent/hi22-action-ktstart_all.png
new file mode 100644
index 0000000..f46ed84
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktstart_all.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktstop.png b/src/apps/ktorrent/hi22-action-ktstop.png
new file mode 100644
index 0000000..9c464de
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktstop.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-action-ktstop_all.png b/src/apps/ktorrent/hi22-action-ktstop_all.png
new file mode 100644
index 0000000..73b548b
--- /dev/null
+++ b/src/apps/ktorrent/hi22-action-ktstop_all.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-app-ktorrent.png b/src/apps/ktorrent/hi22-app-ktorrent.png
new file mode 100644
index 0000000..0b04e49
--- /dev/null
+++ b/src/apps/ktorrent/hi22-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi22-mime-torrent.png b/src/apps/ktorrent/hi22-mime-torrent.png
new file mode 100644
index 0000000..5e28465
--- /dev/null
+++ b/src/apps/ktorrent/hi22-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi32-app-ktorrent.png b/src/apps/ktorrent/hi32-app-ktorrent.png
new file mode 100644
index 0000000..b074bed
--- /dev/null
+++ b/src/apps/ktorrent/hi32-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi32-mime-torrent.png b/src/apps/ktorrent/hi32-mime-torrent.png
new file mode 100644
index 0000000..dbaca97
--- /dev/null
+++ b/src/apps/ktorrent/hi32-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi48-action-ktplugins.png b/src/apps/ktorrent/hi48-action-ktplugins.png
new file mode 100644
index 0000000..936fd6a
--- /dev/null
+++ b/src/apps/ktorrent/hi48-action-ktplugins.png
Binary files differ
diff --git a/src/apps/ktorrent/hi48-app-ktorrent.png b/src/apps/ktorrent/hi48-app-ktorrent.png
new file mode 100644
index 0000000..f2c81eb
--- /dev/null
+++ b/src/apps/ktorrent/hi48-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi48-mime-torrent.png b/src/apps/ktorrent/hi48-mime-torrent.png
new file mode 100644
index 0000000..95b3c0d
--- /dev/null
+++ b/src/apps/ktorrent/hi48-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-action-ktinfowidget.png b/src/apps/ktorrent/hi64-action-ktinfowidget.png
new file mode 100644
index 0000000..703696d
--- /dev/null
+++ b/src/apps/ktorrent/hi64-action-ktinfowidget.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-action-ktqueuemanager.png b/src/apps/ktorrent/hi64-action-ktqueuemanager.png
new file mode 100644
index 0000000..7e21b70
--- /dev/null
+++ b/src/apps/ktorrent/hi64-action-ktqueuemanager.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-action-ktupnp.png b/src/apps/ktorrent/hi64-action-ktupnp.png
new file mode 100644
index 0000000..2c7df7d
--- /dev/null
+++ b/src/apps/ktorrent/hi64-action-ktupnp.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-app-ktorrent.png b/src/apps/ktorrent/hi64-app-ktorrent.png
new file mode 100644
index 0000000..453488b
--- /dev/null
+++ b/src/apps/ktorrent/hi64-app-ktorrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-filesys-ktprefdownloads.png b/src/apps/ktorrent/hi64-filesys-ktprefdownloads.png
new file mode 100644
index 0000000..8efc3d8
--- /dev/null
+++ b/src/apps/ktorrent/hi64-filesys-ktprefdownloads.png
Binary files differ
diff --git a/src/apps/ktorrent/hi64-mime-torrent.png b/src/apps/ktorrent/hi64-mime-torrent.png
new file mode 100644
index 0000000..2e7f063
--- /dev/null
+++ b/src/apps/ktorrent/hi64-mime-torrent.png
Binary files differ
diff --git a/src/apps/ktorrent/hisc-app-ktorrent.svgz b/src/apps/ktorrent/hisc-app-ktorrent.svgz
new file mode 100644
index 0000000..3d068d8
--- /dev/null
+++ b/src/apps/ktorrent/hisc-app-ktorrent.svgz
Binary files differ
diff --git a/src/apps/ktorrent/hisc-mime-torrent.svgz b/src/apps/ktorrent/hisc-mime-torrent.svgz
new file mode 100644
index 0000000..beb7c28
--- /dev/null
+++ b/src/apps/ktorrent/hisc-mime-torrent.svgz
Binary files differ
diff --git a/src/apps/ktorrent/ipfilterwidget.cpp b/src/apps/ktorrent/ipfilterwidget.cpp
new file mode 100644
index 0000000..22c77f7
--- /dev/null
+++ b/src/apps/ktorrent/ipfilterwidget.cpp
@@ -0,0 +1,194 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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 "ipfilterwidget.h"
+
+#include <torrent/ipblocklist.h>
+#include <torrent/globals.h>
+#include <util/log.h>
+#include <util/constants.h>
+
+#include <tqstring.h>
+#include <tqstringlist.h>
+#include <tqregexp.h>
+#include <tqvalidator.h>
+
+#include <tdelistview.h>
+#include <klineedit.h>
+#include <tdesocketaddress.h>
+#include <tdefiledialog.h>
+#include <tdelocale.h>
+#include <tdemessagebox.h>
+
+#define MAX_RANGES 500
+
+using namespace bt;
+
+IPFilterWidget::IPFilterWidget(TQWidget *parent, const char *name)
+ :BlacklistWidgetBase(parent, name)
+{
+ IPBlocklist& ipfilter = IPBlocklist::instance();
+ TQStringList* blocklist = ipfilter.getBlocklist();
+
+ for (TQStringList::Iterator it = blocklist->begin(); it != blocklist->end(); ++it)
+ {
+ new TDEListViewItem(lstPeers, *it);
+ }
+
+ delete blocklist;
+}
+
+void IPFilterWidget::btnAdd_clicked()
+{
+ int var=0;
+
+ TQRegExp rx("([*]|[0-9]{1,3}).([*]|[0-9]{1,3}).([*]|[0-9]{1,3}).([*]|[0-9]{1,3})");
+ TQRegExpValidator v( rx,0);
+
+ TQString ip = peerIP->text();
+
+ if(v.validate( ip, var ) == TQValidator::Acceptable)
+ {
+ if(lstPeers->findItem(ip, 0) == 0)
+ new TDEListViewItem(lstPeers, ip);
+ }
+ else
+ KMessageBox::sorry(0, i18n("You must enter IP in format 'XXX.XXX.XXX.XXX'. You can also use wildcards for ranges like '127.0.0.*'."));
+}
+
+void IPFilterWidget::btnRemove_clicked()
+{
+ if(lstPeers->currentItem())
+ delete lstPeers->currentItem();
+}
+
+void IPFilterWidget::btnClear_clicked()
+{
+ lstPeers->clear();
+}
+
+void IPFilterWidget::btnOpen_clicked()
+{
+ TQString lf = KFileDialog::getOpenFileName(TQString(), "*.txt|",this,i18n("Choose a file"));
+
+ if(lf.isEmpty())
+ return;
+
+ btnClear_clicked();
+
+ loadFilter(lf);
+}
+
+void IPFilterWidget::btnSave_clicked()
+{
+ TQString sf = KFileDialog::getSaveFileName(TQString(),"*.txt|",this,i18n("Choose a filename to save under"));
+
+ if(sf.isEmpty())
+ return;
+
+ saveFilter(sf);
+}
+
+void IPFilterWidget::btnOk_clicked()
+{
+ btnApply_clicked();
+ this->accept();
+}
+
+void IPFilterWidget::btnApply_clicked()
+{
+ IPBlocklist& ipfilter = IPBlocklist::instance();
+
+ int count = 0;
+
+ TQStringList* peers = new TQStringList();
+
+ TQListViewItemIterator it(lstPeers);
+ while (it.current())
+ {
+ *peers << it.current()->text(0);
+ ++it;
+ ++count;
+ }
+
+ ipfilter.setBlocklist(peers);
+
+ delete peers;
+
+ Out(SYS_IPF|LOG_NOTICE) << "Loaded " << count << " blocked IP ranges." << endl;
+}
+
+void IPFilterWidget::saveFilter(TQString& fn)
+{
+ TQFile fptr(fn);
+
+ if (!fptr.open(IO_WriteOnly))
+ {
+ Out(SYS_GEN|LOG_NOTICE) << TQString("Could not open file %1 for writing.").arg(fn) << endl;
+ return;
+ }
+
+ TQTextStream out(&fptr);
+
+ TQListViewItemIterator it(lstPeers);
+ while (it.current())
+ {
+ out << it.current()->text(0) << ::endl;
+ ++it;
+ }
+
+ fptr.close();
+}
+
+void IPFilterWidget::loadFilter(TQString& fn)
+{
+ TQFile dat(fn);
+ dat.open(IO_ReadOnly);
+
+ TQTextStream stream( &dat );
+ TQString line;
+
+ TQRegExp rx("([*]|[0-9]{1,3}).([*]|[0-9]{1,3}).([*]|[0-9]{1,3}).([*]|[0-9]{1,3})");
+ TQRegExpValidator v( rx,0);
+
+
+ int i=0;
+ int var=0;
+ bool err = false;
+
+ while ( !stream.atEnd() && i < MAX_RANGES )
+ {
+ line = stream.readLine();
+ if ( v.validate( line, var ) != TQValidator::Acceptable )
+ {
+ err = true;
+ continue;
+ }
+
+ new TDEListViewItem(lstPeers, line);
+ ++i;
+ }
+
+ if(err)
+ Out(SYS_IPF|LOG_NOTICE) << "Some lines could not be loaded. Check your filter file..." << endl;
+
+ dat.close();
+}
+
+#include "ipfilterwidget.moc"
diff --git a/src/apps/ktorrent/ipfilterwidget.h b/src/apps/ktorrent/ipfilterwidget.h
new file mode 100644
index 0000000..d8a49e1
--- /dev/null
+++ b/src/apps/ktorrent/ipfilterwidget.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef IPFILTERWIDGET_H
+#define IPFILTERWIDGET_H
+
+#include "ipfilterwidgetbase.h"
+
+/**
+ * @author Ivan Vasic <ivasic@gmail.com>
+ * @brief Integrated IPFilter GUI class.
+ * Used to show, add and remove banned peers from blacklist.
+ */
+class IPFilterWidget: public BlacklistWidgetBase
+{
+ TQ_OBJECT
+
+ public:
+ IPFilterWidget(TQWidget *parent = 0, const char *name = 0);
+
+ virtual void btnApply_clicked();
+ virtual void btnOk_clicked();
+ virtual void btnSave_clicked();
+ virtual void btnOpen_clicked();
+ virtual void btnClear_clicked();
+ virtual void btnRemove_clicked();
+ virtual void btnAdd_clicked();
+
+ void saveFilter(TQString& fn);
+ void loadFilter(TQString& fn);
+};
+
+#endif
diff --git a/src/apps/ktorrent/ipfilterwidgetbase.ui b/src/apps/ktorrent/ipfilterwidgetbase.ui
new file mode 100644
index 0000000..6ef38e1
--- /dev/null
+++ b/src/apps/ktorrent/ipfilterwidgetbase.ui
@@ -0,0 +1,355 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>BlacklistWidgetBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>BlacklistWidgetBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>490</width>
+ <height>437</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KTorrent Blacklist</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="resizeMode">
+ <enum>Minimum</enum>
+ </property>
+ <widget class="TQLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Note: Blacklist applies to current session only. Use save/open to save your entries or use IPFilter plugin (PeerGuardian).</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="TQGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Banned Peers</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TDEListView" row="2" column="0">
+ <column>
+ <property name="text">
+ <string>Peer IP address</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>lstPeers</cstring>
+ </property>
+ <property name="fullWidth">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Add peer:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kLineEdit1</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>peerIP</cstring>
+ </property>
+ <property name="text">
+ <string>127.0.0.1</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnAdd</cstring>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>27</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Adds a peer to blacklist</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnRemove</cstring>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>28</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Removes selected peer from blacklist</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnClear</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;lear</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>10</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Clears this list</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnOpen</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>18</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnSave</cstring>
+ </property>
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>8</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Save this blacklist to use with KTorrent IPFilter plugin</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnApply</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Apply</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>9</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>btnCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>btnAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnRemove</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnRemove_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnClear</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnClear_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnOpen</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnOpen_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnSave</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnSave_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnOk</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnOk_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnApply</sender>
+ <signal>clicked()</signal>
+ <receiver>BlacklistWidgetBase</receiver>
+ <slot>btnApply_clicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>btnOk</tabstop>
+ <tabstop>btnApply</tabstop>
+ <tabstop>btnCancel</tabstop>
+ <tabstop>lstPeers</tabstop>
+ <tabstop>btnRemove</tabstop>
+ <tabstop>btnClear</tabstop>
+ <tabstop>btnOpen</tabstop>
+ <tabstop>btnSave</tabstop>
+ <tabstop>peerIP</tabstop>
+ <tabstop>btnAdd</tabstop>
+</tabstops>
+<slots>
+ <slot>btnAdd_clicked()</slot>
+ <slot>btnRemove_clicked()</slot>
+ <slot>btnClear_clicked()</slot>
+ <slot>btnOpen_clicked()</slot>
+ <slot>btnSave_clicked()</slot>
+ <slot>btnOk_clicked()</slot>
+ <slot>btnApply_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">tdelistview.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/ktorrent.cpp b/src/apps/ktorrent/ktorrent.cpp
new file mode 100644
index 0000000..432d481
--- /dev/null
+++ b/src/apps/ktorrent/ktorrent.cpp
@@ -0,0 +1,1017 @@
+/***************************************************************************
+ * 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 <tqdragobject.h>
+#include <tqsplitter.h>
+#include <tqvbox.h>
+#include <tqlabel.h>
+#include <tqtooltip.h>
+#include <tqtoolbutton.h>
+
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <tdemessagebox.h>
+#include <kiconloader.h>
+#include <tdeversion.h>
+#include <tdemenubar.h>
+#include <kstatusbar.h>
+#include <kkeydialog.h>
+#include <tdeaccel.h>
+#include <tdestandarddirs.h>
+#include <tdeio/netaccess.h>
+#include <tdefiledialog.h>
+#include <tdeconfig.h>
+#include <kurl.h>
+#include <kurldrag.h>
+#include <kprogress.h>
+#include <tdepopupmenu.h>
+#include <ktabwidget.h>
+#include <kedittoolbar.h>
+#include <ksqueezedtextlabel.h>
+#include <kpushbutton.h>
+
+#include <tdestdaccel.h>
+#include <tdeaction.h>
+#include <kstdaction.h>
+
+#include <interfaces/torrentinterface.h>
+#include <torrent/peermanager.h>
+#include <torrent/chunkmanager.h>
+#include <torrent/uploadcap.h>
+#include <torrent/downloadcap.h>
+#include <util/error.h>
+#include <torrent/serverauthenticate.h>
+#include <torrent/globals.h>
+#include <torrent/tracker.h>
+#include <torrent/downloader.h>
+#include <torrent/choker.h>
+#include <torrent/server.h>
+#include <torrent/downloadcap.h>
+#include <torrent/udptrackersocket.h>
+#include <net/socketmonitor.h>
+#include <util/log.h>
+#include <util/fileops.h>
+#include <kademlia/dhtbase.h>
+
+#include "ktorrentcore.h"
+#include "ktorrentview.h"
+#include "ktorrent.h"
+#include "pref.h"
+#include "settings.h"
+#include "trayicon.h"
+#include "ktorrentdcop.h"
+#include "torrentcreatordlg.h"
+#include "pastedialog.h"
+#include "queuedialog.h"
+#include "ipfilterwidget.h"
+#include <util/functions.h>
+#include <interfaces/functions.h>
+#include <interfaces/plugin.h>
+#include <interfaces/prefpageinterface.h>
+#include <newui/dtabwidget.h>
+#include <pluginmanager.h>
+#include <groups/group.h>
+#include <groups/groupview.h>
+#include <groups/groupmanager.h>
+#include <mse/streamsocket.h>
+#include "viewmanager.h"
+#include "ktorrentviewitem.h"
+
+
+
+namespace kt
+{
+ TQString DataDir();
+}
+
+#include <util/profiler.h>
+
+
+
+using namespace bt;
+using namespace kt;
+
+KTorrent::KTorrent()
+ : DMainWindow(0,"KTorrent"),m_group_view(0),
+ m_view_man(0), m_systray_icon(0),m_status_prog(0)
+{
+ setHidden(true);
+ //setToolviewStyle(KMdi::TextAndIcon);
+ connect(this,TQ_SIGNAL(widgetChanged(TQWidget*)),this,TQ_SLOT(currentTabChanged(TQWidget*)));
+
+ m_view_man = new ViewManager(this);
+ m_group_view = new kt::GroupView(m_view_man,actionCollection());
+ connect(m_group_view,TQ_SIGNAL(openNewTab(kt::Group*)),this,TQ_SLOT(openView(kt::Group*)));
+
+
+ m_pref = new KTorrentPreferences(*this);
+
+ m_core = new KTorrentCore(this);
+ m_core->setGroupManager(m_group_view->groupManager());
+
+ m_systray_icon = new TrayIcon(m_core, this);
+
+ m_group_view->loadGroups();
+ m_view_man->restoreViewState(TDEGlobal::config(),this);
+
+ TQToolButton* tb = new TQToolButton(m_activeTabWidget);
+ tb->setIconSet(SmallIcon("tab_new"));
+ tb->adjustSize();
+ connect(tb,TQ_SIGNAL(clicked()),this,TQ_SLOT(openDefaultView()));
+ m_activeTabWidget->setCornerWidget(tb, TopLeft);
+
+ connect(m_group_view,TQ_SIGNAL(currentGroupChanged( kt::Group* )),
+ this,TQ_SLOT(groupChanged(kt::Group*)));
+
+ connect(m_group_view,TQ_SIGNAL(groupRenamed(kt::Group*)),
+ this,TQ_SLOT(groupRenamed(kt::Group*)));
+
+ connect(m_group_view,TQ_SIGNAL(groupRemoved(kt::Group*)),
+ this,TQ_SLOT(groupRemoved(kt::Group*)));
+
+ connect(m_core,TQ_SIGNAL(torrentAdded(kt::TorrentInterface* )),
+ m_view_man,TQ_SLOT(addTorrent(kt::TorrentInterface* )));
+
+ connect(m_core,TQ_SIGNAL(torrentRemoved(kt::TorrentInterface* )),
+ m_view_man,TQ_SLOT(removeTorrent(kt::TorrentInterface* )));
+
+ connect(m_core, TQ_SIGNAL(torrentRemoved( kt::TorrentInterface* )),
+ m_group_view, TQ_SLOT(onTorrentRemoved( kt::TorrentInterface* )));
+
+ m_statusInfo = new KSqueezedTextLabel(this);
+ m_statusSpeed = new TQLabel(this);
+ m_statusTransfer = new TQLabel(this);
+ m_statusDHT = new TQLabel(this);
+ m_statusFirewall = new TQLabel(this);
+ m_statusFirewall->setPixmap(SmallIcon("messagebox_warning"));
+ TQToolTip::add(m_statusFirewall,i18n("No incoming connections (possibly firewalled)"));
+
+ statusBar()->addWidget(m_statusFirewall);
+ statusBar()->addWidget(m_statusInfo,1);
+ statusBar()->addWidget(m_statusDHT);
+ statusBar()->addWidget(m_statusSpeed);
+ statusBar()->addWidget(m_statusTransfer);
+
+ m_statusFirewall->hide();
+
+ setupActions();
+ currentTorrentChanged(0);
+
+ m_dcop = new KTorrentDCOP(this);
+
+ setStandardToolBarMenuEnabled(true);
+
+ TQToolTip::add(m_statusInfo, i18n("Info"));
+ TQToolTip::add(m_statusTransfer, i18n("Data transferred during the current session"));
+ TQToolTip::add(m_statusSpeed, i18n("Current speed of all torrents combined"));
+
+ //first apply settings..
+ applySettings(false);
+ //then load stuff from core
+ m_core->loadTorrents();
+ m_core->loadPlugins();
+
+ connect(&m_gui_update_timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(updatedStats()));
+ //Apply GUI update interval
+ int val = 500;
+ switch(Settings::guiUpdateInterval())
+ {
+ case 1:
+ val = 1000;
+ break;
+ case 2:
+ val = 2000;
+ break;
+ case 3:
+ val = 5000;
+ break;
+ default:
+ val = 500;
+ }
+ m_gui_update_timer.start(val);
+
+ statusBar()->show();
+
+ addToolWidget(m_group_view,"player_playlist",i18n("Groups"),DOCK_LEFT);
+
+ setAutoSaveSettings("WindowStatus",true);
+ TDEGlobal::config()->setGroup("WindowStatus");
+ bool hidden_on_exit = TDEGlobal::config()->readBoolEntry("hidden_on_exit",false);
+ if (Settings::showSystemTrayIcon())
+ {
+ if (hidden_on_exit)
+ {
+ Out(SYS_GEN|LOG_DEBUG) << "Starting minimized" << endl;
+ hide();
+ }
+ else
+ {
+ show();
+ }
+ }
+ else
+ {
+ show();
+ }
+
+ bool menubar_hidden = TDEGlobal::config()->readBoolEntry("menubar_hidden",false);
+ menuBar()->setHidden(menubar_hidden);
+ m_menubarAction->setChecked(!menubar_hidden);
+
+ bool statusbar_hidden = TDEGlobal::config()->readBoolEntry("statusbar_hidden",false);
+ statusBar()->setHidden(statusbar_hidden);
+ m_statusbarAction->setChecked(!statusbar_hidden);
+
+ MaximizeLimits();
+ connect(&m_status_msg_expire,TQ_SIGNAL(timeout()),this,TQ_SLOT(statusBarMsgExpired()));
+
+ m_view_man->updateActions();
+}
+
+KTorrent::~KTorrent()
+{
+ delete m_dcop;
+ delete m_core;
+ delete m_pref;
+ delete m_statusInfo;
+ delete m_statusTransfer;
+ delete m_statusSpeed;
+ delete m_statusFirewall;
+}
+
+void KTorrent::openView(kt::Group* g)
+{
+ if (!g)
+ return;
+
+ KTorrentView* v = m_view_man->newView();
+ v->setCurrentGroup((Group*)g);
+ v->setupViewColumns();
+
+ addTabPage(v,g->groupIcon(),v->caption(),m_view_man);
+
+ connect(v,TQ_SIGNAL(currentChanged(kt::TorrentInterface* )),
+ this,TQ_SLOT(currentTorrentChanged(kt::TorrentInterface* )));
+
+ connect(v,TQ_SIGNAL(wantToRemove(kt::TorrentInterface*,bool )),
+ m_core,TQ_SLOT(remove(kt::TorrentInterface*,bool )));
+
+ connect(v->listView(),TQ_SIGNAL(dropped(TQDropEvent*,TQListViewItem*)),
+ this,TQ_SLOT(urlDropped(TQDropEvent*,TQListViewItem*)));
+
+ connect(v,TQ_SIGNAL(wantToStart( kt::TorrentInterface* )),
+ m_core,TQ_SLOT(start( kt::TorrentInterface* )));
+
+ connect(v,TQ_SIGNAL(wantToStop( kt::TorrentInterface*, bool )),
+ m_core,TQ_SLOT(stop( kt::TorrentInterface*, bool )));
+
+ connect(v,TQ_SIGNAL(needsDataCheck( kt::TorrentInterface* )),
+ m_core,TQ_SLOT(doDataCheck( kt::TorrentInterface* )));
+
+ connect(v,TQ_SIGNAL(updateActions( int )),
+ this,TQ_SLOT(onUpdateActions( int )));
+
+ //connect Core queue() with queue() from KTView.
+ connect(v, TQ_SIGNAL(queue( kt::TorrentInterface* )),
+ m_core, TQ_SLOT(queue( kt::TorrentInterface* )));
+
+ connect(v,TQ_SIGNAL(updateGroupsSubMenu(TDEPopupMenu*)),
+ m_group_view,TQ_SLOT(updateGroupsSubMenu(TDEPopupMenu*)));
+
+ connect(v,TQ_SIGNAL(groupsSubMenuItemActivated(KTorrentView*, const TQString&)),
+ m_group_view,TQ_SLOT(onGroupsSubMenuItemActivated(KTorrentView*, const TQString&)));
+
+ if (m_core)
+ {
+ QueueManager* qman = m_core->getQueueManager();
+ QueueManager::iterator i = qman->begin();
+ while (i != qman->end())
+ {
+ v->addTorrent(*i);
+ i++;
+ }
+ }
+}
+
+void KTorrent::openView(const TQString & group_name)
+{
+ const kt::Group* g = m_group_view->findGroup(group_name);
+ if (g)
+ openView((kt::Group*)g);
+}
+
+void KTorrent::groupChanged(kt::Group* g)
+{
+ KTorrentView* v = m_view_man->getCurrentView();
+ if (v)
+ {
+ m_activeTabWidget->changeTab(v,g->groupName());
+ v->setIcon(g->groupIcon());
+ v->setCurrentGroup(g);
+ }
+}
+
+void KTorrent::groupRenamed(kt::Group* g)
+{
+ m_view_man->groupRenamed(g,m_activeTabWidget);
+}
+
+void KTorrent::groupRemoved(kt::Group* g)
+{
+ kt::Group* allg = m_group_view->groupManager()->allGroup();
+ m_view_man->groupRemoved(g,m_activeTabWidget,this,allg);
+}
+
+void KTorrent::addTabPage(TQWidget* page,const TQIconSet & icon,
+ const TQString & caption,kt::CloseTabListener* ctl)
+{
+ addWidget(page,caption);
+ page->setIcon(icon.pixmap(TQIconSet::Small,TQIconSet::Active));
+ m_tab_map[page] = ctl;
+ currentTabChanged(page);
+}
+
+void KTorrent::addTabPage(TQWidget* page,const TQPixmap & icon,
+ const TQString & caption,kt::CloseTabListener* ctl)
+{
+ addWidget(page,caption);
+ page->setIcon(icon);
+ m_tab_map[page] = ctl;
+ currentTabChanged(page);
+}
+
+
+void KTorrent::removeTabPage(TQWidget* page)
+{
+ if (!m_tab_map.contains(page))
+ return;
+
+ m_tab_map.erase(page);
+ page->reparent(0,TQPoint());
+ removeWidget(page);
+}
+
+void KTorrent::addPrefPage(PrefPageInterface* page)
+{
+ m_pref->addPrefPage(page);
+}
+
+void KTorrent::removePrefPage(PrefPageInterface* page)
+{
+ m_pref->removePrefPage(page);
+}
+
+void KTorrent::applySettings(bool change_port)
+{
+ m_core->setMaxDownloads(Settings::maxDownloads());
+ m_core->setMaxSeeds(Settings::maxSeeds());
+ PeerManager::setMaxConnections(Settings::maxConnections());
+ PeerManager::setMaxTotalConnections(Settings::maxTotalConnections());
+ net::SocketMonitor::setDownloadCap(Settings::maxDownloadRate()*1024);
+ net::SocketMonitor::setUploadCap(Settings::maxUploadRate()*1024);
+ net::SocketMonitor::setSleepTime(Settings::cpuUsage());
+ m_core->setKeepSeeding(Settings::keepSeeding());
+ mse::StreamSocket::setTOS(Settings::dSCP() << 2);
+ mse::StreamSocket::setMaxConnecting(Settings::maxConnectingSockets());
+ if (Settings::allwaysDoUploadDataCheck())
+ ChunkManager::setMaxChunkSizeForDataCheck(0);
+ else
+ ChunkManager::setMaxChunkSizeForDataCheck(Settings::maxSizeForUploadDataCheck() * 1024);
+
+ if (Settings::showSystemTrayIcon())
+ {
+ m_systray_icon->show();
+ m_set_max_upload_rate->update();
+ m_set_max_download_rate->update();
+ }
+ else
+ {
+ m_systray_icon->hide();
+ }
+
+ m_core->changeDataDir(Settings::tempDir());
+ UDPTrackerSocket::setPort(Settings::udpTrackerPort());
+ if (change_port)
+ m_core->changePort(Settings::port());
+
+ if (Settings::useExternalIP())
+ Tracker::setCustomIP(Settings::externalIP());
+ else
+ Tracker::setCustomIP(TQString());
+
+ Downloader::setMemoryUsage(Settings::memoryUsage());
+ Choker::setNumUploadSlots(Settings::numUploadSlots());
+
+ //Apply GUI update interval
+ int val = 500;
+ switch(Settings::guiUpdateInterval())
+ {
+ case 1:
+ val = 1000;
+ break;
+ case 2:
+ val = 2000;
+ break;
+ case 3:
+ val = 5000;
+ break;
+ default:
+ val = 500;
+ }
+ m_gui_update_timer.changeInterval(val);
+
+ //update QM
+ m_core->getQueueManager()->orderQueue();
+ dht::DHTBase & ht = Globals::instance().getDHT();
+ if (Settings::dhtSupport() && !ht.isRunning())
+ {
+ ht.start(kt::DataDir() + "dht_table",kt::DataDir() + "dht_key",Settings::dhtPort());
+ }
+ else if (!Settings::dhtSupport() && ht.isRunning())
+ {
+ ht.stop();
+ }
+ else if (Settings::dhtSupport() && ht.getPort() != Settings::dhtPort())
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Restarting DHT with new port " << Settings::dhtPort() << endl;
+ ht.stop();
+ ht.start(kt::DataDir() + "dht_table",kt::DataDir() + "dht_key",Settings::dhtPort());
+ }
+
+ if (Settings::useEncryption())
+ {
+ Globals::instance().getServer().enableEncryption(Settings::allowUnencryptedConnections());
+ }
+ else
+ {
+ Globals::instance().getServer().disableEncryption();
+ }
+}
+
+void KTorrent::load(const KURL& url)
+{
+ m_core->load(url);
+}
+
+void KTorrent::loadSilently(const KURL& url)
+{
+ m_core->loadSilently(url);
+}
+
+void KTorrent::onUpdateActions(int flags)
+{
+ m_start->setEnabled(flags & KTorrentView::START);
+ m_stop->setEnabled(flags & KTorrentView::STOP);
+ m_remove->setEnabled(flags & KTorrentView::REMOVE);
+ m_queueaction->setEnabled(flags & KTorrentView::REMOVE);
+ m_datacheck->setEnabled(flags & KTorrentView::SCAN);
+ m_startall->setEnabled(flags & KTorrentView::START_ALL);
+ m_stopall->setEnabled(flags & KTorrentView::STOP_ALL);
+}
+
+void KTorrent::currentTorrentChanged(kt::TorrentInterface* tc)
+{
+ notifyViewListeners(tc);
+}
+
+
+void KTorrent::setupActions()
+{
+ KStdAction::openNew(this,TQ_SLOT(fileNew()),actionCollection());
+ KStdAction::open(this, TQ_SLOT(fileOpen()), actionCollection());
+ KStdAction::quit(tdeApp, TQ_SLOT(quit()), actionCollection());
+
+ KStdAction::paste(tdeApp,TQ_SLOT(paste()),actionCollection());
+
+ m_statusbarAction = KStdAction::showStatusbar(this, TQ_SLOT(optionsShowStatusbar()), actionCollection());
+ m_menubarAction = KStdAction::showMenubar(this, TQ_SLOT(optionsShowMenubar()), actionCollection());
+
+ KStdAction::keyBindings(this, TQ_SLOT(optionsConfigureKeys()), actionCollection());
+ KStdAction::configureToolbars(this, TQ_SLOT(optionsConfigureToolbars()), actionCollection());
+
+ TDEAction* pref = KStdAction::preferences(this, TQ_SLOT(optionsPreferences()), actionCollection());
+
+ m_start = new TDEAction(
+ i18n("to start", "Start"), "ktstart",0,this, TQ_SLOT(startDownload()),
+ actionCollection(), "Start");
+
+ m_stop = new TDEAction(
+ i18n("to stop", "Stop"), "ktstop",0,this, TQ_SLOT(stopDownload()),
+ actionCollection(), "Stop");
+
+ m_remove = new TDEAction(
+ i18n("Remove"), "ktremove",0,this, TQ_SLOT(removeDownload()),
+ actionCollection(), "Remove");
+
+ m_startall = new TDEAction(
+ i18n("to start all", "Start All"), "ktstart_all",0,this, TQ_SLOT(startAllDownloadsCurrentView()),
+ actionCollection(), "Start all");
+
+ m_startall_systray = new TDEAction(i18n("to start all", "Start All"), "ktstart_all",0,this, TQ_SLOT(startAllDownloads()),actionCollection());
+
+ m_stopall = new TDEAction(
+ i18n("to stop all", "Stop All"), "ktstop_all",0,this, TQ_SLOT(stopAllDownloadsCurrentView()),
+ actionCollection(), "Stop all");
+
+ m_stopall_systray = new TDEAction(i18n("to stop all", "Stop All"), "ktstop_all",0,this, TQ_SLOT(stopAllDownloads()),actionCollection());
+
+ m_pasteurl = new TDEAction(
+ i18n("to paste torrent URL", "Paste Torrent URL..."), "ktstart",0,this, TQ_SLOT(torrentPaste()),
+ actionCollection(), "paste_url");
+
+ m_queuemgr = new TDEAction(
+ i18n("to open Queue Manager", "Open Queue Manager..."),
+ "ktqueuemanager", 0, this, TQ_SLOT(queueManagerShow()),
+ actionCollection(), "Queue manager");
+
+ m_queueaction = new TDEAction(
+ i18n("Enqueue/Dequeue"),
+ "player_playlist", 0, m_view_man, TQ_SLOT(queueAction()),
+ actionCollection(), "queue_action");
+
+ m_ipfilter = new TDEAction(
+ i18n("IPFilter"),
+ "filter", 0, this, TQ_SLOT(showIPFilter()),
+ actionCollection(), "ipfilter_action");
+
+ m_datacheck = new TDEAction(
+ i18n("Check Data Integrity"),
+ TQString(),0,m_view_man,TQ_SLOT(checkDataIntegrity()),actionCollection(),"check_data");
+
+ m_find = KStdAction::find(this,TQ_SLOT(find()),actionCollection());
+
+ //Plug actions to systemtray context menu
+ m_startall_systray->plug(m_systray_icon->contextMenu());
+ m_stopall_systray->plug(m_systray_icon->contextMenu());
+ m_systray_icon->contextMenu()->insertSeparator();
+ m_pasteurl->plug(m_systray_icon->contextMenu());
+ m_systray_icon->contextMenu()->insertSeparator();
+
+ m_set_max_upload_rate = new SetMaxRate(m_core, 0, this);
+ m_systray_icon->contextMenu()->insertItem(i18n("Set max upload rate"),m_set_max_upload_rate);
+
+ m_set_max_download_rate = new SetMaxRate(m_core, 1, this);
+ m_systray_icon->contextMenu()->insertItem(i18n("Set max download rate"),m_set_max_download_rate);
+
+ pref->plug(m_systray_icon->contextMenu());
+
+ createGUI(0);
+}
+
+
+
+bool KTorrent::queryClose()
+{
+ if (Settings::showSystemTrayIcon() && !tdeApp->sessionSaving())
+ {
+ hide();
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool KTorrent::queryExit()
+{
+ // stop timers to prevent update
+ m_gui_update_timer.stop();
+
+ TDEGlobal::config()->setGroup("WindowStatus");
+ TDEGlobal::config()->writeEntry("hidden_on_exit",this->isHidden());
+ TDEGlobal::config()->writeEntry("menubar_hidden",menuBar()->isHidden());
+ TDEGlobal::config()->writeEntry("statusbar_hidden",statusBar()->isHidden());
+ m_view_man->saveViewState(TDEGlobal::config());
+ saveSettings();
+ hide();
+ m_systray_icon->hide(); // hide system tray icon upon exit
+ m_core->onExit();
+ if (Globals::instance().getDHT().isRunning())
+ Globals::instance().getDHT().stop();
+ return true;
+}
+
+
+void KTorrent::fileNew()
+{
+ TorrentCreatorDlg dlg(m_core,this);
+
+ dlg.show();
+ dlg.exec();
+}
+
+void KTorrent::fileOpen()
+{
+ TQString filter = "*.torrent|" + i18n("Torrent Files") + "\n*|" + i18n("All Files");
+ KURL url = KFileDialog::getOpenURL(TQString(), filter, this, i18n("Open Location"));
+
+ if (url.isValid())
+ load(url);
+}
+
+void KTorrent::torrentPaste()
+{
+ PasteDialog dlg(m_core,this);
+ dlg.exec();
+}
+
+void KTorrent::queueManagerShow()
+{
+ QueueDialog dlg(m_core->getQueueManager(), this);
+ dlg.exec();
+}
+
+void KTorrent::startDownload()
+{
+ m_view_man->startDownloads();
+ TorrentInterface* tc = m_view_man->getCurrentTC();
+ currentTorrentChanged(tc);
+}
+
+void KTorrent::startAllDownloadsCurrentView()
+{
+ m_view_man->startAllDownloads();
+}
+
+void KTorrent::startAllDownloads()
+{
+ m_core->startAll(3);
+}
+
+void KTorrent::stopDownload()
+{
+ m_view_man->stopDownloads();
+ TorrentInterface* tc = m_view_man->getCurrentTC();
+ currentTorrentChanged(tc);
+}
+
+void KTorrent::stopAllDownloads()
+{
+ m_core->stopAll(3);
+}
+
+void KTorrent::stopAllDownloadsCurrentView()
+{
+ m_view_man->stopAllDownloads();
+}
+
+void KTorrent::removeDownload()
+{
+ m_view_man->removeDownloads();
+ currentTorrentChanged(m_view_man->getCurrentTC());
+}
+
+void KTorrent::optionsShowStatusbar()
+{
+ // this is all very cut and paste code for showing/hiding the
+ // statusbar
+ if (m_statusbarAction->isChecked())
+ statusBar()->show();
+ else
+ statusBar()->hide();
+}
+
+void KTorrent::optionsShowMenubar()
+{
+ // this is all very cut and paste code for showing/hiding the
+ // menubar
+ if (m_menubarAction->isChecked())
+ menuBar()->show();
+ else
+ menuBar()->hide();
+}
+
+void KTorrent::optionsConfigureKeys()
+{
+ KKeyDialog::configure(actionCollection());
+}
+
+void KTorrent::optionsConfigureToolbars()
+{
+ // use the standard toolbar editor
+#if defined(TDE_MAKE_VERSION)
+# if TDE_VERSION >= TDE_MAKE_VERSION(3,1,0)
+ saveMainWindowSettings(TDEGlobal::config(), autoSaveGroup());
+# else
+ saveMainWindowSettings(TDEGlobal::config());
+# endif
+#else
+ saveMainWindowSettings(TDEGlobal::config());
+#endif
+ KEditToolbar dlg(factory());
+ connect(&dlg,TQ_SIGNAL(newToolbarConfig()),this,TQ_SLOT(newToolbarConfig()));
+ dlg.exec();
+}
+
+void KTorrent::newToolbarConfig()
+{
+ // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
+ // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
+ createGUI(0);
+
+#if defined(TDE_MAKE_VERSION)
+# if TDE_VERSION >= TDE_MAKE_VERSION(3,1,0)
+ applyMainWindowSettings(TDEGlobal::config(), autoSaveGroup());
+# else
+ applyMainWindowSettings(TDEGlobal::config());
+# endif
+#else
+ applyMainWindowSettings(TDEGlobal::config());
+#endif
+}
+
+void KTorrent::optionsPreferences()
+{
+ // popup some sort of preference dialog, here
+ m_pref->updateData();
+ m_pref->exec();
+}
+
+void KTorrent::changeStatusbar(const TQString& text)
+{
+ // display the text on the statusbar
+ //statusBar()->message(text);
+ m_statusInfo->setText(text);
+ m_status_msg_expire.stop();
+ m_status_msg_expire.start(5000,true);
+}
+
+void KTorrent::changeCaption(const TQString& text)
+{
+ // display the text on the caption
+ setCaption(text);
+}
+
+void KTorrent::saveProperties(TDEConfig* )
+{
+}
+
+void KTorrent::readProperties(TDEConfig*)
+{
+}
+
+void KTorrent::urlDropped(TQDropEvent* event,TQListViewItem*)
+{
+ KURL::List urls;
+
+ if (KURLDrag::decode(event, urls) && !urls.isEmpty())
+ {
+ for (KURL::List::iterator i = urls.begin();i != urls.end();i++)
+ load(*i);
+ }
+}
+
+void KTorrent::updatedStats()
+{
+ m_startall_systray->setEnabled(m_core->getNumTorrentsNotRunning() > 0);
+ m_stopall_systray->setEnabled(m_core->getNumTorrentsRunning() > 0);
+
+ CurrentStats stats = this->m_core->getStats();
+
+ //m_statusInfo->setText(i18n("Some info here e.g. connected/disconnected"));
+ TQString tmp = i18n("Speed down: %1 / up: %2")
+ .arg(KBytesPerSecToString((double)stats.download_speed/1024.0))
+ .arg(KBytesPerSecToString((double)stats.upload_speed/1024.0));
+
+ m_statusSpeed->setText(tmp);
+
+ TQString tmp1 = i18n("Transferred down: %1 / up: %2")
+ .arg(BytesToString(stats.bytes_downloaded))
+ .arg(BytesToString(stats.bytes_uploaded));
+ m_statusTransfer->setText(tmp1);
+
+ if (ServerAuthenticate::isFirewalled() && m_core->getNumTorrentsRunning() > 0)
+ m_statusFirewall->show();
+ else
+ m_statusFirewall->hide();
+
+ m_view_man->update();
+
+ m_systray_icon->updateStats(stats,Settings::showSpeedBarInTrayIcon(),Settings::downloadBandwidth(), Settings::uploadBandwidth());
+
+ m_core->getPluginManager().updateGuiPlugins();
+
+
+ if (Globals::instance().getDHT().isRunning())
+ {
+ const dht::Stats & s = Globals::instance().getDHT().getStats();
+ m_statusDHT->setText(i18n("DHT: %1 nodes, %2 tasks")
+ .arg(s.num_peers).arg(s.num_tasks));
+ }
+ else
+ m_statusDHT->setText(i18n("DHT: off"));
+}
+
+void KTorrent::mergePluginGui(Plugin* p)
+{
+ if (!p) return;
+ guiFactory()->addClient(p);
+}
+
+void KTorrent::removePluginGui(Plugin* p)
+{
+ if (!p) return;
+ guiFactory()->removeClient(p);
+}
+
+void KTorrent::addWidgetInView(TQWidget* w,Position pos)
+{
+}
+
+void KTorrent::removeWidgetFromView(TQWidget* w)
+{
+}
+
+void KTorrent::addWidgetBelowView(TQWidget* w,const TQString & icon,const TQString & caption)
+{
+ addToolWidget(w,icon,caption,DOCK_BOTTOM);
+}
+
+void KTorrent::removeWidgetBelowView(TQWidget* w)
+{
+ removeToolWidget(w);
+}
+
+void KTorrent::addToolWidget(TQWidget* w,const TQString & icon,const TQString & caption,ToolDock dock)
+{
+ if (!w) return;
+
+
+ if (!icon.isNull())
+ w->setIcon(TDEGlobal::iconLoader()->loadIcon(icon,TDEIcon::Small));
+
+ switch (dock)
+ {
+ case DOCK_BOTTOM:
+ addDockWidget(DDockWindow::Bottom,w,caption);
+ break;
+
+ case DOCK_LEFT:
+ addDockWidget(DDockWindow::Left,w,caption);
+ break;
+
+ case DOCK_RIGHT:
+ default:
+ addDockWidget(DDockWindow::Right,w,caption);
+ break;
+ }
+}
+
+void KTorrent::removeToolWidget(TQWidget* w)
+{
+ if (!w) return;
+
+ removeDockWidget(w);
+ w->reparent(0,TQPoint());
+}
+
+const TorrentInterface* KTorrent::getCurrentTorrent() const
+{
+ return m_view_man->getCurrentTC();
+}
+
+TQString KTorrent::getStatusInfo()
+{
+ return m_statusInfo->text();
+}
+
+TQString KTorrent::getStatusTransfer()
+{
+ return m_statusTransfer->text();
+}
+
+TQString KTorrent::getStatusSpeed()
+{
+ return m_statusSpeed->text();
+}
+
+TQString KTorrent::getStatusDHT()
+{
+ return m_statusDHT->text();
+}
+
+TQString KTorrent::getStatusFirewall()
+{
+ return m_statusFirewall->text();
+}
+
+QCStringList KTorrent::getTorrentInfo(kt::TorrentInterface* tc)
+{
+ return KTorrentViewItem::getTorrentInfo(tc);
+}
+
+void KTorrent::showIPFilter()
+{
+ IPFilterWidget ipf(this);
+ ipf.exec();
+}
+
+
+void KTorrent::closeTab()
+{
+ TQWidget* w = m_currentWidget;
+ if (!w)
+ return;
+
+ CloseTabListener* ctl = m_tab_map[w];
+ if (ctl)
+ {
+ ctl->tabCloseRequest(this,w);
+ currentTabChanged(m_activeTabWidget->currentPage());
+ }
+}
+
+void KTorrent::currentTabChanged(TQWidget* w)
+{
+ m_view_man->onCurrentTabChanged(w);
+ currentTorrentChanged(m_view_man->getCurrentTC());
+ if (!m_activeTabWidget || !w)
+ return;
+
+ bool close_allowed = false;
+ CloseTabListener* ctl = m_tab_map[w];
+ if (ctl)
+ close_allowed = ctl->closeAllowed(w);
+
+ m_activeTabWidget->closeButton()->setEnabled(close_allowed);
+}
+
+void KTorrent::openDefaultView()
+{
+ openView(i18n("All Torrents"));
+}
+
+TDEToolBar* KTorrent::addToolBar(const char* name)
+{
+ return toolBar(name);
+}
+
+void KTorrent::removeToolBar(TDEToolBar* tb)
+{
+ delete tb;
+}
+
+void KTorrent::loadSilentlyDir(const KURL& url, const KURL& savedir)
+{
+ m_core->loadSilentlyDir(url, savedir);
+}
+
+KProgress* KTorrent::addProgressBarToStatusBar()
+{
+ if (m_status_prog)
+ return 0;
+
+ KStatusBar* sb = statusBar();
+ m_status_prog = new KProgress(100,sb);
+ m_status_prog->setValue(0);
+ sb->addWidget(m_status_prog);
+ m_status_prog->show();
+ return m_status_prog;
+}
+
+void KTorrent::removeProgressBarFromStatusBar(KProgress* p)
+{
+ if (m_status_prog != p)
+ return;
+
+ KStatusBar* sb = statusBar();
+ sb->removeWidget(p);
+ delete p;
+ m_status_prog = 0;
+}
+
+void KTorrent::statusBarMsgExpired()
+{
+ m_statusInfo->clear();
+}
+
+void KTorrent::find()
+{
+ KTorrentView* v = m_view_man->getCurrentView();
+ if (v)
+ v->toggleFilterBar();
+}
+
+#include "ktorrent.moc"
+
diff --git a/src/apps/ktorrent/ktorrent.desktop b/src/apps/ktorrent/ktorrent.desktop
new file mode 100644
index 0000000..923b8cd
--- /dev/null
+++ b/src/apps/ktorrent/ktorrent.desktop
@@ -0,0 +1,15 @@
+[Desktop Entry]
+Name=KTorrent
+
+GenericName=BitTorrent Client
+
+Comment=A BitTorrent program for TDE
+
+Type=Application
+Exec=ktorrent %i %m -caption "%c" %u
+Icon=ktorrent
+MimeType=application/x-bittorrent;application/x-torrent;
+Terminal=false
+X-DCOP-ServiceType=Unique
+X-DocPath=ktorrent/index.html
+Categories=Qt;TDE;Network;FileTransfer;
diff --git a/src/apps/ktorrent/ktorrent.h b/src/apps/ktorrent/ktorrent.h
new file mode 100644
index 0000000..6669443
--- /dev/null
+++ b/src/apps/ktorrent/ktorrent.h
@@ -0,0 +1,239 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+
+
+#ifndef _KTORRENT_H_
+#define _KTORRENT_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <tdeapplication.h>
+#include <newui/dmainwindow.h>
+#include <tqtimer.h>
+#include <interfaces/guiinterface.h>
+
+typedef TQValueList<TQCString> QCStringList;
+
+class TDEAction;
+class TDEToggleAction;
+class KURL;
+class KTorrentCore;
+class KTorrentView;
+class TrayIcon;
+class SetMaxRate;
+class KTorrentDCOP;
+class TQLabel;
+class TQListViewItem;
+class KTorrentPreferences;
+class ViewManager;
+
+
+namespace kt
+{
+ class TorrentInterface;
+ class Group;
+ class GroupView;
+}
+
+
+/**
+ * This class serves as the main window for KTorrent. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ * @version 0.1
+ */
+class KTorrent : public DMainWindow, public kt::GUIInterface
+{
+ TQ_OBJECT
+
+public:
+ /**
+ * Default Constructor
+ */
+ KTorrent();
+
+ /**
+ * Default Destructor
+ */
+ virtual ~KTorrent();
+
+ /// Open a view with the given group
+ void openView(const TQString & group_name);
+
+ /// Get the core
+ KTorrentCore & getCore() {return *m_core;}
+
+ /**
+ * Apply the settings.
+ * @param change_port Wether or not to change the server port
+ */
+ void applySettings(bool change_port = true);
+
+ virtual void addTabPage(TQWidget* page,const TQIconSet & icon,
+ const TQString & caption,kt::CloseTabListener* ctl = 0);
+ virtual void addTabPage(TQWidget* page,const TQPixmap & icon,
+ const TQString & caption,kt::CloseTabListener* ctl = 0);
+ virtual void removeTabPage(TQWidget* page);
+ virtual void addPrefPage(kt::PrefPageInterface* page);
+ virtual void removePrefPage(kt::PrefPageInterface* page);
+ virtual void mergePluginGui(kt::Plugin* p);
+ virtual void removePluginGui(kt::Plugin* p);
+ virtual void addWidgetBelowView(TQWidget* w,const TQString & icon,const TQString & caption);
+ virtual void removeWidgetBelowView(TQWidget* w);
+ virtual void addToolWidget(TQWidget* w,const TQString & icon,const TQString & caption,ToolDock dock);
+ virtual void removeToolWidget(TQWidget* w);
+ virtual const kt::TorrentInterface* getCurrentTorrent() const;
+ virtual TDEToolBar* addToolBar(const char* name);
+ virtual void removeToolBar(TDEToolBar* tb);
+ virtual KProgress* addProgressBarToStatusBar();
+ virtual void removeProgressBarFromStatusBar(KProgress* p);
+
+ TQString getStatusInfo();
+ TQString getStatusTransfer();
+ TQString getStatusSpeed();
+ TQString getStatusDHT();
+ TQString getStatusFirewall();
+ QCStringList getTorrentInfo(kt::TorrentInterface* tc);
+
+public slots:
+ /**
+ * Use this method to load whatever file/URL you have
+ */
+ void load(const KURL& url);
+
+ /**
+ * Does the same as load, but doesn't ask any questions
+ */
+ void loadSilently(const KURL& url);
+
+ /**
+ * Does the same as loadSilently, except accepts a directory to
+ * save to
+ */
+ void loadSilentlyDir(const KURL& url, const KURL& savedir);
+
+ /// Open a view with the given group
+ void openView(kt::Group* g);
+
+protected:
+ /**
+ * This function is called when it is time for the app to save its
+ * properties for session management purposes.
+ */
+ void saveProperties(TDEConfig *);
+
+ /**
+ * This function is called when this app is restored. The TDEConfig
+ * object points to the session management config file that was saved
+ * with @ref saveProperties
+ */
+ void readProperties(TDEConfig *);
+
+
+private slots:
+ void fileOpen();
+ void fileNew();
+ void torrentPaste();
+ void startDownload();
+ void startAllDownloadsCurrentView();
+ void startAllDownloads();
+ void stopDownload();
+ void stopAllDownloadsCurrentView();
+ void stopAllDownloads();
+ void showIPFilter();
+ void removeDownload();
+ void queueManagerShow();
+ void optionsShowStatusbar();
+ void optionsShowMenubar();
+ void optionsConfigureKeys();
+ void optionsConfigureToolbars();
+ void optionsPreferences();
+ void newToolbarConfig();
+ void changeStatusbar(const TQString& text);
+ void changeCaption(const TQString& text);
+ void currentTorrentChanged(kt::TorrentInterface* tc);
+ void updatedStats();
+ void urlDropped(TQDropEvent*,TQListViewItem*);
+ void onUpdateActions(int flags);
+ void groupChanged(kt::Group* g);
+ void groupRenamed(kt::Group* g);
+ void groupRemoved(kt::Group* g);
+ void currentTabChanged(TQWidget* w);
+ void openDefaultView();
+ void statusBarMsgExpired();
+ void find();
+
+private:
+ void setupAccel();
+ void setupActions();
+ bool queryClose();
+ bool queryExit();
+
+
+ virtual void addWidgetInView(TQWidget* w,kt::Position pos);
+ virtual void removeWidgetFromView(TQWidget* w);
+ virtual void closeTab();
+
+private:
+ kt::GroupView* m_group_view;
+ ViewManager* m_view_man;
+ TDEToggleAction *m_statusbarAction;
+ TDEToggleAction* m_menubarAction;
+
+ KTorrentCore* m_core;
+ TrayIcon* m_systray_icon;
+ SetMaxRate* m_set_max_upload_rate;
+ SetMaxRate* m_set_max_download_rate;
+
+ KTorrentDCOP* m_dcop;
+ TQTimer m_gui_update_timer;
+ TQTimer m_status_msg_expire;
+ KTorrentPreferences* m_pref;
+
+ TQMap<TQWidget*,kt::CloseTabListener*> m_tab_map;
+
+ TQLabel* m_statusInfo;
+ TQLabel* m_statusTransfer;
+ TQLabel* m_statusSpeed;
+ TQLabel* m_statusDHT;
+ TQLabel* m_statusFirewall;
+
+ TDEAction* m_start;
+ TDEAction* m_stop;
+ TDEAction* m_remove;
+ TDEAction* m_startall;
+ TDEAction* m_startall_systray;
+ TDEAction* m_stopall;
+ TDEAction* m_stopall_systray;
+ TDEAction* m_pasteurl;
+ TDEAction* m_queuemgr;
+ TDEAction* m_queueaction;
+ TDEAction* m_datacheck;
+ TDEAction* m_ipfilter;
+ TDEAction* m_find;
+
+ KProgress* m_status_prog;
+};
+
+#endif // _KTORRENT_H_
diff --git a/src/apps/ktorrent/ktorrentapp.cpp b/src/apps/ktorrent/ktorrentapp.cpp
new file mode 100644
index 0000000..9ced625
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentapp.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Adam Treat *
+ * treat@kde.org *
+ * *
+ * 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 "ktorrentapp.h"
+
+#include <tdeglobal.h>
+#include <tdestartupinfo.h>
+#include <tdecmdlineargs.h>
+#include <tdestandarddirs.h>
+#include <dcopclient.h>
+
+#include <util/log.h>
+#include <torrent/globals.h>
+#include <util/functions.h>
+
+#include "ktorrent.h"
+
+KTorrentApp::KTorrentApp()
+ : TDEUniqueApplication()
+{}
+
+KTorrentApp::~KTorrentApp()
+{}
+
+int KTorrentApp::newInstance()
+{
+ // register ourselves as a dcop client
+ if (!dcopClient()->isRegistered() )
+ dcopClient()->registerAs(name(), false);
+
+ TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+ bt::Globals::instance().setDebugMode(args->isSet("debug"));
+
+ TQString data_dir = TDEGlobal::dirs()->saveLocation("data","ktorrent");
+ if (!data_dir.endsWith(bt::DirSeparator()))
+ data_dir += bt::DirSeparator();
+ bt::Globals::instance().initLog(data_dir + "log");
+
+ if (!mainWidget())
+ {
+ KTorrent *widget = new KTorrent();
+ setMainWidget(widget);
+ }
+ else
+ TDEStartupInfo::setNewStartupId( mainWidget(), tdeApp->startupId());
+
+
+ KTorrent *widget = ::tqt_cast<KTorrent*>( mainWidget() );
+
+ for (int i = 0; i < args->count(); i++)
+ {
+ if (args->isSet("silent"))
+ widget->loadSilently(args->url(i));
+ else
+ widget->load(args->url(i));
+ }
+
+ args->clear();
+ return 0;
+}
+
+#include "ktorrentapp.moc"
+
diff --git a/src/apps/ktorrent/ktorrentapp.h b/src/apps/ktorrent/ktorrentapp.h
new file mode 100644
index 0000000..489eb04
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentapp.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Adam Treat *
+ * treat@kde.org *
+ * *
+ * 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. *
+ ***************************************************************************/
+
+#ifndef _KTORRENTAPP_H_
+#define _KTORRENTAPP_H_
+
+#include "dcopinterface.h"
+#include <tdeuniqueapplication.h>
+
+class KTorrentApp : public TDEUniqueApplication
+{
+ TQ_OBJECT
+
+public:
+ KTorrentApp();
+ virtual ~KTorrentApp();
+
+ virtual int newInstance();
+};
+
+#endif // _KTORRENTAPP_H_
+
diff --git a/src/apps/ktorrent/ktorrentcore.cpp b/src/apps/ktorrent/ktorrentcore.cpp
new file mode 100644
index 0000000..6ac9426
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentcore.cpp
@@ -0,0 +1,1145 @@
+/***************************************************************************
+ * 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 <unistd.h>
+#include <tqdir.h>
+#include <tdelocale.h>
+#include <tdeglobal.h>
+#include <tdefiledialog.h>
+#include <kprogress.h>
+#include <tdemessagebox.h>
+#include <tdestandarddirs.h>
+#include <tdeapplication.h>
+#include <tdeio/job.h>
+#include <tdeio/netaccess.h>
+#include <tqregexp.h>
+
+#include <util/log.h>
+#include <torrent/torrentcontrol.h>
+#include <torrent/globals.h>
+#include <util/error.h>
+#include <util/fileops.h>
+#include <util/waitjob.h>
+#include <torrent/torrentcreator.h>
+#include <torrent/server.h>
+#include <torrent/authenticationmonitor.h>
+#include <util/functions.h>
+#include <torrent/ipblocklist.h>
+#include <kademlia/dhtbase.h>
+#include <torrent/torrentfile.h>
+
+#include "pluginmanager.h"
+#include <torrent/queuemanager.h>
+
+#include "ktorrentcore.h"
+#include "settings.h"
+#include "functions.h"
+#include "fileselectdlg.h"
+#include "scandialog.h"
+
+
+#include <util/profiler.h>
+
+
+using namespace bt;
+using namespace kt;
+
+const Uint32 CORE_UPDATE_INTERVAL = 250;
+
+
+
+KTorrentCore::KTorrentCore(kt::GUIInterface* gui) : max_downloads(0),keep_seeding(true),pman(0)
+{
+ UpdateCurrentTime();
+
+ qman = new QueueManager();
+ connect(qman, TQ_SIGNAL(lowDiskSpace(kt::TorrentInterface*,bool)), this, TQ_SLOT(onLowDiskSpace(kt::TorrentInterface*,bool)));
+
+
+ data_dir = Settings::tempDir();
+ bool dd_not_exist = !bt::Exists(data_dir);
+ if (data_dir == TQString() || dd_not_exist)
+ {
+ data_dir = TDEGlobal::dirs()->saveLocation("data","ktorrent");
+ if (dd_not_exist)
+ {
+ Settings::setTempDir(data_dir);
+ Settings::writeConfig();
+ }
+ }
+
+ removed_bytes_up = removed_bytes_down = 0;
+
+ if (!data_dir.endsWith(bt::DirSeparator()))
+ data_dir += bt::DirSeparator();
+ // downloads.setAutoDelete(true);
+
+ connect(&update_timer,TQ_SIGNAL(timeout()),this,TQ_SLOT(update()));
+ update_timer.start(CORE_UPDATE_INTERVAL);
+
+ Uint16 port = Settings::port();
+ if (port == 0)
+ {
+ port = 6881;
+ Settings::setPort(6881);
+ }
+ Uint16 i = 0;
+ do
+ {
+ Globals::instance().initServer(port + i);
+ i++;
+ }
+ while (!Globals::instance().getServer().isOK() && i < 10);
+
+ if (Globals::instance().getServer().isOK())
+ {
+ if (port != port + i - 1)
+ KMessageBox::information(0,
+ i18n("Specified port (%1) is unavailable or in"
+ " use by another application. KTorrent is now using port %2.")
+ .arg(port).arg(port + i - 1));
+
+ Out(SYS_GEN|LOG_NOTICE) << "Bound to port " << (port + i - 1) << endl;
+ }
+ else
+ {
+ KMessageBox::error(0,
+ i18n("KTorrent is unable to accept connections because the ports %1 to %2 are "
+ "already in use by another program.").arg(port).arg(port + i - 1));
+ Out(SYS_GEN|LOG_IMPORTANT) << "Cannot find free port" << endl;
+ }
+
+
+ pman = new kt::PluginManager(this,gui);
+}
+
+
+KTorrentCore::~KTorrentCore()
+{
+ delete qman;
+ delete pman;
+}
+
+void KTorrentCore::loadPlugins()
+{
+ pman->loadConfigFile(TDEGlobal::dirs()->saveLocation("data","ktorrent") + "plugins");
+ pman->loadPluginList();
+}
+
+bool KTorrentCore::init(TorrentControl* tc,bool silently)
+{
+ connectSignals(tc);
+ qman->append(tc);
+
+ bool user = false;
+ bool start_torrent = false;
+
+ if (!silently)
+ {
+ FileSelectDlg dlg(gman, &user, &start_torrent);
+
+ if (dlg.execute(tc) != TQDialog::Accepted)
+ {
+ remove(tc,false);
+ return false;
+ }
+ }
+
+ try
+ {
+ tc->createFiles();
+ }
+ catch (bt::Error & err)
+ {
+ // if we can't create files, just remove the torrent
+ KMessageBox::error(0,err.toString());
+ remove(tc,false);
+ return false;
+ }
+
+ if (tc->hasExistingFiles())
+ {
+ ScanDialog* scan_dlg = new ScanDialog(this,true);
+ scan_dlg->show();
+ scan_dlg->execute(tc,true);
+ }
+
+ tc->setPreallocateDiskSpace(true);
+
+ if(Settings::maxRatio()>0)
+ tc->setMaxShareRatio(Settings::maxRatio());
+
+ if (Settings::maxSeedTime() > 0)
+ tc->setMaxSeedTime(Settings::maxSeedTime());
+
+ torrentAdded(tc);
+ qman->torrentAdded(tc, user, start_torrent);
+
+
+ //now copy torrent file to user specified dir if needed
+ if(Settings::useTorrentCopyDir())
+ {
+ TQString torFile = tc->getTorDir();
+
+ if(!torFile.endsWith("/"))
+ torFile += "/";
+
+ torFile += "torrent";
+
+ TQString destination = Settings::torrentCopyDir();
+
+ if(!destination.endsWith("/"))
+ destination += "/";
+
+ destination += tc->getStats().torrent_name + ".torrent";
+
+ try
+ {
+ bt::CopyFile(torFile, destination, true);
+ }
+ catch(bt::Error& err)
+ {
+ Out(SYS_GEN|LOG_IMPORTANT) << "Could not copy torrent file to " << destination << endl;
+ }
+ }
+
+ return true;
+}
+
+bool KTorrentCore::load(const TQByteArray & data,const TQString & dir,bool silently, const KURL& url)
+{
+ TQString tdir = findNewTorrentDir();
+ TorrentControl* tc = 0;
+ try
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Loading torrent from data " << endl;
+ tc = new TorrentControl();
+ tc->init(qman, data, tdir, dir,
+ Settings::useSaveDir() ? Settings::saveDir() : TQString());
+
+ if(!init(tc,silently))
+ loadingFinished(url, false, true);
+ else
+ loadingFinished(url, true, false);
+
+ return true;
+ }
+ catch (bt::Error & err)
+ {
+ KMessageBox::error(0,err.toString());
+ delete tc;
+ tc = 0;
+ // delete tdir if necesarry
+ if (bt::Exists(tdir))
+ bt::Delete(tdir,true);
+
+ loadingFinished(url, false, false);
+
+ return false;
+ }
+}
+
+bool KTorrentCore::load(const TQString & target,const TQString & dir,bool silently)
+{
+ TQString tdir = findNewTorrentDir();
+ TorrentControl* tc = 0;
+ try
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Loading file " << target << endl;
+ tc = new TorrentControl();
+ tc->init(qman, target, tdir, dir,
+ Settings::useSaveDir() ? Settings::saveDir() : TQString());
+
+ init(tc,silently);
+ return true;
+ }
+ catch (bt::Error & err)
+ {
+ KMessageBox::error(0,err.toString());
+ delete tc;
+ tc = 0;
+ // delete tdir if necesarry
+ if (bt::Exists(tdir))
+ bt::Delete(tdir,true);
+ return false;
+ }
+}
+
+void KTorrentCore::downloadFinished(TDEIO::Job *job)
+{
+ TDEIO::StoredTransferJob* j = (TDEIO::StoredTransferJob*)job;
+ int err = j->error();
+ if (err == TDEIO::ERR_USER_CANCELED)
+ {
+ loadingFinished(j->url(),false,true);
+ return;
+ }
+
+ if (err)
+ {
+ loadingFinished(j->url(),false,false);
+ j->showErrorDialog(0);
+ }
+ else
+ {
+ // load in the file (target is always local)
+ TQString dir = Settings::saveDir();
+ if (!Settings::useSaveDir() || dir.isNull())
+ dir = TQDir::homeDirPath();
+
+ if (dir != TQString() && load(j->data(),dir,false, j->url()))
+ loadingFinished(j->url(),true,false);
+ else
+ loadingFinished(j->url(),false,true);
+ }
+}
+
+void KTorrentCore::load(const KURL& url)
+{
+ if (url.isLocalFile())
+ {
+ TQString path = url.path();
+ TQString dir = Settings::saveDir();
+ if (!Settings::useSaveDir() || dir.isNull())
+ dir = TQDir::homeDirPath();
+
+ if (dir != TQString() && load(path,dir,false))
+ loadingFinished(url,true,false);
+ else
+ loadingFinished(url,false,true);
+ }
+ else
+ {
+ TDEIO::Job* j = TDEIO::storedGet(url,false,true);
+ connect(j,TQ_SIGNAL(result(TDEIO::Job*)),this,TQ_SLOT(downloadFinished( TDEIO::Job* )));
+ }
+}
+
+void KTorrentCore::downloadFinishedSilently(TDEIO::Job *job)
+{
+ TDEIO::StoredTransferJob* j = (TDEIO::StoredTransferJob*)job;
+ int err = j->error();
+ if (err == TDEIO::ERR_USER_CANCELED)
+ {
+ loadingFinished(j->url(),false,true);
+ }
+ else if (err)
+ {
+ loadingFinished(j->url(),false,false);
+ }
+ else
+ {
+ TQString dir;
+ if (custom_save_locations.contains(j))
+ {
+ // we have a custom save location so save to that
+ dir = custom_save_locations[j].path();
+ custom_save_locations.erase(j);
+ }
+ else if (!Settings::useSaveDir())
+ {
+ // incase save dir is not set, use home director
+ Out(SYS_GEN|LOG_NOTICE) << "Cannot load " << j->url() << " silently, default save location not set !" << endl;
+ Out(SYS_GEN|LOG_NOTICE) << "Using home directory instead !" << endl;
+ dir = TQDir::homeDirPath();
+ }
+ else
+ {
+ dir = Settings::saveDir();
+ }
+
+
+ if (dir != TQString() && load(j->data(),dir,true,j->url()))
+ loadingFinished(j->url(),true,false);
+ else
+ loadingFinished(j->url(),false,false);
+ }
+}
+
+void KTorrentCore::loadSilently(const KURL& url)
+{
+ if (url.isLocalFile())
+ {
+ TQString path = url.path();
+ TQString dir = Settings::saveDir();
+ if (!Settings::useSaveDir() || dir.isNull())
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Cannot load " << path << " silently, default save location not set !" << endl;
+ Out(SYS_GEN|LOG_NOTICE) << "Using home directory instead !" << endl;
+ dir = TQDir::homeDirPath();
+ }
+
+ if (dir != TQString() && load(path,dir,true))
+ loadingFinished(url,true,false);
+ else
+ loadingFinished(url,false,true);
+ }
+ else
+ {
+ // download to a random file in tmp
+ TDEIO::Job* j = TDEIO::storedGet(url,false,true);
+ connect(j,TQ_SIGNAL(result(TDEIO::Job*)),this,TQ_SLOT(downloadFinishedSilently( TDEIO::Job* )));
+ }
+}
+
+void KTorrentCore::loadSilentlyDir(const KURL& url, const KURL& savedir)
+{
+ if (url.isLocalFile())
+ {
+ TQString path = url.path();
+ TQString dir = savedir.path();
+ TQFileInfo fi(dir);
+ if (!fi.exists() || !fi.isWritable() || !fi.isDir())
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Cannot load " << path << " silently, destination directory is not OK ! Using default save directory." << endl;
+ dir = Settings::saveDir();
+ if (!Settings::useSaveDir())
+ {
+ Out(SYS_GEN|LOG_NOTICE) << "Default save directory not set, using home directory !" << endl;
+ dir = TQDir::homeDirPath();
+ }
+ }
+
+ if (dir != TQString() && load(path,dir,true))
+ loadingFinished(url,true,false);
+ else
+ loadingFinished(url,false,true);
+ }
+ else
+ {
+ // download to a random file in tmp
+ TDEIO::Job* j = TDEIO::storedGet(url,false,true);
+ custom_save_locations.insert(j,savedir); // keep track of save location
+ connect(j,TQ_SIGNAL(result(TDEIO::Job*)),this,TQ_SLOT(downloadFinishedSilently( TDEIO::Job* )));
+ }
+}
+
+void KTorrentCore::start(kt::TorrentInterface* tc)
+{
+ kt::TorrentStartResponse reason = qman->start(tc);
+ switch (reason)
+ {
+ // we can return, the question to ignore the limits will have informed the user
+ case MAX_SHARE_RATIO_REACHED:
+ case START_OK: // start OK is normal
+ case BUSY_WITH_DATA_CHECK: // checking data, so let the torrent be
+ case USER_CANCELED:
+ return;
+ case NOT_ENOUGH_DISKSPACE:
+ case TQM_LIMITS_REACHED:
+ canNotStart(tc,reason);
+ break;
+ }
+}
+
+void KTorrentCore::stop(TorrentInterface* tc, bool user)
+{
+ qman->stop(tc, user);
+}
+
+int KTorrentCore::getNumRunning(bool onlyDownloads, bool onlySeeds) const
+{
+ return qman->getNumRunning(onlyDownloads, onlySeeds);
+}
+
+TQString KTorrentCore::findNewTorrentDir() const
+{
+ int i = 0;
+ while (true)
+ {
+ TQDir d;
+ TQString dir = data_dir + TQString("tor%1/").arg(i);
+ if (!d.exists(dir))
+ {
+ return dir;
+ }
+ i++;
+ }
+ return TQString();
+}
+
+void KTorrentCore::loadExistingTorrent(const TQString & tor_dir)
+{
+ TorrentControl* tc = 0;
+
+ TQString idir = tor_dir;
+ if (!idir.endsWith(bt::DirSeparator()))
+ idir += bt::DirSeparator();
+
+ if (!bt::Exists(idir + "torrent"))
+ return;
+
+ try
+ {
+ tc = new TorrentControl();
+ tc->init(qman,idir + "torrent",idir,TQString(),
+ Settings::useSaveDir() ? Settings::saveDir() : TQString());
+
+ qman->append(tc);
+ connectSignals(tc);
+ if (tc->getStats().autostart && tc->getStats().user_controlled)
+ start(tc);
+ torrentAdded(tc);
+ }
+ catch (bt::Error & err)
+ {
+ KMessageBox::error(0,err.toString());
+ delete tc;
+ }
+}
+
+void KTorrentCore::loadTorrents()
+{
+ TQDir dir(data_dir);
+ TQStringList sl = dir.entryList("tor*",TQDir::Dirs);
+ for (Uint32 i = 0;i < sl.count();i++)
+ {
+
+ TQString idir = data_dir + *sl.at(i);
+ if (!idir.endsWith(DirSeparator()))
+ idir.append(DirSeparator());
+
+ Out(SYS_GEN|LOG_NOTICE) << "Loading " << idir << endl;
+ loadExistingTorrent(idir);
+ }
+ qman->orderQueue();
+}
+
+void KTorrentCore::remove(TorrentInterface* tc,bool data_to)
+{
+ try
+ {
+ const TorrentStats & s = tc->getStats();
+ removed_bytes_up += s.session_bytes_uploaded;
+ removed_bytes_down += s.session_bytes_downloaded;
+ stop(tc);
+
+ TQString dir = tc->getTorDir();
+
+ try
+ {
+ if (data_to)
+ tc->deleteDataFiles();
+ }
+ catch (Error & e)
+ {
+ KMessageBox::error(0,e.toString());
+ }
+
+ torrentRemoved(tc);
+ qman->torrentRemoved(tc);
+
+ bt::Delete(dir,false);
+ }
+ catch (Error & e)
+ {
+ KMessageBox::error(0,e.toString());
+ }
+}
+
+void KTorrentCore::setMaxDownloads(int max)
+{
+ qman->setMaxDownloads(max);
+}
+
+void KTorrentCore::setMaxSeeds(int max)
+{
+ qman->setMaxSeeds(max);
+}
+
+void KTorrentCore::torrentFinished(kt::TorrentInterface* tc)
+{
+ if (!keep_seeding)
+ tc->stop(false);
+
+ finished(tc);
+ qman->torrentFinished(tc);
+}
+
+void KTorrentCore::setKeepSeeding(bool ks)
+{
+ keep_seeding = ks;
+ qman->setKeepSeeding(ks);
+}
+
+void KTorrentCore::onExit()
+{
+ // stop timer to prevent updates during wait
+ update_timer.stop();
+ // stop all authentications going on
+ AuthenticationMonitor::instance().clear();
+ // shutdown the server
+ Globals::instance().shutdownServer();
+
+ WaitJob* job = new WaitJob(5000);
+ qman->onExit(job);
+ // wait for completion of stopped events
+ if (job->needToWait())
+ WaitJob::execute(job);
+ else
+ delete job;
+
+ pman->unloadAll(false);
+ qman->clear();
+}
+
+bool KTorrentCore::changeDataDir(const TQString & new_dir)
+{
+ try
+ {
+ update_timer.stop();
+ // do nothing if new and old dir are the same
+ if (KURL(data_dir) == KURL(new_dir) || data_dir == (new_dir + bt::DirSeparator()))
+ {
+ update_timer.start(CORE_UPDATE_INTERVAL);
+ return true;
+ }
+
+ // safety check
+ if (!bt::Exists(new_dir))
+ bt::MakeDir(new_dir);
+
+
+ // make sure new_dir ends with a /
+ TQString nd = new_dir;
+ if (!nd.endsWith(DirSeparator()))
+ nd += DirSeparator();
+
+ Out() << "Switching to datadir " << nd << endl;
+
+ qman->setPausedState(true);
+
+ TQPtrList<kt::TorrentInterface> succes;
+
+ TQPtrList<kt::TorrentInterface>::iterator i = qman->begin();
+ while (i != qman->end())
+ {
+ kt::TorrentInterface* tc = *i;
+ if (!tc->changeDataDir(nd))
+ {
+ // failure time to roll back all the succesfull tc's
+ rollback(succes);
+ // set back the old data_dir in Settings
+ Settings::setTempDir(data_dir);
+ Settings::self()->writeConfig();
+ qman->setPausedState(false);
+ update_timer.start(CORE_UPDATE_INTERVAL);
+ return false;
+ }
+ else
+ {
+ succes.append(tc);
+ }
+ i++;
+ }
+ data_dir = nd;
+ qman->setPausedState(false);
+ update_timer.start(CORE_UPDATE_INTERVAL);
+ return true;
+ }
+ catch (bt::Error & e)
+ {
+ Out(SYS_GEN|LOG_IMPORTANT) << "Error : " << e.toString() << endl;
+ update_timer.start(CORE_UPDATE_INTERVAL);
+ return false;
+ }
+}
+
+void KTorrentCore::rollback(const TQPtrList<kt::TorrentInterface> & succes)
+{
+ Out() << "Error, rolling back" << endl;
+ update_timer.stop();
+ TQPtrList<kt::TorrentInterface> ::const_iterator i = succes.begin();
+ while (i != succes.end())
+ {
+ (*i)->rollback();
+ i++;
+ }
+ update_timer.start(CORE_UPDATE_INTERVAL);
+}
+
+void KTorrentCore::startAll(int type)
+{
+ qman->startall(type);
+}
+
+void KTorrentCore::stopAll(int type)
+{
+ qman->stopall(type);
+}
+
+void KTorrentCore::update()
+{
+ bt::UpdateCurrentTime();
+ AuthenticationMonitor::instance().update();
+
+ TQPtrList<kt::TorrentInterface>::iterator i = qman->begin();
+ //Uint32 down_speed = 0;
+ while (i != qman->end())
+ {
+ bool finished = false;
+ kt::TorrentInterface* tc = *i;
+ if (tc->isCheckingData(finished))
+ {
+ if (finished)
+ tc->afterDataCheck();
+ }
+ else if (tc->getStats().running)
+ {
+ // see if we need to do a auto data check
+ if (Settings::autoRecheck() && tc->getStats().num_corrupted_chunks >= Settings::maxCorruptedBeforeRecheck())
+ {
+ Out(SYS_GEN|LOG_IMPORTANT) << "Doing an automatic data check on "
+ << tc->getStats().torrent_name << endl;
+
+ ScanDialog* scan_dlg = new ScanDialog(this,false);
+ scan_dlg->show();
+ scan_dlg->execute(tc,true);
+ }
+ else
+ {
+ tc->update();
+ }
+ }
+ i++;
+ }
+}
+
+void KTorrentCore::makeTorrent(const TQString & file,const TQStringList & trackers,
+ int chunk_size,const TQString & name,
+ const TQString & comments,bool seed,
+ const TQString & output_file,bool priv_tor,KProgress* prog, bool decentralized)
+{
+ TQString tdir;
+ try
+ {
+ if (chunk_size < 0)
+ chunk_size = 256;
+
+ bt::TorrentCreator mktor(file,trackers,chunk_size,name,comments,priv_tor, decentralized);
+ prog->setTotalSteps(mktor.getNumChunks());
+ Uint32 ns = 0;
+ while (!mktor.calculateHash())
+ {
+ prog->setProgress(ns);
+ ns++;
+ if (ns % 10 == 0)
+ tdeApp->processEvents();
+ }
+
+ mktor.saveTorrent(output_file);
+ tdir = findNewTorrentDir();
+ kt::TorrentInterface* tc = mktor.makeTC(tdir);
+ if (tc)
+ {
+ connectSignals(tc);
+ qman->append(tc);
+ if (seed)
+ start(tc);
+ torrentAdded(tc);
+ }
+ }
+ catch (bt::Error & e)
+ {
+ // cleanup if necessary
+ if (bt::Exists(tdir))
+ bt::Delete(tdir,true);
+
+ // Show error message
+ KMessageBox::error(0,
+ i18n("Cannot create torrent: %1").arg(e.toString()),
+ i18n("Error"));
+ }
+}
+
+CurrentStats KTorrentCore::getStats()
+{
+ CurrentStats stats;
+ Uint64 bytes_dl = 0, bytes_ul = 0;
+ Uint32 speed_dl = 0, speed_ul = 0;
+
+
+ for ( TQPtrList<kt::TorrentInterface>::iterator i = qman->begin(); i != qman->end(); ++i )
+ {
+ kt::TorrentInterface* tc = *i;
+ const TorrentStats & s = tc->getStats();
+ speed_dl += s.download_rate;
+ speed_ul += s.upload_rate;
+ bytes_dl += s.session_bytes_downloaded;
+ bytes_ul += s.session_bytes_uploaded;
+ }
+ stats.download_speed = speed_dl;
+ stats.upload_speed = speed_ul;
+ stats.bytes_downloaded = bytes_dl + removed_bytes_down;
+ stats.bytes_uploaded = bytes_ul + removed_bytes_up;
+
+ return stats;
+}
+
+bool KTorrentCore::changePort(Uint16 port)
+{
+ if (getNumTorrentsRunning() == 0)
+ {
+ Globals::instance().getServer().changePort(port);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void KTorrentCore::slotStoppedByError(kt::TorrentInterface* tc, TQString msg)
+{
+ emit torrentStoppedByError(tc, msg);
+}
+
+Uint32 KTorrentCore::getNumTorrentsRunning() const
+{
+ return qman->getNumRunning();
+}
+
+Uint32 KTorrentCore::getNumTorrentsNotRunning() const
+{
+ return qman->count() - qman->getNumRunning();
+}
+
+int KTorrentCore::countSeeds() const
+{
+ return qman->countSeeds();
+}
+
+int KTorrentCore::countDownloads() const
+{
+ return qman->countDownloads();
+}
+
+void KTorrentCore::addBlockedIP(TQString& ip)
+{
+ IPBlocklist& filter = IPBlocklist::instance();
+ filter.addRange(ip);
+}
+
+void KTorrentCore::removeBlockedIP(TQString& ip)
+{
+ IPBlocklist& filter = IPBlocklist::instance();
+ filter.removeRange(ip);
+}
+
+bt::QueueManager* KTorrentCore::getQueueManager()
+{
+ return this->qman;
+}
+
+void KTorrentCore::torrentSeedAutoStopped( kt::TorrentInterface * tc,kt::AutoStopReason reason )
+{
+ qman->startNext();
+ if (reason == kt::MAX_RATIO_REACHED)
+ maxShareRatioReached(tc);
+ else
+ maxSeedTimeReached(tc);
+}
+
+int KTorrentCore::getMaxUploadSpeed()
+{
+ return Settings::maxUploadRate();
+}
+
+int KTorrentCore::getMaxDownloadSpeed()
+{
+ return Settings::maxDownloadRate();
+}
+
+void KTorrentCore::setMaxUploadSpeed(int v)
+{
+ return Settings::setMaxUploadRate(v);
+}
+
+void KTorrentCore::setMaxDownloadSpeed(int v)
+{
+ return Settings::setMaxDownloadRate(v);
+}
+
+void KTorrentCore::setPausedState(bool pause)
+{
+ qman->setPausedState(pause);
+}
+
+void KTorrentCore::queue(kt::TorrentInterface* tc)
+{
+ qman->queue(tc);
+}
+
+TorrentInterface* KTorrentCore::getTorFromNumber(int tornumber)
+{
+ TQString tordir = data_dir + "tor" + TQString("%1").arg(tornumber) + "/";
+ Out() << "tordir " << tordir << endl;
+ TQPtrList<TorrentInterface>::iterator i = qman->begin();
+ while(i != qman->end())
+ {
+ TorrentInterface* tc = *i;
+ TQString td = tc->getTorDir();
+ if(td == tordir)
+ return tc;
+ i++;
+ }
+ TorrentInterface* nullinterface = 0;
+ return nullinterface;
+}
+
+TQValueList<int> KTorrentCore::getTorrentNumbers(int type = 3)
+{
+ TQValueList<int> tornums;
+ TQPtrList<TorrentInterface>::iterator i = qman->begin();
+ while(i != qman->end())
+ {
+ TorrentInterface* tc = *i;
+ if((type == 1 && tc->getStats().completed) ||
+ (type == 2 && !(tc->getStats().completed)))
+ {
+ Out() << "Skipping a torrent" << endl;
+ i++;
+ continue;
+ }
+ TQString td = tc->getTorDir();
+ Out() << td << endl;
+ td = td.remove(0, td.length() - 6);
+ td = td.remove(TQRegExp("[^0-9]*"));
+ Out() << td << endl;
+ tornums.append(td.toInt());
+ i++;
+ }
+ return tornums;
+}
+
+Uint32 KTorrentCore::getFileCount(int tornumber)
+{
+ kt::TorrentInterface* tc = getTorFromNumber(tornumber);
+ if(tc)
+ return tc->getNumFiles();
+ else
+ return 0;
+}
+
+QCStringList KTorrentCore::getFileNames(int tornumber)
+{
+ QCStringList filenames;
+ kt::TorrentInterface* tc = getTorFromNumber(tornumber);
+ if(!tc || tc->getNumFiles() == 0)
+ return filenames;
+ for(Uint32 i = 0; i < tc->getNumFiles(); i++)
+ {
+ TQCString filename = tc->getTorrentFile(i).getPath().ascii();
+ filenames.append(filename);
+ }
+
+ return filenames;
+}
+
+TQValueList<int> KTorrentCore::getFilePriorities(int tornumber)
+{
+ TQValueList<int> priorities;
+ kt::TorrentInterface* tc = getTorFromNumber(tornumber);
+ if(!tc || tc->getNumFiles() == 0)
+ return priorities;
+
+ for(Uint32 i = 0; i < tc->getNumFiles(); i++)
+ {
+ bt::Priority priority = tc->getTorrentFile(i).getPriority();
+ int newpriority;
+ switch(priority)
+ {
+ case bt::FIRST_PRIORITY:
+ newpriority = 3;
+ break;
+ case bt::LAST_PRIORITY:
+ newpriority = 1;
+ break;
+ case bt::EXCLUDED:
+ newpriority = 0;
+ break;
+ default:
+ newpriority = 2;
+ break;
+ }
+ priorities.append(newpriority);
+ }
+ return priorities;
+}
+
+void KTorrentCore::setFilePriority(kt::TorrentInterface* tc, Uint32 index,
+ int priority)
+{
+ bt::Priority newpriority;
+ switch(priority)
+ {
+ case 3:
+ newpriority = bt::FIRST_PRIORITY;
+ break;
+ case 1:
+ newpriority = bt::LAST_PRIORITY;
+ break;
+ case 0:
+ newpriority = bt::EXCLUDED;
+ break;
+ default:
+ newpriority = bt::NORMAL_PRIORITY;
+ break;
+ }
+
+ tc->getTorrentFile(index).setPriority(newpriority);
+}
+
+void KTorrentCore::announceByTorNum(int tornumber)
+{
+ kt::TorrentInterface* tc = getTorFromNumber(tornumber);
+ if(tc)
+ tc->updateTracker();
+}
+
+void KTorrentCore::aboutToBeStarted(kt::TorrentInterface* tc,bool & ret)
+{
+ ret = true;
+
+ TQStringList missing;
+ if (!tc->hasMissingFiles(missing))
+ return;
+
+
+ if (tc->getStats().multi_file_torrent)
+ {
+ TQString msg = i18n("Several data files of the torrent \"%1\" are missing, do you want to recreate them, or do you want to not download them?").arg(tc->getStats().torrent_name);
+
+ int ret = KMessageBox::warningYesNoCancelList(0,msg,missing,TQString(),
+ KGuiItem(i18n("Recreate")),KGuiItem(i18n("Do Not Download")));
+ if (ret == KMessageBox::Yes)
+ {
+ try
+ {
+ // recreate them
+ tc->recreateMissingFiles();
+ }
+ catch (bt::Error & e)
+ {
+ KMessageBox::error(0,i18n("Cannot recreate missing files: %1").arg(e.toString()));
+ tc->handleError(i18n("Data files are missing"));
+ ret = false;
+ }
+ }
+ else if (ret == KMessageBox::No)
+ {
+ try
+ {
+ // mark them as do not download
+ tc->dndMissingFiles();
+ }
+ catch (bt::Error & e)
+ {
+ KMessageBox::error(0,i18n("Cannot deselect missing files: %1").arg(e.toString()));
+ tc->handleError(i18n("Data files are missing"));
+ ret = false;
+ }
+ }
+ else
+ {
+ tc->handleError(i18n("Data files are missing"));
+ ret = false;
+ }
+ }
+ else
+ {
+ TQString msg = i18n("The file where the data is saved of the torrent \"%1\" is missing, do you want to recreate it?").arg(tc->getStats().torrent_name);
+ int ret = KMessageBox::warningYesNo(0,msg, i18n("Recreate"),KGuiItem(i18n("Recreate")),KGuiItem(i18n("Do Not Recreate")));
+ if (ret == KMessageBox::Yes)
+ {
+ try
+ {
+ tc->recreateMissingFiles();
+ }
+ catch (bt::Error & e)
+ {
+ KMessageBox::error(0,i18n("Cannot recreate data file: %1").arg(e.toString()));
+ tc->handleError(i18n("Data file is missing"));
+ ret = false;
+ }
+ }
+ else
+ {
+ tc->handleError(i18n("Data file is missing"));
+ ret = false;
+ }
+ }
+
+}
+
+void KTorrentCore::emitCorruptedData(kt::TorrentInterface* tc)
+{
+ corruptedData(tc);
+
+}
+
+void KTorrentCore::connectSignals(kt::TorrentInterface* tc)
+{
+ connect(tc,TQ_SIGNAL(finished(kt::TorrentInterface*)),
+ this,TQ_SLOT(torrentFinished(kt::TorrentInterface* )));
+ connect(tc, TQ_SIGNAL(stoppedByError(kt::TorrentInterface*, TQString )),
+ this, TQ_SLOT(slotStoppedByError(kt::TorrentInterface*, TQString )));
+ connect(tc, TQ_SIGNAL(seedingAutoStopped(kt::TorrentInterface*, kt::AutoStopReason)),
+ this, TQ_SLOT(torrentSeedAutoStopped(kt::TorrentInterface*, kt::AutoStopReason)));
+ connect(tc,TQ_SIGNAL(aboutToBeStarted( kt::TorrentInterface*,bool & )),
+ this, TQ_SLOT(aboutToBeStarted( kt::TorrentInterface*,bool & )));
+ connect(tc,TQ_SIGNAL(corruptedDataFound( kt::TorrentInterface* )),
+ this, TQ_SLOT(emitCorruptedData( kt::TorrentInterface* )));
+ connect(qman, TQ_SIGNAL(queuingNotPossible(kt::TorrentInterface*)),
+ this, TQ_SLOT(enqueueTorrentOverMaxRatio( kt::TorrentInterface* )));
+ connect(qman, TQ_SIGNAL(lowDiskSpace(kt::TorrentInterface*, bool)),
+ this, TQ_SLOT(onLowDiskSpace(kt::TorrentInterface*, bool)));
+
+}
+
+float KTorrentCore::getGlobalMaxShareRatio() const
+{
+ return Settings::maxRatio();
+}
+
+void KTorrentCore::enqueueTorrentOverMaxRatio(kt::TorrentInterface* tc)
+{
+ emit queuingNotPossible(tc);
+}
+
+
+void KTorrentCore::doDataCheck(kt::TorrentInterface* tc)
+{
+ bool dummy = false;
+ if (tc->isCheckingData(dummy))
+ return;
+
+ ScanDialog* scan_dlg = new ScanDialog(this,false);
+ scan_dlg->setCaption(i18n("Checking Data Integrity"));
+ scan_dlg->show();
+ scan_dlg->execute(tc,false);
+}
+
+void KTorrentCore::onLowDiskSpace(kt::TorrentInterface * tc, bool stopped)
+{
+ emit lowDiskSpace(tc, stopped);
+}
+
+#include "ktorrentcore.moc"
diff --git a/src/apps/ktorrent/ktorrentcore.h b/src/apps/ktorrent/ktorrentcore.h
new file mode 100644
index 0000000..4c79ad5
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentcore.h
@@ -0,0 +1,358 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTORRENTCORE_H
+#define KTORRENTCORE_H
+
+#include <tqmap.h>
+#include <tqtimer.h>
+#include <tqcstring.h>
+#include <util/constants.h>
+#include <interfaces/coreinterface.h>
+
+typedef TQValueList<TQCString> QCStringList;
+
+namespace bt
+{
+ class Server;
+ class QueueManager;
+ class TorrentControl;
+}
+
+namespace TDEIO
+{
+ class Job;
+}
+
+namespace kt
+{
+ class Plugin;
+ class PluginManager;
+ class GUIInterface;
+ class TorrentInterface;
+ class GroupManager;
+}
+
+
+
+
+class KProgress;
+
+/**
+ * @author Joris Guisson
+ * @brief Keeps track of all TorrentInterface objects
+ *
+ * This class keeps track of all TorrentInterface objects.
+ */
+class KTorrentCore : public kt::CoreInterface
+{
+ TQ_OBJECT
+
+public:
+ KTorrentCore(kt::GUIInterface* gui);
+ virtual ~KTorrentCore();
+
+
+ kt::PluginManager & getPluginManager() {return *pman;}
+ const kt::PluginManager & getPluginManager() const {return *pman;}
+
+ /**
+ * Load all torrents from the data dir.
+ */
+ void loadTorrents();
+
+ /**
+ * Load an existing torrent, which has already a properly set up torX dir.
+ * @param tor_dir The torX dir
+ */
+ void loadExistingTorrent(const TQString & tor_dir);
+
+ /**
+ * Set the maximum number of simultanious downloads.
+ * @param max The max num (0 == no limit)
+ */
+ void setMaxDownloads(int max);
+
+ /**
+ * Set the maximum number of simultaneous seeds.
+ * @param max The max num (0 == no limit)
+ */
+ void setMaxSeeds(int max);
+
+ /**
+ * Set wether or not we should keep seeding after
+ * a download has finished.
+ * @param ks Keep seeding yes or no
+ */
+ void setKeepSeeding(bool ks);
+
+ /**
+ * Change the data dir. This involves copying
+ * all data from the old dir to the new.
+ * This can offcourse go horribly wrong, therefore
+ * if it doesn't succeed it returns false
+ * and leaves everything where it supposed to be.
+ * @param new_dir The new directory
+ */
+ bool changeDataDir(const TQString & new_dir);
+
+ /**
+ * Save active torrents on exit.
+ */
+ void onExit();
+
+ /**
+ * Start all, takes into account the maximum number of downloads.
+ * @param type Wether to start all downloads or seeds. 1=Downloads, 2=Seeds, 3=All
+ */
+ void startAll(int type);
+
+ /**
+ * Stop all torrents.
+ * @param type Wether to start all downloads or seeds. 1=Downloads, 2=Seeds, 3=All
+ */
+ void stopAll(int type);
+
+ /**
+ * Make a torrent file
+ * @param file The file or dir to make a torrent of
+ * @param trackers A list of trackers
+ * @param chunk_size The size of each chunk (in KB)
+ * @param name The torrents name (usually filename)
+ * @param comments The comments
+ * @param seed Wether or not to start seeding or not
+ * @param output_file File to store the torrent file
+ * @param priv_tor Is this a private torrent
+ * @param prog Progress bar to update
+ */
+ void makeTorrent(const TQString & file,const TQStringList & trackers,
+ int chunk_size,const TQString & name,const TQString & comments,
+ bool seed,const TQString & output_file,bool priv_tor,KProgress* prog, bool decentralized);
+
+ CurrentStats getStats();
+
+ /**
+ * Switch the port when no torrents are running.
+ * @param port The new port
+ * @return true if we can, false if there are torrents running
+ */
+ bool changePort(bt::Uint16 port);
+
+ /// Get the number of torrents running (including seeding torrents).
+ bt::Uint32 getNumTorrentsRunning() const;
+
+ /// Get the number of torrents not running.
+ bt::Uint32 getNumTorrentsNotRunning() const;
+
+ ///Inserts blocked IP range into IPBlocklist
+ void addBlockedIP(TQString& ip);
+
+ ///Removes blocked IP range from IPBlocklist
+ void removeBlockedIP(TQString& ip);
+
+ /**
+ * Find the next free torX dir.
+ * @return Path to the dir (including the torX part)
+ */
+ TQString findNewTorrentDir() const;
+
+ /**
+ * Load plugins.
+ */
+ void loadPlugins();
+
+ virtual void load(const KURL& url);
+ virtual void loadSilently(const KURL& url);
+ virtual void loadSilentlyDir(const KURL& url, const KURL& savedir);
+ virtual float getGlobalMaxShareRatio() const;
+
+
+ bt::QueueManager* getQueueManager();
+
+ kt::GroupManager* getGroupManager() const { return gman; }
+ void setGroupManager(kt::GroupManager* g) { gman = g; }
+
+ ///Gets the number of torrents running
+ int getNumRunning(bool onlyDownloads = true, bool onlySeeds = false) const;
+ ///Gets the number of torrents that are in state 'download' - total
+ int countDownloads() const;
+ ///Gets the number of torrents that are in state 'seed' - total
+ int countSeeds() const;
+
+ int getMaxDownloadSpeed();
+ int getMaxUploadSpeed();
+ void setMaxDownloadSpeed(int v);
+ void setMaxUploadSpeed(int v);
+
+ void setPausedState(bool pause);
+
+ kt::TorrentInterface* getTorFromNumber(int tornumber);
+ TQValueList<int> getTorrentNumbers(int type);
+ unsigned int getFileCount(int tornumber);
+ QCStringList getFileNames(int tornumber);
+ TQValueList<int> getFilePriorities(int tornumber);
+ void setFilePriority(kt::TorrentInterface* tc, bt::Uint32 index, int priority);
+ void announceByTorNum(int tornumber);
+
+
+public slots:
+ /**
+ * Load a torrent file. Pops up an error dialog
+ * if something goes wrong.
+ * @param file The torrent file (always a local file)
+ * @param dir Directory to save the data
+ * @param silently Wether or not to do this silently
+ */
+ bool load(const TQString & file,const TQString & dir,bool silently);
+
+ /**
+ * Load a torrent file. Pops up an error dialog
+ * if something goes wrong.
+ * @param data Byte array of the torrent file
+ * @param dir Directory to save the data
+ * @param silently Wether or not to do this silently
+ */
+ bool load(const TQByteArray & data,const TQString & dir,bool silently, const KURL& url);
+
+ /**
+ * Remove a download.This will delete all temp
+ * data from this TorrentInterface And delete the
+ * TorrentInterface itself. It can also potentially
+ * start a new download (when one is waiting to be downloaded).
+ * @param tc
+ * @param data_to
+ */
+ void remove(kt::TorrentInterface* tc,bool data_to);
+
+ /**
+ * Update all torrents.
+ */
+ void update();
+
+ /**
+ * Start a torrent, takes into account the maximum number of downloads.
+ * @param tc The TorrentInterface
+ */
+ void start(kt::TorrentInterface* tc);
+
+ /**
+ * Stop a torrent, may start another download if it hasn't been started.
+ * @param tc The TorrentInterface
+ */
+ void stop(kt::TorrentInterface* tc, bool user = false);
+
+ /**
+ * Enqueue/Dequeue function. Places a torrent in queue.
+ * If the torrent is already in queue this will remove it from queue.
+ * @param tc TorrentControl pointer.
+ */
+ void queue(kt::TorrentInterface* tc);
+
+ /**
+ * A torrent is about to be started. We will do some file checks upon this signal.
+ * @param tc The TorrentInterface
+ */
+ void aboutToBeStarted(kt::TorrentInterface* tc,bool & ret);
+
+ /**
+ * User tried to enqueue a torrent that has reached max share ratio.
+ * Emits appropriate signal.
+ */
+ void enqueueTorrentOverMaxRatio(kt::TorrentInterface* tc);
+
+ /**
+ * Do a data check on a torrent
+ * @param tc
+ */
+ void doDataCheck(kt::TorrentInterface* tc);
+
+ ///Fires when disk space is running low
+ void onLowDiskSpace(kt::TorrentInterface* tc, bool stopped);
+
+signals:
+ /**
+ * TorrentCore torrents have beed updated. Stats are changed.
+ **/
+ void statsUpdated();
+
+ /**
+ * Emitted when a torrent has reached it's max share ratio.
+ * @param tc The torrent
+ */
+ void maxShareRatioReached(kt::TorrentInterface* tc);
+
+ /**
+ * Emitted when a torrent has reached it's max seed time
+ * @param tc The torrent
+ */
+ void maxSeedTimeReached(kt::TorrentInterface* tc);
+
+ /**
+ * Corrupted data has been detected.
+ * @param tc The torrent with the corrupted data
+ */
+ void corruptedData(kt::TorrentInterface* tc);
+
+ /**
+ * User tried to enqueue a torrent that has reached max share ratio. It's not possible.
+ * Signal should be connected to SysTray slot which shows appropriate KPassivePopup info.
+ * @param tc The torrent in question.
+ */
+ void queuingNotPossible(kt::TorrentInterface* tc);
+
+ /**
+ * Emitted when a torrent cannot be started
+ * @param tc The torrent
+ * @param reason The reason
+ */
+ void canNotStart(kt::TorrentInterface* tc,kt::TorrentStartResponse reason);
+
+ /**
+ * Diskspace is running low.
+ * Signal should be connected to SysTray slot which shows appropriate KPassivePopup info.
+ * @param tc The torrent in question.
+ */
+ void lowDiskSpace(kt::TorrentInterface* tc, bool stopped);
+
+private:
+ void rollback(const TQPtrList<kt::TorrentInterface> & success);
+ void connectSignals(kt::TorrentInterface* tc);
+ bool init(bt::TorrentControl* tc,bool silently);
+
+private slots:
+ void torrentFinished(kt::TorrentInterface* tc);
+ void slotStoppedByError(kt::TorrentInterface* tc, TQString msg);
+ void torrentSeedAutoStopped(kt::TorrentInterface* tc,kt::AutoStopReason reason);
+ void downloadFinished(TDEIO::Job *job);
+ void downloadFinishedSilently(TDEIO::Job *job);
+ void emitCorruptedData(kt::TorrentInterface* tc);
+
+private:
+ TQString data_dir;
+ int max_downloads;
+ bool keep_seeding;
+ TQTimer update_timer;
+ bt::Uint64 removed_bytes_up,removed_bytes_down;
+ kt::PluginManager* pman;
+ bt::QueueManager* qman;
+ kt::GroupManager* gman;
+ TQMap<TDEIO::Job*,KURL> custom_save_locations; // map to store save locations
+};
+
+#endif
diff --git a/src/apps/ktorrent/ktorrentdcop.cpp b/src/apps/ktorrent/ktorrentdcop.cpp
new file mode 100644
index 0000000..10e09cb
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentdcop.cpp
@@ -0,0 +1,254 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <kurl.h>
+#include "ktorrentdcop.h"
+#include "ktorrent.h"
+#include "ktorrentcore.h"
+#include "settings.h"
+#include <torrent/ipblocklist.h>
+
+KTorrentDCOP::KTorrentDCOP(KTorrent* app)
+ : DCOPObject("KTorrent"),app(app)
+{}
+
+
+KTorrentDCOP::~KTorrentDCOP()
+{}
+
+
+bool KTorrentDCOP::changeDataDir(const TQString& new_dir)
+{
+ Settings::setTempDir(new_dir);
+ Settings::writeConfig();
+ return app->getCore().changeDataDir(new_dir);
+}
+
+void KTorrentDCOP::openTorrent(const TQString& file)
+{
+ app->load(KURL::fromPathOrURL(file));
+}
+
+void KTorrentDCOP::openTorrentSilently(const TQString & file)
+{
+ app->loadSilently(KURL::fromPathOrURL(file));
+}
+
+void KTorrentDCOP::setKeepSeeding(bool ks)
+{
+ Settings::setKeepSeeding(ks);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setMaxConnectionsPerDownload(int max)
+{
+ Settings::setMaxConnections(max);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setMaxDownloads(int max)
+{
+ Settings::setMaxDownloads(max);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setMaxSeeds(int max)
+{
+ Settings::setMaxSeeds(max);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setMaxUploadSpeed(int kbytes_per_sec)
+{
+ Settings::setMaxUploadRate(kbytes_per_sec);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setMaxDownloadSpeed(int kbytes_per_sec)
+{
+ Settings::setMaxDownloadRate(kbytes_per_sec);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::setShowSysTrayIcon(bool yes)
+{
+ Settings::setShowSystemTrayIcon(yes);
+ Settings::writeConfig();
+ app->applySettings();
+}
+
+void KTorrentDCOP::startAll(int type)
+{
+ app->getCore().startAll(type);
+}
+
+void KTorrentDCOP::stopAll(int type)
+{
+ app->getCore().stopAll(type);
+}
+
+void KTorrentDCOP::start(int tornumber)
+{
+ kt::TorrentInterface* tc = app->getCore().getTorFromNumber(tornumber);
+ if(tc)
+ app->getCore().start(tc);
+}
+
+void KTorrentDCOP::stop(int tornumber, bool user)
+{
+ kt::TorrentInterface* tc = app->getCore().getTorFromNumber(tornumber);
+ if(tc)
+ app->getCore().stop(tc, user);
+}
+
+TQValueList<int> KTorrentDCOP::getTorrentNumbers(int type)
+{
+ return app->getCore().getTorrentNumbers(type);
+}
+
+QCStringList KTorrentDCOP::getTorrentInfo(int tornumber)
+{
+ QCStringList torrentinfo;
+ kt::TorrentInterface* tc = app->getCore().getTorFromNumber(tornumber);
+ if(tc)
+ torrentinfo = app->getTorrentInfo(tc);
+ return torrentinfo;
+}
+
+
+QCStringList KTorrentDCOP::getInfo()
+{
+ QCStringList info;
+ TQString thisinfo = app->getStatusInfo();
+ info.append(thisinfo.ascii());
+ thisinfo = app->getStatusTransfer();
+ info.append(thisinfo.ascii());
+ thisinfo = app->getStatusSpeed();
+ info.append(thisinfo.ascii());
+ thisinfo = app->getStatusDHT();
+ info.append(thisinfo.ascii());
+ return info;
+}
+
+int KTorrentDCOP::getFileCount(int tornumber)
+{
+ return app->getCore().getFileCount(tornumber);
+}
+
+QCStringList KTorrentDCOP::getFileNames(int tornumber)
+{
+ return app->getCore().getFileNames(tornumber);
+}
+
+TQValueList<int> KTorrentDCOP::getFilePriorities(int tornumber)
+{
+ return app->getCore().getFilePriorities(tornumber);
+}
+
+void KTorrentDCOP::setFilePriority(int tornumber,
+ int index, int priority)
+{
+ kt::TorrentInterface* tc = app->getCore().getTorFromNumber(tornumber);
+ if(tc)
+ app->getCore().setFilePriority(tc, index, priority);
+}
+
+void KTorrentDCOP::remove(int tornumber, bool del_data)
+{
+ kt::TorrentInterface* tc = app->getCore().getTorFromNumber(tornumber);
+ if(tc)
+ app->getCore().remove(tc, del_data);
+}
+
+void KTorrentDCOP::announce(int tornumber)
+{
+ app->getCore().announceByTorNum(tornumber);
+}
+
+TQCString KTorrentDCOP::dataDir()
+{
+ TQCString dir = Settings::tempDir().ascii();
+ return dir;
+}
+
+int KTorrentDCOP::maxDownloads()
+{
+ return Settings::maxDownloads();
+}
+
+int KTorrentDCOP::maxSeeds()
+{
+ return Settings::maxSeeds();
+}
+
+int KTorrentDCOP::maxConnections()
+{
+ return Settings::maxConnections();
+}
+
+int KTorrentDCOP::maxUploadRate()
+{
+ return Settings::maxUploadRate();
+}
+
+int KTorrentDCOP::maxDownloadRate()
+{
+ return Settings::maxDownloadRate();
+}
+
+bool KTorrentDCOP::keepSeeding()
+{
+ return Settings::keepSeeding();
+}
+
+bool KTorrentDCOP::showSystemTrayIcon()
+{
+ return Settings::showSystemTrayIcon();
+}
+
+TQValueList<int> KTorrentDCOP::intSettings()
+{
+ TQValueList<int> intsettings;
+ intsettings.append(Settings::maxDownloads());
+ intsettings.append(Settings::maxSeeds());
+ intsettings.append(Settings::maxConnections());
+ intsettings.append(Settings::maxUploadRate());
+ intsettings.append(Settings::maxDownloadRate());
+ intsettings.append((int)Settings::keepSeeding());
+ intsettings.append((int)Settings::showSystemTrayIcon());
+ return intsettings;
+}
+
+bool KTorrentDCOP::isBlockedIP(TQString ip)
+{
+ return bt::IPBlocklist::instance().isBlocked(ip);
+}
+
+void KTorrentDCOP::openTorrentSilentlyDir(const TQString & file, const TQString & savedir)
+{
+ app->loadSilentlyDir(KURL::fromPathOrURL(file), KURL::fromPathOrURL(savedir));
+}
+
+#include "ktorrentdcop.moc"
diff --git a/src/apps/ktorrent/ktorrentdcop.h b/src/apps/ktorrent/ktorrentdcop.h
new file mode 100644
index 0000000..14f30ba
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentdcop.h
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTORRENTDCOP_H
+#define KTORRENTDCOP_H
+
+#include "dcopinterface.h"
+
+class KTorrent;
+
+/**
+@author Joris Guisson
+*/
+class KTorrentDCOP : public TQObject,virtual public DCOPInterface
+{
+ TQ_OBJECT
+
+ KTorrent* app;
+public:
+ KTorrentDCOP(KTorrent* app);
+ ~KTorrentDCOP();
+
+ virtual bool changeDataDir(const TQString& new_dir);
+ virtual void openTorrent(const TQString& file);
+ virtual void openTorrentSilently(const TQString & file);
+ virtual void setKeepSeeding(bool ks);
+ virtual void setMaxConnectionsPerDownload(int max);
+ virtual void setMaxDownloads(int max);
+ virtual void setMaxSeeds(int max);
+ virtual void setMaxUploadSpeed(int kbytes_per_sec);
+ virtual void setMaxDownloadSpeed(int kbytes_per_sec);
+ virtual void setShowSysTrayIcon(bool yes);
+ virtual void startAll(int type = 3);
+ virtual void stopAll(int type = 3);
+ virtual TQValueList<int> getTorrentNumbers(int type = 3);
+ virtual QCStringList getTorrentInfo(int tornumber);
+ virtual int getFileCount(int tornumber);
+ virtual QCStringList getInfo();
+ virtual QCStringList getFileNames(int tornumber);
+ virtual TQValueList<int> getFilePriorities(int tornumber);
+ virtual void setFilePriority(int tornumber, int index, int priority);
+ virtual void start(int tornumber);
+ virtual void stop(int tornumber, bool user);
+ virtual void remove(int tornumber, bool del_data);
+ virtual void announce(int tornumber);
+ virtual TQCString dataDir();
+ virtual int maxDownloads();
+ virtual int maxSeeds();
+ virtual int maxConnections();
+ virtual int maxUploadRate();
+ virtual int maxDownloadRate();
+ virtual bool keepSeeding();
+ virtual bool showSystemTrayIcon();
+ virtual TQValueList<int> intSettings();
+ virtual bool isBlockedIP(TQString ip);
+ virtual void openTorrentSilentlyDir(const TQString & file, const TQString & savedir);
+
+};
+
+#endif
diff --git a/src/apps/ktorrent/ktorrentplugin.desktop b/src/apps/ktorrent/ktorrentplugin.desktop
new file mode 100644
index 0000000..298abb0
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentplugin.desktop
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Name=KTorrent Plugin
+
+Type=ServiceType
+X-TDE-ServiceType=KTorrent/Plugin
diff --git a/src/apps/ktorrent/ktorrentui.rc b/src/apps/ktorrent/ktorrentui.rc
new file mode 100644
index 0000000..a5845a1
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentui.rc
@@ -0,0 +1,44 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="ktorrent" version="1">
+<MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="paste_url"/>
+ <Action name="ipfilter_action"/>
+ <Merge/>
+ </Menu>
+ <Menu name="Downloads"><text>Downloads</text>
+ <Action name="Start" />
+ <Action name="Stop" />
+ <Action name="Remove" />
+ <Separator/>
+ <Action name="Start all"/>
+ <Action name="Stop all"/>
+ <Separator/>
+ <Action name="check_data"/>
+ <Separator/>
+ <Action name="queue_action"/>
+ <Action name="Queue manager"/>
+ </Menu>
+</MenuBar>
+
+<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text>
+ <Action name="file_new"/>
+ <Action name="file_open"/>
+ <Action name="file_save"/>
+ <Separator/>
+ <Action name="edit_copy"/>
+ <Action name="edit_paste"/>
+ <Separator/>
+ <Action name="ipfilter_action"/>
+</ToolBar>
+<ToolBar name="DownloadToolBar" noMerge="1"><text>Download Toolbar</text>
+ <Action name="Start"/>
+ <Action name="Stop"/>
+ <Action name="Remove"/>
+ <Action name="Start all"/>
+ <Action name="Stop all"/>
+ <Action name="queue_action"/>
+ <Separator/>
+ <Action name="Queue manager"/>
+</ToolBar>
+</kpartgui>
diff --git a/src/apps/ktorrent/ktorrentview.cpp b/src/apps/ktorrent/ktorrentview.cpp
new file mode 100644
index 0000000..15e1d83
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentview.cpp
@@ -0,0 +1,912 @@
+/***************************************************************************
+ * Copyright (C) 2005,2006 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 <tdelocale.h>
+#include <tdeglobal.h>
+#include <kiconloader.h>
+#include <tdepopupmenu.h>
+#include <krun.h>
+#include <kurl.h>
+#include <kurldrag.h>
+#include <tdemessagebox.h>
+#include <kstdguiitem.h>
+#include <tdefiledialog.h>
+
+#include <interfaces/torrentinterface.h>
+#include <torrent/globals.h>
+#include <util/log.h>
+#include <util/functions.h>
+
+#include <groups/group.h>
+#include <groups/torrentdrag.h>
+
+#include <tqcursor.h>
+#include <tqheader.h>
+#include <tqvaluelist.h>
+#include <tqlayout.h>
+
+#include "ktorrentview.h"
+#include "ktorrentviewitem.h"
+#include "settings.h"
+#include "scandialog.h"
+#include "addpeerwidget.h"
+#include "ktorrentviewmenu.h"
+#include "speedlimitsdlg.h"
+#include "filterbar.h"
+
+using namespace bt;
+using namespace kt;
+
+
+TorrentView::TorrentView(KTorrentView* parent) : TDEListView(parent),ktview(parent)
+{}
+
+TorrentView::~TorrentView()
+{}
+
+bool TorrentView::eventFilter(TQObject* watched, TQEvent* e)
+{
+ if((TQHeader*)watched == header())
+ {
+ switch(e->type())
+ {
+ case TQEvent::MouseButtonPress:
+ {
+ if(static_cast<TQMouseEvent*>(e)->button() == TQt::RightButton)
+ ktview->m_headerMenu->popup(TQCursor::pos());
+
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return TDEListView::eventFilter(watched, e);
+}
+
+KTorrentView::KTorrentView(TQWidget *parent)
+ : TQWidget(parent),menu(0),current_group(0),running(0),total(0),view(0),filter_bar(0)
+{
+ TQVBoxLayout* layout = new TQVBoxLayout(this);
+ layout->setAutoAdd(true);
+ view = new TorrentView(this);
+ filter_bar = new FilterBar(this);
+ filter_bar->setHidden(true);
+
+ setupColumns();
+
+ connect(view,TQ_SIGNAL(executed(TQListViewItem* )),
+ this,TQ_SLOT(onExecuted(TQListViewItem* )));
+
+ connect(view,TQ_SIGNAL(currentChanged(TQListViewItem* )),
+ this,TQ_SLOT(onExecuted(TQListViewItem* )));
+
+ connect(view,TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*, const TQPoint& )),
+ this,TQ_SLOT(showContextMenu(TDEListView*, TQListViewItem*, const TQPoint& )));
+
+ connect(view,TQ_SIGNAL(selectionChanged()),this,TQ_SLOT(onSelectionChanged()));
+
+ menu = new KTorrentViewMenu(this);
+ connect(menu,TQ_SIGNAL(groupItemActivated(const TQString&)),this,TQ_SLOT(gsmItemActived(const TQString&)));
+
+ connect(m_headerMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(onColumnVisibilityChange( int )));
+
+ view->setFrameShape(TQFrame::NoFrame);
+}
+
+KTorrentView::~KTorrentView()
+{
+}
+
+void KTorrentView::insertColumn(TQString label, TQt::AlignmentFlags align)
+{
+ m_headerMenu->insertItem(label);
+
+ int ind = view->addColumn(label);
+ view->setColumnAlignment(ind, align);
+}
+
+void KTorrentView::setupColumns()
+{
+ //Header menu
+ m_headerMenu = new TDEPopupMenu(view);
+ m_headerMenu->setCheckable(true);
+ m_headerMenu->insertTitle(i18n("Visible columns"));
+
+ insertColumn(i18n("File"), TQt::AlignLeft);
+ insertColumn(i18n("Status"), TQt::AlignLeft);
+ insertColumn(i18n("Downloaded"), TQt::AlignRight);
+ insertColumn(i18n("Size"), TQt::AlignRight);
+ insertColumn(i18n("Uploaded"), TQt::AlignRight);
+ insertColumn(i18n("Down Speed"), TQt::AlignRight);
+ insertColumn(i18n("Up Speed"), TQt::AlignRight);
+ insertColumn(i18n("Time Left"), TQt::AlignCenter);
+ insertColumn(i18n("Seeders"), TQt::AlignRight);
+ insertColumn(i18n("Leechers"), TQt::AlignRight);
+ insertColumn(i18n("% Complete"), TQt::AlignRight);
+ insertColumn(i18n("Share Ratio"), TQt::AlignRight);
+ insertColumn(i18n("Time Downloaded"), TQt::AlignRight);
+ insertColumn(i18n("Time Seeded"), TQt::AlignRight);
+
+ view->setAllColumnsShowFocus(true);
+ view->setShowSortIndicator(true);
+ view->setAcceptDrops(true);
+ view->setSelectionMode(TQListView::Extended);
+ for (Uint32 i = 0;i < (Uint32)view->columns();i++)
+ {
+ view->setColumnWidth(i, 100);
+ view->setColumnWidthMode(i,TQListView::Manual);
+ }
+}
+
+void KTorrentView::setCurrentGroup(Group* group)
+{
+ if (current_group == group)
+ return;
+
+ current_group = group;
+
+ running = 0;
+ total = 0;
+ // go over the current items, if they still match keep them, else remove them
+ // add new itesm if necessary
+ TQMap<TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ KTorrentViewItem* tvi = i.data();
+ TorrentInterface* tc = i.key();
+ if (current_group && !current_group->isMember(tc))
+ {
+ if (tvi)
+ {
+ delete tvi;
+ i.data() = 0;
+ }
+ }
+ else if (!tvi)
+ {
+ tvi = new KTorrentViewItem(this,tc);
+ i.data() = tvi;
+ }
+
+ if (i.data())
+ {
+ total++;
+ if (tc->getStats().running)
+ running++;
+ }
+
+ i++;
+ }
+
+ if (current_group)
+ setCaption(TQString("%1 %2/%3").arg(current_group->groupName()).arg(running).arg(total));
+ else
+ setCaption(i18n("All Torrents %1/%2").arg(running).arg(total));
+
+ onSelectionChanged();
+ onExecuted(view->currentItem());
+}
+
+void KTorrentView::saveSettings(TDEConfig* cfg,int idx)
+{
+ TQString group = TQString("KTorrentView-%1").arg(idx);
+ view->saveLayout(cfg,group);
+ cfg->setGroup(group);
+ filter_bar->saveSettings(cfg);
+}
+
+
+void KTorrentView::loadSettings(TDEConfig* cfg,int idx)
+{
+ TQString group = TQString("KTorrentView-%1").arg(idx);
+ view->restoreLayout(cfg,group);
+ view->setDragEnabled(true);
+
+ for(int i=0; i < view->columns();++i)
+ {
+ bool visible = columnVisible(i);
+
+ m_headerMenu->setItemChecked(m_headerMenu->idAt(i+1), visible);
+ view->header()->setResizeEnabled(visible, i);
+ }
+ cfg->setGroup(group);
+ filter_bar->loadSettings(cfg);
+}
+
+
+int KTorrentView::getNumRunning()
+{
+ int num = 0;
+ TQMap<TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ KTorrentViewItem* tvi = i.data();
+ if (tvi)
+ {
+ TorrentInterface* tc = tvi->getTC();
+ num += tc->getStats().running ? 1 : 0;
+ }
+ i++;
+ }
+ return num;
+}
+
+bool KTorrentView::startDownload(kt::TorrentInterface* tc)
+{
+ if (tc && !tc->getStats().running)
+ {
+ wantToStart(tc);
+ if (!tc->getStats().running && !tc->getStats().stopped_by_error)
+ {
+ if (tc->getStats().completed)
+ {
+ if (!tc->overMaxRatio() && !tc->overMaxSeedTime())
+ return false;
+ }
+ else
+ return false;
+ }
+ }
+ return true;
+}
+
+void KTorrentView::stopDownload(kt::TorrentInterface* tc)
+{
+ if (tc && tc->getStats().running)
+ {
+ wantToStop(tc,true);
+ }
+}
+
+void KTorrentView::showStartError()
+{
+ TQString err = i18n("Cannot start more than 1 download, ",
+ "Cannot start more than %n downloads, ",Settings::maxDownloads());
+
+ err += i18n("and 1 seed. ","and %n seeds. ",Settings::maxSeeds());
+ err += i18n("Go to Settings -> Configure KTorrent, if you want to change the limits.");
+ KMessageBox::error(this,err);
+}
+
+void KTorrentView::startDownloads()
+{
+ bool err = false;
+
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (!startDownload(tc))
+ err = true;;
+ }
+
+ /*
+ if (err)
+ {
+ showStartError();
+ }
+ */
+ // make sure toolbuttons get updated
+ onSelectionChanged();
+}
+
+void KTorrentView::stopDownloads()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ stopDownload(kvi->getTC());
+ }
+
+ // make sure toolbuttons get updated
+ onSelectionChanged();
+}
+
+void KTorrentView::startAllDownloads()
+{
+ bool err = false;
+ TQMap<TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ KTorrentViewItem* tvi = i.data();
+ if (tvi && !startDownload(tvi->getTC()))
+ err = true;
+
+ i++;
+ }
+ /*
+ if (err)
+ {
+ showStartError();
+ }
+ */
+ onSelectionChanged();
+}
+
+void KTorrentView::stopAllDownloads()
+{
+ TQMap<TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ KTorrentViewItem* tvi = i.data();
+ if (tvi)
+ stopDownload(tvi->getTC());
+
+ i++;
+ }
+ onSelectionChanged();
+}
+
+void KTorrentView::removeDownloads()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy = false;
+ if (tc && !tc->isCheckingData(dummy))
+ {
+ const TorrentStats & s = tc->getStats();
+ bool data_to = false;
+ if (!s.completed)
+ {
+ TQString msg = i18n("The torrent %1 has not finished downloading, "
+ "do you want to delete the incomplete data, too?").arg(s.torrent_name);
+ int ret = KMessageBox::questionYesNoCancel(
+ this,msg,i18n("Remove Download"),
+ i18n("Delete Data"),i18n("Keep Data"));
+ if (ret == KMessageBox::Cancel)
+ return;
+ else if (ret == KMessageBox::Yes)
+ data_to = true;
+ }
+ wantToRemove(tc,data_to);
+ }
+ }
+
+ // make sure toolbuttons get updated
+ onSelectionChanged();
+}
+
+void KTorrentView::removeDownloadsAndData()
+{
+ TQString msg = i18n("You will lose all the downloaded data. Are you sure you want to do this?");
+ // TODO: replace i18n("Remove") by KStdGuiItem::remove() in KDE4
+ if (KMessageBox::warningYesNo(this,msg, i18n("Remove Torrent"), i18n("&Remove"),
+ KStdGuiItem::cancel()) == KMessageBox::No)
+ return;
+
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc)
+ wantToRemove(tc,true);
+ }
+
+ // make sure toolbuttons get updated
+ onSelectionChanged();
+}
+
+void KTorrentView::manualAnnounce()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc && tc->getStats().running)
+ tc->updateTracker();
+ }
+}
+
+void KTorrentView::previewFiles()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc && tc->readyForPreview() && !tc->getStats().multi_file_torrent)
+ {
+ TQFileInfo fi(tc->getTorDir()+"cache");
+ new KRun(KURL::fromPathOrURL(fi.readLink()), 0, true, true);
+ }
+ }
+}
+
+TorrentInterface* KTorrentView::getCurrentTC()
+{
+ KTorrentViewItem* tvi = dynamic_cast<KTorrentViewItem*>(view->currentItem());
+ if (tvi)
+ return tvi->getTC();
+ else
+ return 0;
+}
+
+void KTorrentView::onExecuted(TQListViewItem* item)
+{
+ KTorrentViewItem* tvi = dynamic_cast<KTorrentViewItem*>(item);
+ if (tvi)
+ {
+ torrentClicked(tvi->getTC());
+ currentChanged(tvi->getTC());
+ }
+ else
+ {
+ currentChanged(0);
+ }
+}
+
+void KTorrentView::showContextMenu(TDEListView* ,TQListViewItem*,const TQPoint & p)
+{
+ updateGroupsSubMenu(menu->getGroupsSubMenu());
+ menu->show(p);
+}
+
+void KTorrentView::addTorrent(TorrentInterface* tc)
+{
+ if (current_group && !current_group->isMember(tc))
+ {
+ items.insert(tc,0);
+ }
+ else
+ {
+ KTorrentViewItem* tvi = new KTorrentViewItem(this,tc);
+ items.insert(tc,tvi);
+ tvi->update();
+ if (items.count() == 1)
+ currentChanged(tc);
+ }
+}
+
+void KTorrentView::removeTorrent(TorrentInterface* tc)
+{
+ TQMap<kt::TorrentInterface*,KTorrentViewItem*>::iterator i = items.find(tc);
+ if (i != items.end())
+ {
+ KTorrentViewItem* tvi = i.data();
+ items.erase(i);
+ delete tvi;
+ tvi = dynamic_cast<KTorrentViewItem*>(view->currentItem());
+ if (tvi)
+ currentChanged(tvi->getTC());
+ else
+ currentChanged(0);
+ }
+}
+
+
+void KTorrentView::update()
+{
+ Uint32 r = 0;
+ Uint32 t = 0;
+
+ TQMap<kt::TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ bool count = true;
+ KTorrentViewItem* tvi = i.data();
+ if (tvi)
+ tvi->update();
+ // check if the torrent still is part of the group
+ kt::TorrentInterface* ti = i.key();
+
+ bool member = (current_group->isMember(ti) && filter_bar->matchesFilter(ti));
+
+ if (tvi && current_group && !member)
+ {
+ // torrent is no longer a member of this group so remove it from the view
+ delete tvi;
+ i.data() = 0;
+ count = false;
+ }
+ else if (!tvi && (!current_group || member))
+ {
+ tvi = new KTorrentViewItem(this,ti);
+ i.data() = tvi;
+ }
+
+ if (i.data())
+ {
+ t++;
+ if (ti->getStats().running)
+ r++;
+ }
+
+ i++;
+ }
+
+ if (running != r || total != t)
+ {
+ running = r;
+ total = t;
+
+ if (current_group)
+ setCaption(TQString("%1 %2/%3").arg(current_group->groupName()).arg(running).arg(total));
+ else
+ setCaption(i18n("All Torrents %1/%2").arg(running).arg(total));
+ onSelectionChanged();
+ }
+
+ view->sort();
+}
+
+bool KTorrentView::acceptDrag(TQDropEvent* event) const
+{
+ // accept uri drops only
+ return KURLDrag::canDecode(event);
+}
+
+void KTorrentView::onSelectionChanged()
+{
+ int flags = 0;
+
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy;
+ if (tc && !tc->isCheckingData(dummy))
+ {
+ const TorrentStats & s = tc->getStats();
+ if (!s.running)
+ flags |= START;
+ else
+ flags |= STOP;
+
+ if (flags & (START|STOP))
+ break;
+ }
+ }
+
+ if (sel.count() > 0)
+ flags |= REMOVE;
+
+ if (sel.count() == 1)
+ flags |= SCAN;
+
+ if (running > 0)
+ flags |= STOP_ALL;
+
+ if (running == 0 && total > 0)
+ flags |= START_ALL;
+
+ updateActions(flags);
+}
+
+void KTorrentView::queueSlot()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy;
+ if (tc && !tc->isCheckingData(dummy))
+ emit queue(tc);
+ }
+}
+
+
+void KTorrentView::checkDataIntegrity()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ if (sel.count() == 0)
+ return;
+
+ bool dummy = false;
+ KTorrentViewItem* kvi = (KTorrentViewItem*)sel.first();
+ TorrentInterface* tc = kvi->getTC();
+ if (!tc->isCheckingData(dummy))
+ {
+ needsDataCheck(tc);
+ }
+ else
+ {
+ KMessageBox::error(0,i18n("You are already checking the data of the torrent %1 !").arg(tc->getStats().torrent_name));
+ }
+}
+
+TQDragObject* KTorrentView::dragObject()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ if (sel.count() == 0)
+ return 0;
+
+ return new TorrentDrag(this);
+}
+
+void KTorrentView::getSelection(TQValueList<kt::TorrentInterface*> & sel)
+{
+ TQPtrList<TQListViewItem> s = view->selectedItems();
+ if (s.count() == 0)
+ return;
+
+ TQPtrList<TQListViewItem>::iterator i = s.begin();
+ while (i != s.end())
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*i;
+ TorrentInterface* tc = kvi->getTC();
+ sel.append(tc);
+ i++;
+ }
+}
+
+void KTorrentView::removeFromGroup()
+{
+ TQPtrList<TQListViewItem> s = view->selectedItems();
+ if (s.count() == 0 || !current_group || current_group->isStandardGroup())
+ return;
+
+ TQPtrList<TQListViewItem>::iterator i = s.begin();
+ while (i != s.end())
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*i;
+ TorrentInterface* tc = kvi->getTC();
+ current_group->removeTorrent(tc);
+ delete kvi;
+ items[tc] = 0;
+ i++;
+ }
+}
+
+void KTorrentView::addSelectionToGroup(kt::Group* g)
+{
+ TQPtrList<TQListViewItem> s = view->selectedItems();
+ if (s.count() == 0 || !g)
+ return;
+
+ TQPtrList<TQListViewItem>::iterator i = s.begin();
+ while (i != s.end())
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*i;
+ TorrentInterface* tc = kvi->getTC();
+ g->addTorrent(tc);
+ i++;
+ }
+}
+
+void KTorrentView::showAddPeersWidget()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy;
+ if (tc && !tc->isCheckingData(dummy))
+ {
+ AddPeerWidget dlg(tc, this);
+ dlg.exec();
+ }
+ }
+}
+
+void KTorrentView::openOutputDirectory()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc)
+ {
+ if(tc->getStats().multi_file_torrent)
+ new KRun(KURL::fromPathOrURL(tc->getStats().output_path), 0, true, true);
+ else
+ new KRun(KURL::fromPathOrURL(tc->getDataDir()), 0, true, true);
+ }
+ }
+}
+
+void KTorrentView::openTorXDirectory()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc)
+ {
+ new KRun(KURL::fromPathOrURL(tc->getTorDir()), 0, true, true);
+ }
+ }
+}
+
+void KTorrentView::setDownloadLocationSlot()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc)
+ {
+ TQString dn;
+ dn = KFileDialog::getExistingDirectory(tc->getStats().output_path, this, i18n("Choose download location for %1").arg(tc->getStats().torrent_name));
+
+ if(dn.isNull() || dn.isEmpty())
+ continue;
+
+ if(!dn.endsWith(bt::DirSeparator()))
+ dn += bt::DirSeparator();
+
+ if(!dn.isEmpty())
+ tc->changeOutputDir(dn);
+ }
+ }
+}
+
+void KTorrentView::dhtSlot()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy;
+ if (tc && !tc->isCheckingData(dummy))
+ {
+ bool on = tc->isFeatureEnabled(kt::DHT_FEATURE);
+ tc->setFeatureEnabled(kt::DHT_FEATURE,!on);
+ }
+ }
+}
+
+void KTorrentView::utPexSlot()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ bool dummy;
+ if (tc && !tc->isCheckingData(dummy))
+ {
+ bool on = tc->isFeatureEnabled(kt::UT_PEX_FEATURE);
+ tc->setFeatureEnabled(kt::UT_PEX_FEATURE,!on);
+ }
+ }
+}
+
+void KTorrentView::speedLimits()
+{
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ if (sel.count() != 1)
+ return;
+
+ KTorrentViewItem* kvi = (KTorrentViewItem*)sel.first();
+ TorrentInterface* tc = kvi->getTC();
+ SpeedLimitsDlg dlg(tc,0);
+ dlg.show();
+ dlg.exec();
+}
+
+
+void KTorrentView::columnHide(int index)
+{
+ view->hideColumn(index);
+ view->header()->setResizeEnabled(false, index);
+}
+
+void KTorrentView::columnShow(int index)
+{
+ view->setColumnWidth(index, 100);
+ view->header()->setResizeEnabled(true, index);
+}
+
+bool KTorrentView::columnVisible(int index)
+{
+ if (index < view->columns() && index >= 0)
+ return view->columnWidth(index) != 0;
+ else
+ return true;
+}
+
+void KTorrentView::onColumnVisibilityChange(int id)
+{
+ int mid = m_headerMenu->indexOf(id) - 1;
+ if(mid == -1)
+ return;
+
+ bool visible = !columnVisible(mid);
+
+ m_headerMenu->setItemChecked(id, visible);
+
+ if(visible)
+ columnShow(mid);
+ else
+ columnHide(mid);
+}
+
+void KTorrentView::gsmItemActived(const TQString & group)
+{
+ groupsSubMenuItemActivated(this,group);
+}
+
+void KTorrentView::updateCaption()
+{
+ Uint32 r = 0;
+ Uint32 t = 0;
+ TQMap<kt::TorrentInterface*,KTorrentViewItem*>::iterator i = items.begin();
+ while (i != items.end())
+ {
+ if (!current_group || current_group->isMember(i.key()))
+ {
+ t++;
+ if (i.key()->getStats().running)
+ r++;
+ }
+
+ i++;
+ }
+
+ if (running != r || total != t)
+ {
+ running = r;
+ total = t;
+
+ if (current_group)
+ setCaption(TQString("%1 %2/%3").arg(current_group->groupName()).arg(running).arg(total));
+ else
+ setCaption(i18n("All Torrents %1/%2").arg(running).arg(total));
+ }
+}
+
+void KTorrentView::setupViewColumns()
+{
+ if (current_group->groupFlags() == kt::Group::UPLOADS_ONLY_GROUP)
+ {
+ // we are an uploads group so lets hide, downloaded, percentage, download speed and time left
+ columnHide(2); // Downloaded
+ columnHide(5); // Down speed
+ columnHide(7); // Time left
+ columnHide(10); // Percentage
+ }
+ else if (current_group->groupFlags() == kt::Group::DOWNLOADS_ONLY_GROUP)
+ {
+ columnHide(13); // Seed time is not necessary for a download
+ }
+
+ // make sure menu is OK
+ for(int i=0; i< view->columns();++i)
+ {
+ bool visible = columnVisible(i);
+ m_headerMenu->setItemChecked(m_headerMenu->idAt(i+1), visible);
+ view->header()->setResizeEnabled(visible, i);
+ }
+}
+
+
+
+void KTorrentView::toggleFilterBar()
+{
+ filter_bar->setHidden(!filter_bar->isHidden());
+}
+
+#include "ktorrentview.moc"
diff --git a/src/apps/ktorrent/ktorrentview.h b/src/apps/ktorrent/ktorrentview.h
new file mode 100644
index 0000000..bf52598
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentview.h
@@ -0,0 +1,217 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+
+
+#ifndef _KTORRENTVIEW_H_
+#define _KTORRENTVIEW_H_
+
+#include <tdelistview.h>
+
+typedef TQValueList<TQCString> QCStringList;
+
+class KURL;
+class KTorrentViewItem;
+class TDEPopupMenu;
+class KTorrentCore;
+class KTorrentViewMenu;
+class KTorrentView;
+class ScanDialog;
+class TQString;
+class FilterBar;
+
+namespace kt
+{
+ class TorrentInterface;
+ class Group;
+}
+
+using namespace bt;
+
+class TorrentView : public TDEListView
+{
+public:
+ TorrentView(KTorrentView* parent);
+ virtual ~TorrentView();
+
+ virtual bool eventFilter(TQObject* watched, TQEvent* e);
+
+private:
+ KTorrentView* ktview;
+};
+
+
+
+
+/**
+ * List view which shows information about torrents.
+ */
+class KTorrentView : public TQWidget
+{
+ TQ_OBJECT
+
+public:
+ enum ActionEnableFlags
+ {
+ START = 1,
+ STOP = 2,
+ START_ALL = 4,
+ STOP_ALL = 8,
+ REMOVE = 16,
+ SCAN = 32
+ };
+
+ /**
+ * Default constructor
+ */
+ KTorrentView(TQWidget *parent);
+
+ /**
+ * Destructor
+ */
+ virtual ~KTorrentView();
+
+ /// Update the caption, so the correct number of running torrents is shown in the tab
+ void updateCaption();
+
+ /// Trigger an updateActions signal
+ void updateActions() {onSelectionChanged();}
+
+ /// Get the current group
+ const kt::Group* getCurrentGroup() const {return current_group;}
+
+ /// Get the current TorrentInterface object
+ kt::TorrentInterface* getCurrentTC();
+
+ /// Save the views settings
+ void saveSettings(TDEConfig* cfg,int idx);
+
+ /// Load the views settings
+ void loadSettings(TDEConfig* cfg,int idx);
+
+ /**
+ * Put the current selection in a list.
+ * @param sel The list to put it in
+ */
+ void getSelection(TQValueList<kt::TorrentInterface*> & sel);
+
+ /**
+ * Add the current selection to a group.
+ * @param g The group
+ */
+ void addSelectionToGroup(kt::Group* g);
+
+ /**
+ * Is column visible?
+ */
+ bool columnVisible(int index);
+
+ /**
+ * Setup the view columns, based upon the current group
+ * This will hide some columns for uploads only groups.
+ */
+ void setupViewColumns();
+
+ TQPtrList<TQListViewItem> selectedItems() {return view->selectedItems();}
+
+ TDEListView* listView() {return view;}
+
+ /**
+ * Toggle the visibility of the filter bar
+ */
+ void toggleFilterBar();
+
+public slots:
+ void setCurrentGroup(kt::Group* group);
+ void addTorrent(kt::TorrentInterface* tc);
+ void removeTorrent(kt::TorrentInterface* tc);
+ void update();
+ void startDownloads();
+ void stopDownloads();
+ void startAllDownloads();
+ void stopAllDownloads();
+ void manualAnnounce();
+ void previewFiles();
+ void removeDownloads();
+ void removeDownloadsAndData();
+ void onSelectionChanged();
+ void queueSlot();
+ void checkDataIntegrity();
+ void removeFromGroup();
+ void showAddPeersWidget();
+ void openOutputDirectory();
+ void openTorXDirectory();
+ void setDownloadLocationSlot();
+ void dhtSlot();
+ void utPexSlot();
+ void speedLimits();
+
+private slots:
+ void onExecuted(TQListViewItem* item);
+ void showContextMenu(TDEListView* ,TQListViewItem* item,const TQPoint & p);
+ void onColumnVisibilityChange(int);
+ void gsmItemActived(const TQString & group);
+
+
+signals:
+ void torrentClicked(kt::TorrentInterface* tc);
+ void currentChanged(kt::TorrentInterface* tc);
+ void wantToRemove(kt::TorrentInterface* tc,bool data_to);
+ void wantToStop(kt::TorrentInterface* tc,bool user);
+ void wantToStart(kt::TorrentInterface* tc);
+ void viewChange(kt::TorrentInterface* tc);
+
+ /**
+ * Emit that actions need to be updated
+ * @param flags OR of ActionEnableFlags
+ */
+ void updateActions(int flags);
+ void queue(kt::TorrentInterface* tc);
+ void needsDataCheck(kt::TorrentInterface* tc);
+ void updateGroupsSubMenu(TDEPopupMenu* gsm);
+ void groupsSubMenuItemActivated(KTorrentView* v,const TQString & group);
+
+private:
+ bool acceptDrag(TQDropEvent* event) const;
+ int getNumRunning();
+ bool startDownload(kt::TorrentInterface* tc);
+ void stopDownload(kt::TorrentInterface* tc);
+ void showStartError();
+ virtual TQDragObject* dragObject();
+ void setupColumns();
+ void insertColumn(TQString label, TQt::AlignmentFlags);
+ void columnHide(int index);
+ void columnShow(int index);
+
+
+private:
+ TQMap<kt::TorrentInterface*,KTorrentViewItem*> items;
+ KTorrentViewMenu* menu;
+ TDEPopupMenu* m_headerMenu;
+ kt::Group* current_group;
+ Uint32 running;
+ Uint32 total;
+ TorrentView* view;
+ FilterBar* filter_bar;
+
+ friend class TorrentView;
+};
+
+#endif // _KTORRENTVIEW_H_
diff --git a/src/apps/ktorrent/ktorrentviewitem.cpp b/src/apps/ktorrent/ktorrentviewitem.cpp
new file mode 100644
index 0000000..4a60329
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentviewitem.cpp
@@ -0,0 +1,354 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <tdeglobal.h>
+#include <interfaces/torrentinterface.h>
+#include <tqdatetime.h>
+#include <tqpainter.h>
+#include <math.h>
+#include <interfaces/functions.h>
+#include "ktorrentview.h"
+#include "ktorrentviewitem.h"
+
+using namespace bt;
+using namespace kt;
+/*
+static TQString StatusToString(TorrentInterface* tc,TorrentStatus s)
+{
+ switch (s)
+ {
+ case kt::NOT_STARTED :
+ return i18n("Not started");
+ case kt::COMPLETE :
+ return i18n("Completed");
+ case kt::SEEDING :
+ return i18n("Seeding");
+ case kt::DOWNLOADING:
+ return i18n("Downloading");
+ case kt::STALLED:
+ return i18n("Stalled");
+ case kt::STOPPED:
+ return i18n("Stopped");
+ case kt::ERROR :
+ return i18n("Error: ") + tc->getShortErrorMessage();
+ case kt::ALLOCATING_DISKSPACE:
+ return i18n("Allocating diskspace");
+ }
+ return TQString();
+}
+*/
+
+static TQColor StatusToColor(TorrentStatus s,const TQColorGroup & cg)
+{
+ TQColor green(40,205,40);
+ TQColor yellow(255,174,0);
+ switch (s)
+ {
+ case kt::SEEDING :
+ case kt::DOWNLOADING:
+ case kt::ALLOCATING_DISKSPACE :
+ return green;
+ case kt::STALLED:
+ case kt::CHECKING_DATA:
+ return yellow;
+ case kt::ERROR :
+ return TQt::red;
+ case kt::NOT_STARTED :
+ case kt::STOPPED:
+ case kt::QUEUED:
+ case kt::DOWNLOAD_COMPLETE :
+ case kt::SEEDING_COMPLETE :
+ default:
+ return cg.text();
+ }
+ return cg.text();
+}
+
+static TQColor ratioToColor(float ratio)
+{
+ TQColor green(40,205,40);
+ return ratio > 0.8 ? green : TQt::red;
+}
+
+static double Percentage(const TorrentStats & s)
+{
+ if (s.bytes_left_to_download == 0)
+ {
+ return 100.0;
+ }
+ else
+ {
+ if (s.total_bytes_to_download == 0)
+ {
+ return 100.0;
+ }
+ else
+ {
+ double perc = 100.0 - ((double)s.bytes_left_to_download / s.total_bytes_to_download) * 100.0;
+ if (perc > 100.0)
+ perc = 100.0;
+ else if (perc > 99.9)
+ perc = 99.9;
+ else if (perc < 0.0)
+ perc = 0.0;
+
+ return perc;
+ }
+ }
+}
+
+
+
+KTorrentViewItem::KTorrentViewItem(KTorrentView* parent,TorrentInterface* tc)
+ : TDEListViewItem(parent->listView()),tc(tc)
+{
+ m_parent = parent;
+ update();
+}
+
+
+KTorrentViewItem::~KTorrentViewItem()
+{}
+
+QCStringList KTorrentViewItem::getTorrentInfo(kt::TorrentInterface* tc)
+{
+ QCStringList info;
+ const TorrentStats & s = tc->getStats();
+ info.append(s.torrent_name.local8Bit());
+ info.append(tc->statusToString().local8Bit());
+ info.append(BytesToString(s.bytes_downloaded).local8Bit());
+ info.append(BytesToString(s.total_bytes_to_download).local8Bit());
+ info.append(BytesToString(s.bytes_uploaded).local8Bit());
+ if (s.bytes_left_to_download == 0)
+ info.append(KBytesPerSecToString(0).local8Bit());
+ else
+ info.append(KBytesPerSecToString(s.download_rate / 1024.0).local8Bit());
+
+ info.append(KBytesPerSecToString(s.upload_rate / 1024.0).local8Bit());
+ if (s.bytes_left_to_download == 0)
+ {
+ info.append(TQCString(""));
+ }
+ else if (s.running)
+ {
+ Uint32 secs = tc->getETA();
+ if(secs == -1)
+ info.append(i18n("infinity").local8Bit());
+ else
+ info.append(DurationToString(secs).local8Bit());
+ }
+ else
+ {
+ info.append(i18n("infinity").local8Bit());
+ }
+
+ info.append(TQString::number(s.num_peers).local8Bit());
+ info.append(TQString(TDEGlobal::locale()->formatNumber(Percentage(s),2) + " %").local8Bit());
+ info.append(TDEGlobal::locale()->formatNumber(kt::ShareRatio(s),2).local8Bit());
+ info.append(TQString::number(s.seeders_connected_to).local8Bit());
+ info.append(TQString::number(s.leechers_connected_to).local8Bit());
+ return info;
+}
+
+void KTorrentViewItem::update()
+{
+ const TorrentStats & s = tc->getStats();
+
+ if(m_parent->columnVisible(0))
+ setText(0,s.torrent_name);
+
+ if(m_parent->columnVisible(1))
+ setText(1,tc->statusToString());
+
+ if(m_parent->columnVisible(2))
+ {
+ Uint64 nb = /*s.bytes_downloaded > s.total_bytes ? s.total_bytes : */s.bytes_downloaded;
+ setText(2,BytesToString(nb));
+ }
+
+ if(m_parent->columnVisible(3))
+ setText(3,BytesToString(s.total_bytes_to_download));
+
+ if(m_parent->columnVisible(4))
+ setText(4,BytesToString(s.bytes_uploaded));
+
+ if(m_parent->columnVisible(5))
+ {
+ if (s.download_rate >= 103) // lowest "visible" speed, all below will be 0,0 Kb/s
+ {
+ if (s.bytes_left_to_download == 0)
+ setText(5,KBytesPerSecToString(0));
+ else
+ setText(5,KBytesPerSecToString(s.download_rate / 1024.0));
+ }
+ else
+ setText(5, "");
+ }
+
+ if(m_parent->columnVisible(6))
+ {
+ if (s.upload_rate >= 103) // lowest "visible" speed, all below will be 0,0 Kb/s
+ setText(6,KBytesPerSecToString(s.upload_rate / 1024.0));
+ else
+ setText(6, "");
+ }
+
+ if(m_parent->columnVisible(7))
+ {
+ if (s.bytes_left_to_download == 0)
+ {
+ setText(7,TQString());
+ eta = -1;
+ }
+ else if (s.running)
+ {
+ Uint32 secs = tc->getETA();
+ if(secs == -1)
+ {
+ setText(7,TQString("%1").arg(TQChar(0x221E)));
+ eta = -2;
+ }
+ else
+ {
+ eta = secs;
+ setText(7,DurationToString(secs));
+ }
+ }
+ else
+ {
+ setText(7,TQString("%1").arg(TQChar(0x221E)));
+ eta = -2;
+ }
+ }
+ if(m_parent->columnVisible(8))
+ setText(8,TQString::number(s.num_peers));
+
+ if(m_parent->columnVisible(8))
+ {
+ setText(8,TQString("%1 (%2)").arg(TQString::number(s.seeders_connected_to)).arg(TQString::number(s.seeders_total)));
+ }
+
+ if(m_parent->columnVisible(9))
+ {
+ setText(9,TQString("%1 (%2)").arg(TQString::number(s.leechers_connected_to)).arg(TQString::number(s.leechers_total)));
+ }
+
+ if(m_parent->columnVisible(10))
+ {
+ setText(10,i18n("%1 %").arg(TDEGlobal::locale()->formatNumber(Percentage(s),2)));
+ }
+
+ if(m_parent->columnVisible(11))
+ {
+ float ratio = kt::ShareRatio(s);
+ setText(11,TQString("%1").arg(TDEGlobal::locale()->formatNumber(ratio,2)));
+ }
+
+ if (m_parent->columnVisible(12))
+ {
+ Uint32 secs = tc->getRunningTimeDL();
+ setText(12,secs > 0 ? DurationToString(secs) : "");
+ }
+
+ if (m_parent->columnVisible(13))
+ {
+ Uint32 secs = tc->getRunningTimeUL() - tc->getRunningTimeDL();
+ setText(13,secs > 0 ? DurationToString(secs) : "");
+ }
+}
+
+
+
+int KTorrentViewItem::compare(TQListViewItem * i,int col,bool) const
+{
+ KTorrentViewItem* other = (KTorrentViewItem*)i;
+ TorrentInterface* otc = other->tc;
+ const TorrentStats & s = tc->getStats();
+ const TorrentStats & os = otc->getStats();
+ switch (col)
+ {
+ case 0: return TQString::compare(s.torrent_name,os.torrent_name);
+ case 1: return TQString::compare(tc->statusToString(),otc->statusToString());
+ case 2: return CompareVal(s.bytes_downloaded,os.bytes_downloaded);
+ case 3: return CompareVal(s.total_bytes_to_download,os.total_bytes_to_download);
+ case 4: return CompareVal(s.bytes_uploaded,os.bytes_uploaded);
+ case 5: return CompareVal(s.download_rate,os.download_rate);
+ case 6: return CompareVal(s.upload_rate,os.upload_rate);
+ case 7:
+ if (eta == other->eta)
+ return 0;
+ else if (eta >= 0 && other->eta >= 0)
+ return CompareVal(eta,other->eta);
+ else if (eta == -1) // finsihed is minux one
+ return -1;
+ else if (other->eta == -1)
+ return 1;
+ else if (eta == -2) // infinity is minus 2
+ return 1;
+ else if (other->eta == -2)
+ return -1;
+ else
+ return CompareVal(eta,other->eta);
+ case 8: return CompareVal(s.seeders_total,os.seeders_total);
+ case 9: return CompareVal(s.leechers_total,os.leechers_total);
+ case 10:
+ {
+ double perc = s.total_bytes_to_download == 0 ? 100.0 : ((double)s.bytes_downloaded / s.total_bytes_to_download) * 100.0;
+ if (perc > 100.0)
+ perc = 100.0;
+ double operc = os.total_bytes_to_download == 0 ? 100.0 : ((double)os.bytes_downloaded / os.total_bytes_to_download) * 100.0;
+ if (operc > 100.0)
+ operc = 100.0;
+ return CompareVal(perc,operc);
+ }
+ case 11:
+ {
+ float r1 = kt::ShareRatio(s);
+ float r2 = kt::ShareRatio(os);
+ return CompareVal(r1,r2);
+ }
+ case 12:
+ return CompareVal(tc->getRunningTimeDL(),otc->getRunningTimeDL());
+ case 13:
+ {
+ Uint32 t = tc->getRunningTimeUL() - tc->getRunningTimeDL();
+ Uint32 ot = otc->getRunningTimeUL() - otc->getRunningTimeDL();
+ return CompareVal(t,ot);
+ }
+ }
+
+ return 0;
+}
+
+void KTorrentViewItem::paintCell(TQPainter* p,const TQColorGroup & cg,
+ int column,int width,int align)
+{
+ TQColorGroup _cg( cg );
+ TQColor c = _cg.text();
+
+ if (column == 1)
+ _cg.setColor(TQColorGroup::Text, StatusToColor(tc->getStats().status,cg));
+
+ if (column == 11)
+ _cg.setColor(TQColorGroup::Text, ratioToColor(kt::ShareRatio(tc->getStats())));
+
+
+ TDEListViewItem::paintCell(p,_cg,column,width,align);
+}
diff --git a/src/apps/ktorrent/ktorrentviewitem.h b/src/apps/ktorrent/ktorrentviewitem.h
new file mode 100644
index 0000000..575844d
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentviewitem.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTORRENTVIEWITEM_H
+#define KTORRENTVIEWITEM_H
+
+#include <tdelistview.h>
+#include <dcopclient.h>
+#include <util/constants.h>
+
+namespace kt
+{
+ class TorrentInterface;
+}
+
+class KTorrentView;
+
+/**
+ * @author Joris Guisson
+*/
+class KTorrentViewItem : public TDEListViewItem
+{
+ kt::TorrentInterface* tc;
+ bt::Int64 eta;
+public:
+ KTorrentViewItem(KTorrentView* parent,kt::TorrentInterface* tc);
+ virtual ~KTorrentViewItem();
+
+ kt::TorrentInterface* getTC() {return tc;}
+ void update();
+
+ static QCStringList getTorrentInfo(kt::TorrentInterface* tc);
+
+private:
+ int compare(TQListViewItem * i,int col,bool ascending) const;
+ void paintCell(TQPainter* p,const TQColorGroup & cg,int column,int width,int align);
+
+ KTorrentView* m_parent;
+
+};
+
+#endif
diff --git a/src/apps/ktorrent/ktorrentviewmenu.cpp b/src/apps/ktorrent/ktorrentviewmenu.cpp
new file mode 100644
index 0000000..5dca77e
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentviewmenu.cpp
@@ -0,0 +1,217 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdeglobal.h>
+#include <tdelocale.h>
+#include <kiconloader.h>
+#include <interfaces/torrentinterface.h>
+#include <groups/group.h>
+#include "ktorrentviewmenu.h"
+#include "ktorrentviewitem.h"
+#include "ktorrentview.h"
+
+using namespace kt;
+
+KTorrentViewMenu::KTorrentViewMenu (KTorrentView *parent, const char *name )
+ : TDEPopupMenu ( parent, name ),view(parent)
+{
+ TDEIconLoader* iload = TDEGlobal::iconLoader();
+
+ stop_id = insertItem(
+ iload->loadIconSet("ktstop",TDEIcon::Small),i18n("to stop", "Stop"),
+ parent,TQ_SLOT(stopDownloads()));
+
+ start_id = insertItem(
+ iload->loadIconSet("ktstart",TDEIcon::Small),i18n("to start", "Start"),
+ parent,TQ_SLOT(startDownloads()));
+
+ remove_id = insertItem(
+ iload->loadIconSet("ktremove",TDEIcon::Small),i18n("Remove Torrent"),
+ parent,TQ_SLOT(removeDownloads()));
+
+ remove_all_id = insertItem(
+ iload->loadIconSet("ktremove",TDEIcon::Small),i18n("Remove Torrent and Data"),
+ parent,TQ_SLOT(removeDownloadsAndData()));
+
+ queue_id = insertItem(
+ iload->loadIconSet("player_playlist",TDEIcon::Small),i18n("Enqueue/Dequeue"),
+ parent,TQ_SLOT(queueSlot()));
+
+ insertSeparator();
+
+ add_peer_id = insertItem(
+ iload->loadIconSet("add", TDEIcon::Small), i18n("Add Peers"),
+ parent, TQ_SLOT(showAddPeersWidget()));
+
+ peer_sources_menu = new TDEPopupMenu(this);
+ peer_sources_id = insertItem(i18n("Additional Peer Sources"), peer_sources_menu);
+ peer_sources_menu->insertTitle(i18n("Torrent Peer Sources:"));
+ peer_sources_menu->setCheckable(true);
+ dht_id = peer_sources_menu->insertItem(i18n("DHT"), parent, TQ_SLOT(dhtSlot()));
+ ut_pex_id = peer_sources_menu->insertItem(i18n("Peer Exchange"), parent, TQ_SLOT(utPexSlot()));
+
+ insertSeparator();
+
+ announce_id = insertItem(
+ iload->loadIconSet("apply",TDEIcon::Small),i18n("Manual Announce"),
+ parent,TQ_SLOT(manualAnnounce()));
+
+ preview_id = insertItem(
+ iload->loadIconSet("frame_image",TDEIcon::Small),i18n("Preview"),
+ parent, TQ_SLOT(previewFiles()));
+
+ insertSeparator();
+ dirs_sub_menu = new TDEPopupMenu(this);
+ dirs_id = insertItem(i18n("Open Directory"), dirs_sub_menu);
+ outputdir_id = dirs_sub_menu->insertItem(iload->loadIconSet("folder",TDEIcon::Small), i18n("Data Directory"),
+ parent, TQ_SLOT(openOutputDirectory()));
+ torxdir_id = dirs_sub_menu->insertItem(iload->loadIconSet("folder",TDEIcon::Small), i18n("Temporary Directory"),
+ parent, TQ_SLOT(openTorXDirectory()));
+
+ downloaddir_id = insertItem(i18n("Set Download Location"), parent, TQ_SLOT(setDownloadLocationSlot()));
+
+ insertSeparator();
+ remove_from_group_id = insertItem(i18n("Remove From Group"),parent, TQ_SLOT(removeFromGroup()));
+ groups_sub_menu = new TDEPopupMenu(this);
+
+ add_to_group_id = insertItem(i18n("Add to Group"),groups_sub_menu);
+
+ insertSeparator();
+ scan_id = insertItem(i18n("Check Data Integrity"),parent, TQ_SLOT(checkDataIntegrity()));
+
+ connect(groups_sub_menu,TQ_SIGNAL(activated(int)),this,TQ_SLOT(gsmItemActived(int)));
+
+ traffic_lim_id = insertItem(i18n("Speed Limits"),parent,TQ_SLOT(speedLimits()));
+}
+
+
+KTorrentViewMenu::~KTorrentViewMenu()
+{}
+
+void KTorrentViewMenu::gsmItemActived(int id)
+{
+ groupItemActivated(groups_sub_menu->text(id).remove('&'));
+}
+
+void KTorrentViewMenu::show(const TQPoint & p)
+{
+ bool en_start = false;
+ bool en_stop = false;
+ bool en_remove = false;
+ bool en_prev = false;
+ bool en_announce = false;
+ bool en_add_peer = false;
+ bool en_dirs = false;
+ bool en_peer_sources = false;
+ bool dummy = false;
+
+ TQPtrList<TQListViewItem> sel = view->selectedItems();
+ for (TQPtrList<TQListViewItem>::iterator itr = sel.begin(); itr != sel.end();itr++)
+ {
+ KTorrentViewItem* kvi = (KTorrentViewItem*)*itr;
+ TorrentInterface* tc = kvi->getTC();
+ if (tc)
+ {
+ const TorrentStats & s = tc->getStats();
+
+ if (tc->readyForPreview() && !s.multi_file_torrent)
+ en_prev = true;
+
+ if (!tc->isCheckingData(dummy))
+ en_remove = true;
+
+ if (!s.running)
+ {
+ if (!tc->isCheckingData(dummy))
+ {
+ en_start = true;
+ }
+ }
+ else
+ {
+ if (!tc->isCheckingData(dummy))
+ {
+ en_stop = true;
+ if (tc->announceAllowed())
+ en_announce = true;
+ }
+ }
+
+ if (!s.priv_torrent && !tc->isCheckingData(dummy))
+ {
+ en_add_peer = true;
+ en_peer_sources = true;
+ }
+ }
+ }
+
+ en_add_peer = en_add_peer && en_stop;
+
+ setItemEnabled(start_id,en_start);
+ setItemEnabled(stop_id,en_stop);
+ setItemEnabled(remove_id,en_remove);
+ setItemEnabled(remove_all_id,en_remove);
+ setItemEnabled(preview_id,en_prev);
+ setItemEnabled(add_peer_id, en_add_peer);
+ setItemEnabled(announce_id,en_announce);
+ setItemEnabled(queue_id, en_remove);
+
+ const kt::Group* current_group = view->getCurrentGroup();
+ setItemEnabled(remove_from_group_id,current_group && !current_group->isStandardGroup());
+ setItemEnabled(add_to_group_id,groups_sub_menu->count() > 0);
+
+ if (sel.count() == 1)
+ {
+ //enable directories
+ en_dirs = true;
+
+ KTorrentViewItem* kvi = (KTorrentViewItem*)sel.getFirst();
+ TorrentInterface* tc = kvi->getTC();
+ // no data check when we are preallocating diskspace
+ if (tc->getStats().status == kt::ALLOCATING_DISKSPACE || tc->isCheckingData(dummy))
+ setItemEnabled(scan_id, false);
+ else
+ setItemEnabled(scan_id, true);
+
+ //enable additional peer sources if torrent is not private
+ setItemEnabled(peer_sources_id, en_peer_sources);
+
+ if (en_peer_sources)
+ {
+ peer_sources_menu->setItemChecked(dht_id, tc->isFeatureEnabled(kt::DHT_FEATURE));
+ peer_sources_menu->setItemChecked(ut_pex_id, tc->isFeatureEnabled(kt::UT_PEX_FEATURE));
+ }
+ }
+ else
+ {
+ setItemEnabled(scan_id,false);
+
+ //disable peer source
+ setItemEnabled(peer_sources_id, false);
+ }
+
+ setItemEnabled(dirs_id, en_dirs);
+ setItemEnabled(traffic_lim_id,sel.count() == 1);
+ setItemEnabled(add_to_group_id,sel.count() > 0);
+ setItemEnabled(downloaddir_id,sel.count() > 0);
+
+ popup(p);
+}
+
+#include "ktorrentviewmenu.moc"
diff --git a/src/apps/ktorrent/ktorrentviewmenu.h b/src/apps/ktorrent/ktorrentviewmenu.h
new file mode 100644
index 0000000..75c5112
--- /dev/null
+++ b/src/apps/ktorrent/ktorrentviewmenu.h
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef KTORRENTVIEWMENU_H
+#define KTORRENTVIEWMENU_H
+
+#include <tdepopupmenu.h>
+
+class KTorrentView;
+
+/**
+ @author Joris Guisson <joris.guisson@gmail.com>
+*/
+class KTorrentViewMenu : public TDEPopupMenu
+{
+ TQ_OBJECT
+
+public:
+ KTorrentViewMenu(KTorrentView *parent, const char *name = 0 );
+ virtual ~KTorrentViewMenu();
+
+ /// Show the menu at the given point
+ void show(const TQPoint & p);
+
+ /// Get the group sub menu
+ TDEPopupMenu* getGroupsSubMenu() {return groups_sub_menu;}
+
+public slots:
+ void gsmItemActived(int id);
+
+signals:
+ /// A item in the groups sub menu has been activated
+ void groupItemActivated(const TQString & group);
+
+private:
+ KTorrentView* view;
+ TDEPopupMenu* groups_sub_menu;
+ TDEPopupMenu* dirs_sub_menu;
+ TDEPopupMenu* peer_sources_menu;
+ int stop_id;
+ int start_id;
+ int remove_id;
+ int remove_all_id;
+ int preview_id;
+ int announce_id;
+ int queue_id;
+ int scan_id;
+ int remove_from_group_id;
+ int add_to_group_id;
+ int add_peer_id;
+ int dirs_id;
+ int outputdir_id;
+ int torxdir_id;
+ int downloaddir_id;
+ int peer_sources_id;
+ int dht_id;
+ int ut_pex_id;
+ int traffic_lim_id;
+};
+
+#endif
diff --git a/src/apps/ktorrent/leaktrace.cpp b/src/apps/ktorrent/leaktrace.cpp
new file mode 100644
index 0000000..76439ce
--- /dev/null
+++ b/src/apps/ktorrent/leaktrace.cpp
@@ -0,0 +1,295 @@
+#ifdef KT_LEAKTRACE
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <util/constants.h>
+
+/*
+ * prime number for the address lookup hash table.
+ * if you have _really_ many memory allocations, use a
+ * higher value, like 343051 for instance.
+ */
+#define SOME_PRIME 35323
+#define ADDR_HASH(addr) ((unsigned long) addr % SOME_PRIME)
+
+using namespace bt;
+
+struct MemAlloc
+{
+ void* ptr;
+ size_t size;
+ void* alloc_addr; // addr of function which did the allocation
+ MemAlloc* left;
+ MemAlloc* right;
+};
+
+struct MemAllocTree
+{
+ Uint32 num_buckets;
+ Uint32 count;
+ Uint64 bytes;
+ pthread_mutex_t mutex;
+ MemAlloc* buckets[SOME_PRIME];
+};
+
+static MemAllocTree mtree = {0,0,0,PTHREAD_MUTEX_INITIALIZER};
+static bool print_status_done = false;
+
+static void InsertIntoTree(MemAlloc* cnode,MemAlloc* target)
+{
+ if (target->ptr < cnode->ptr)
+ {
+ if (!cnode->left)
+ cnode->left = target;
+ else
+ InsertIntoTree(cnode->left,target);
+ }
+ else
+ {
+ if (!cnode->right)
+ cnode->right = target;
+ else
+ InsertIntoTree(cnode->right,target);
+ }
+}
+
+static void PrintTree(MemAlloc* ma)
+{
+ if (!ma)
+ return;
+
+ printf("\t0x%p 0x%p %i bytes\n",ma->alloc_addr,ma->ptr,ma->size);
+ PrintTree(ma->left);
+ PrintTree(ma->right);
+}
+
+static void PrintTreeToFile(FILE* fptr,MemAlloc* ma)
+{
+ if (!ma)
+ return;
+
+ fprintf(fptr, "L %10p %9ld # %p\n",ma->alloc_addr,ma->size,ma->ptr);
+ PrintTreeToFile(fptr,ma->left);
+ PrintTreeToFile(fptr,ma->right);
+}
+
+static void WriteLeakReport()
+{
+ FILE* report = fopen("leak.out","wt");
+ if (!report)
+ {
+ printf("Cannot write report !!!!!!!!\n");
+ return;
+ }
+
+
+ for (Uint32 b = 0;b < SOME_PRIME;b++)
+ PrintTreeToFile(report,mtree.buckets[b]);
+ fclose(report);
+}
+
+static void PrintStatus()
+{
+ if (mtree.count == 0)
+ {
+ printf("No memory leaks detected !!!\n");
+ }
+ else
+ {
+ printf("LeakTrace results : \n");
+ for (Uint32 b = 0;b < SOME_PRIME;b++)
+ PrintTree(mtree.buckets[b]);
+ printf("====================\n");
+ printf("Total : %i leaks, %li bytes leaked\n",mtree.count,mtree.bytes);
+ }
+ WriteLeakReport();
+ print_status_done = true;
+}
+
+
+
+static void RegisterAlloc(void* ptr,Uint32 size)
+{
+ MemAlloc* ma = (MemAlloc*)malloc(sizeof(MemAlloc));
+ ma->left = ma->right = 0;
+ ma->size = size;
+ ma->alloc_addr = __builtin_return_address(1);
+ ma->ptr = ptr;
+ if (mtree.num_buckets == 0)
+ {
+ // init buckets
+ for (Uint32 b = 0;b < SOME_PRIME;b++)
+ mtree.buckets[b] = 0;
+ mtree.num_buckets = SOME_PRIME;
+ atexit(PrintStatus);
+ }
+
+ // hash the address
+ Uint32 b = ADDR_HASH(ptr);
+ if (!mtree.buckets[b])
+ {
+ mtree.count++;
+ mtree.bytes += size;
+ mtree.buckets[b] = ma;
+ }
+ else
+ {
+ // walk the tree and insert it
+ InsertIntoTree(mtree.buckets[b],ma);
+ mtree.count++;
+ mtree.bytes += size;
+ }
+}
+
+static void DeregisterAlloc(void* ptr)
+{
+ if (print_status_done)
+ printf("PrintStatus already happened !!!!!!!!!!\n");
+ Uint32 b = ADDR_HASH(ptr);
+
+ MemAlloc* p = mtree.buckets[b];
+ MemAlloc* prev = 0;
+ while (p && p->ptr != ptr)
+ {
+ prev = p;
+ if (ptr < p->ptr)
+ p = p->left;
+ else if (ptr > p->ptr)
+ p = p->right;
+ }
+
+ if (!p)
+ return;
+
+ if (!prev)
+ {
+ // it's the root
+ mtree.count--;
+ mtree.bytes -= p->size;
+ free(p);
+ mtree.buckets[b] = 0;
+ }
+ else
+ {
+ // first update some additional info
+ mtree.count--;
+ mtree.bytes -= p->size;
+
+ if (!p->left && !p->right)
+ {
+ // no children so just free p
+ if (prev->left == p)
+ {
+ free(prev->left);
+ prev->left = 0;
+ }
+ else
+ {
+ free(prev->right);
+ prev->right = 0;
+ }
+ }
+ else if (p->left && !p->right)
+ {
+ // one child of p is zero, so just attach
+ // the child of p to prev
+ if (prev->left == p)
+ prev->left = p->left;
+ else
+ prev->right = p->left;
+ free(p);
+ }
+ else if (!p->left && p->right)
+ {
+ // one child of p is zero, so just attach
+ // the child of p to prev
+ if (prev->left == p)
+ prev->left = p->right;
+ else
+ prev->right = p->right;
+ free(p);
+ }
+ else
+ {
+ // both children exist
+ if (prev->left == p)
+ {
+ // attach the left child of p
+ prev->left = p->left;
+ InsertIntoTree(prev,p->right);
+ }
+ else
+ {
+ // attach the right child of p
+ prev->right = p->right;
+ InsertIntoTree(prev,p->left);
+ }
+
+ free(p);
+ }
+ }
+
+}
+
+
+void* operator new(size_t size)
+{
+ void* ptr = malloc(size);
+ if (!ptr)
+ {
+ printf("PANIC : memory allocation failed !\n");
+ exit(-1);
+ }
+
+
+ pthread_mutex_lock(&mtree.mutex);
+ RegisterAlloc(ptr,size);
+ pthread_mutex_unlock(&mtree.mutex);
+ return ptr;
+}
+
+
+void* operator new[] (size_t size)
+{
+ void* ptr = malloc(size);
+ if (!ptr)
+ {
+ printf("PANIC : memory allocation failed !\n");
+ exit(-1);
+ }
+
+ pthread_mutex_lock(&mtree.mutex);
+ RegisterAlloc(ptr,size);
+ pthread_mutex_unlock(&mtree.mutex);
+ return ptr;
+}
+
+
+void operator delete (void *ptr)
+{
+ if (!ptr)
+ return;
+
+
+ pthread_mutex_lock(&mtree.mutex);
+ DeregisterAlloc(ptr);
+ pthread_mutex_unlock(&mtree.mutex);
+ free(ptr);
+}
+
+
+void operator delete[] (void *ptr)
+{
+ if (!ptr)
+ return;
+
+ pthread_mutex_lock(&mtree.mutex);
+ DeregisterAlloc(ptr);
+ pthread_mutex_unlock(&mtree.mutex);
+ free(ptr);
+}
+
+#endif // KT_LEAKTRACE
diff --git a/src/apps/ktorrent/main.cpp b/src/apps/ktorrent/main.cpp
new file mode 100644
index 0000000..a6b67c8
--- /dev/null
+++ b/src/apps/ktorrent/main.cpp
@@ -0,0 +1,200 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <signal.h>
+#include <tdelocale.h>
+#include <tdeaboutdata.h>
+#include <tdeapplication.h>
+#include <tdecmdlineargs.h>
+
+#include <stdlib.h>
+
+#include "ktorrentapp.h"
+
+#include <tqapplication.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <util/error.h>
+#include <util/log.h>
+#include <torrent/globals.h>
+#include <util/fileops.h>
+#include <ktversion.h>
+#include <functions.h>
+#include <tqfile.h>
+#include <tqdir.h>
+
+using namespace bt;
+
+
+
+void StupidWarningMessagesFromTQt( TQtMsgType type, const char *msg )
+{
+ switch ( type )
+ {
+ case TQtDebugMsg:
+ // printf("TQt: Debug: %s\n",msg);
+ break;
+ case TQtWarningMsg:
+ printf("TQt: Warning: %s\n",msg);
+ break;
+ case TQtFatalMsg:
+ printf("TQt: Fatal : %s\n",msg);
+ abort(); // deliberately core dump
+ break;
+ }
+}
+
+
+
+static const char description[] =
+ I18N_NOOP("A BitTorrent program for TDE");
+
+
+bool GrabPIDLock()
+{
+ // create a lock file in /tmp/ with the user id of the current user included in the name
+ TQString pid_file = TQString("/tmp/.ktorrent_%1.lock").arg(getuid());
+
+ int fd = open(TQFile::encodeName(pid_file),O_RDWR|O_CREAT,0640);
+ if (fd < 0)
+ {
+ fprintf(stderr,"Failed to open KT lock file %s : %s\n",pid_file.ascii(),strerror(errno));
+ return false;
+ }
+
+ if (lockf(fd,F_TLOCK,0)<0)
+ {
+ fprintf(stderr,"Failed to get lock on %s : %s\n",pid_file.ascii(),strerror(errno));
+ return false;
+ }
+
+ char str[20];
+ sprintf(str,"%d\n",getpid());
+ write(fd,str,strlen(str)); /* record pid to lockfile */
+
+ // leave file open, so nobody else can lock it until KT exists
+ return true;
+}
+
+
+static TDECmdLineOptions options[] =
+{
+ { "debug", I18N_NOOP("Debug mode"), 0 },
+ { "silent", I18N_NOOP("Silently save torrent given on URL"), 0 },
+ { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ TDECmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+ // ignore SIGPIPE's
+ signal(SIGPIPE,SIG_IGN);
+ signal(SIGXFSZ,SIG_IGN);
+ qInstallMsgHandler( StupidWarningMessagesFromTQt );
+ TDEAboutData about("ktorrent", I18N_NOOP("KTorrent"), kt::VERSION_STRING, description,
+ TDEAboutData::License_GPL, "(C) 2005 -2008 Joris Guisson and Ivan Vasic", 0);
+ about.addAuthor("Joris Guisson", 0, "joris.guisson@gmail.com" );
+ about.addAuthor("Ivan Vasic",0,"ivasic@gmail.com");
+ about.addAuthor("Alan Jones",I18N_NOOP("RSS Plugin"),"skyphyr@gmail.com");
+ about.addAuthor("Diego R. Brogna",I18N_NOOP("Webinterface Plugin"),"dierbro@gmail.com");
+ about.addAuthor("Krzysztof Kundzicz",I18N_NOOP("Statistics Plugin"),"athantor@gmail.com");
+
+ about.addCredit("Mladen Babic",
+ I18N_NOOP("Application icon and a couple of others"),"bmladen@EUnet.yu");
+ about.addCredit("The-Error",I18N_NOOP("The downloads icon"),"zotrix@eunet.yu");
+ about.addCredit("Adam Treat", 0, "treat@kde.org" );
+ about.addCredit("Danny Allen",
+ I18N_NOOP("1.0 application icon"),
+ "danny@dannyallen.co.uk");
+ about.addCredit("Vincent Wagelaar",0,"vincent@ricardis.tudelft.nl");
+ about.addCredit("Knut Morten Johansson",0,"knut@johansson.com");
+ about.addCredit("Felix Berger",
+ I18N_NOOP("ChunkBar's tooltip and IWFileTreeItem sorting"),
+ "bflat1@gmx.net");
+ about.addCredit("Andreas Kling",0,"kling@impul.se");
+ about.addCredit("Felipe Sateler",0,"fsateler@gmail.com");
+ about.addCredit("Maxmind", I18N_NOOP("Country locator for InfoWidget plugin (This product includes GeoLite data created by MaxMind, available from http://www.maxmind.com/). "),0, "http://www.maxmind.com/");
+ about.addCredit("http://flags.blogpotato.de/",I18N_NOOP("Country flags"),0);
+ about.addCredit("Adam Forsyth",I18N_NOOP("File prioritization"),"agforsyth@gmail.com");
+ about.addCredit("Thomas Bernard",I18N_NOOP("Miniupnp was used as an example for our own UPnP implementation"),0,"http://miniupnp.free.fr/");
+ about.addCredit("Diego Rosario Brogna",I18N_NOOP("Global max share ratio patch"),0,"dierbro@gmail.com");
+ about.addCredit("Lesly Weyts",I18N_NOOP("Zeroconf enhancements"),0,0);
+ about.addCredit("Kevin Andre",I18N_NOOP("Zeroconf enhancements"),0,"http://users.edpnet.be/hyperquantum/");
+ about.addCredit("Dagur Valberg Johannsson",I18N_NOOP("Coldmilk webgui"),"dagurval@pvv.ntnu.no");
+ about.addCredit("Alexander Dymo",I18N_NOOP("IDEAl code from KDevelop"),"adymo@kdevelop.org");
+ about.addCredit("Scott Wolchok",I18N_NOOP("Conversion speed improvement in ipfilter plugin"),"swolchok@umich.edu");
+ about.addCredit("Bryan Burns of Juniper Networks",I18N_NOOP("Discovered 2 security vulnerabilities (both are fixed)"),0);
+ about.addCredit("Goten Xiao",I18N_NOOP("Patch to load silently with a save location"),0);
+ about.addCredit("Rapsys",I18N_NOOP("Fixes in PHP code of webinterface"),0);
+ about.addCredit("Athantor",I18N_NOOP("XFS specific disk preallocation"),0);
+ about.addCredit("twisted_fall",I18N_NOOP("Patch to not show very low speeds"),"twisted.fall@gmail.com");
+ about.addCredit("Lucke",I18N_NOOP("Patch to show potentially firewalled status"),0);
+ about.addCredit("Modestas Vainius",I18N_NOOP("Several patches"),"modestas@vainius.eu");
+ about.addCredit("Stefan Monov",I18N_NOOP("Patch to hide the menubar"),"logixoul@gmail.com");
+ about.addCredit("The_Kernel",I18N_NOOP("Patch to modify file priorities in the webgui"),"kernja@cs.earlham.edu");
+ about.addCredit("Rafał Miłecki",I18N_NOOP("Several webgui patches"),"zajec5@gmail.com");
+ about.addCredit("Lukasz Fibinger",I18N_NOOP("Filterbar patch"),"lucke@o2.pl");
+ about.addCredit("Jindrich Makovicka",I18N_NOOP("Non threaded fileview update patch"),"makovick@gmail.com");
+ about.addCredit("swolchok",I18N_NOOP("Optimization to SHA1 hash generation"),"evilsporkman@gmail.com");
+ about.addCredit("Markus Brueffer",I18N_NOOP("Patch to fix free diskspace calculation on FreeBSD"),"markus@brueffer.de");
+ about.addCredit("caruccio",I18N_NOOP("Patch to load torrents silently from the command line"),"mateus@caruccio.com");
+
+ TDECmdLineArgs::init(argc, argv, &about);
+ TDECmdLineArgs::addCmdLineOptions(options);
+
+ KTorrentApp::addCmdLineOptions();
+ if (!KTorrentApp::start())
+ {
+ fprintf(stderr, "ktorrent is already running!\n");
+ return 0;
+ }
+
+ // need to grab lock after the fork call in start, otherwise this will not work properly
+ if (!GrabPIDLock())
+ {
+ fprintf(stderr, "ktorrent is already running!\n");
+ return 0;
+ }
+
+ try
+ {
+ KTorrentApp app;
+ app.exec();
+ }
+ catch (bt::Error & e)
+ {
+ fprintf(stderr, "Aborted by error : %s\n",e.toString().ascii());
+ }
+ Globals::cleanup();
+
+// printf("\n\nObjects alive = %i\n\n",(unsigned int)Object::numAlive());
+ return 0;
+}
+
+
diff --git a/src/apps/ktorrent/newui/CMakeLists.txt b/src/apps/ktorrent/newui/CMakeLists.txt
new file mode 100644
index 0000000..a9dc774
--- /dev/null
+++ b/src/apps/ktorrent/newui/CMakeLists.txt
@@ -0,0 +1,14 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+##### newui library (static)
+
+tde_add_library( newui STATIC_PIC AUTOMOC
+ SOURCES
+ button.cpp button.h buttonbar.cpp buttonbar.h comdefs.h ddockwindow.cpp ddockwindow.h
+ dmainwindow.cpp dmainwindow.h docksplitter.cpp docksplitter.h dtabwidget.cpp dtabwidget.h
+)
diff --git a/src/apps/ktorrent/newui/button.cpp b/src/apps/ktorrent/newui/button.cpp
new file mode 100644
index 0000000..d2d839b
--- /dev/null
+++ b/src/apps/ktorrent/newui/button.cpp
@@ -0,0 +1,351 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "button.h"
+
+#include <tqpainter.h>
+#include <tqtooltip.h>
+#include <tqstyle.h>
+#include <tqapplication.h>
+#include <tqregexp.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <kxmlguiclient.h>
+#include <tdeaction.h>
+#include <tdepopupmenu.h>
+#include <kinputdialog.h>
+#include <tdelocale.h>
+#include <tdeapplication.h>
+#include <tdeconfig.h>
+
+#include "buttonbar.h"
+
+namespace Ideal {
+
+Button::Button(ButtonBar *parent, const TQString text, const TQIconSet &icon,
+ const TQString &description)
+ :TQPushButton(icon, text, parent), m_buttonBar(parent), m_description(description),
+ m_place(parent->place()), m_realText(text), m_realIconSet(icon)
+{
+ hide();
+ setFlat(true);
+ setToggleButton(true);
+ setFocusPolicy(TQWidget::NoFocus);
+ setDescription(m_description);
+ setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
+ resize(sizeHint());
+ fixDimensions(Ideal::Bottom);
+
+ TQToolTip::add(this, m_realText);
+
+ m_assignAccelAction = new TDEAction(i18n("Assign Accelerator..."), 0,
+ this, TQ_SLOT(assignAccel()), this);
+ m_clearAccelAction = new TDEAction(i18n("Clear Accelerator"), 0,
+ this, TQ_SLOT(clearAccel()), this);
+
+ TDEConfig *config = tdeApp->config();
+ config->setGroup("UI");
+ TQString accel = config->readEntry(TQString("button_%1").arg(text), "");
+ if (!accel.isEmpty())
+ setRealText(TQString("&%1 %2").arg(accel).arg(m_realText));
+}
+
+Button::~Button()
+{
+// m_buttonBar->removeButton(this);
+ TDEConfig *config = tdeApp->config();
+ config->setGroup("UI");
+
+ TQRegExp r("^&([0-9])\\s.*");
+ TQRegExp r2("^&[0-9]\\s");
+ if (r.search(m_realText) > -1)
+ {
+ TQString text = m_realText;
+ if (text.contains(r2))
+ text.remove(r2);
+ config->writeEntry(TQString("button_%1").arg(text), r.cap(1));
+ }
+ else
+ {
+ config->writeEntry(TQString("button_%1").arg(m_realText), "");
+ }
+}
+
+void Button::setDescription(const TQString &description)
+{
+ m_description = description;
+ TQToolTip::remove(this);
+ TQToolTip::add(this, m_description);
+}
+
+TQString Button::description() const
+{
+ return m_description;
+}
+
+void Button::drawButton(TQPainter *p)
+{
+ TQRect r = rect();
+ TQSize sh = r.size();
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ sh.setHeight(r.width());
+ sh.setWidth(r.height());
+ break;
+ }
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (isOn())
+ flags |= TQStyle::Style_On;
+ if (! isFlat() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+ if (isDefault())
+ flags |= TQStyle::Style_ButtonDefault;
+
+ TQPixmap pm(sh.width(), sh.height());
+ pm.fill(eraseColor());
+ TQPainter p2(&pm);
+
+ style().drawControl(TQStyle::CE_PushButton,&p2,this, TQRect(0,0,pm.width(),pm.height()), colorGroup(),flags);
+
+ style().drawControl(TQStyle::CE_PushButtonLabel, &p2, this,
+ TQRect(0,0,pm.width(),pm.height()),
+ colorGroup(), flags, TQStyleOption());
+
+ switch (m_place)
+ {
+ case Ideal::Left:
+ p->rotate(-90);
+ p->drawPixmap(1-pm.width(), 0, pm);
+ break;
+ case Ideal::Right:
+ p->rotate(90);
+ p->drawPixmap(0, 1-pm.height(), pm);
+ break;
+ default:
+ p->drawPixmap(0, 0, pm);
+ break;
+ }
+}
+
+void Button::drawButtonLabel(TQPainter */*p*/)
+{
+}
+
+ButtonMode Button::mode()
+{
+ return m_buttonBar->mode();
+}
+
+void Button::setPlace(Ideal::Place place)
+{
+ Place oldPlace = m_place;
+ m_place = place;
+ fixDimensions(oldPlace);
+}
+
+void Button::fixDimensions(Place oldPlace)
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ if ((oldPlace == Ideal::Bottom) || (oldPlace == Ideal::Top))
+ {
+ setFixedWidth(height());
+ setMinimumHeight(sizeHint().width());
+ setMaximumHeight(32767);
+ }
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ if ((oldPlace == Ideal::Left) || (oldPlace == Ideal::Right))
+ {
+ setFixedHeight(width());
+ setMinimumWidth(sizeHint().height());
+ setMaximumWidth(32767);
+ }
+ break;
+ }
+}
+
+TQSize Button::sizeHint() const
+{
+ return sizeHint(text());
+}
+
+TQSize Button::sizeHint(const TQString &text) const
+{
+ constPolish();
+ int w = 0, h = 0;
+
+ if ( iconSet() && !iconSet()->isNull() && (m_buttonBar->mode() != Text) ) {
+ int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4;
+ int ih = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height();
+ w += iw;
+ h = TQMAX( h, ih );
+ }
+ if ( isMenuButton() )
+ w += style().pixelMetric(TQStyle::PM_MenuButtonIndicator, this);
+ if ( pixmap() ) {
+ TQPixmap *pm = (TQPixmap *)pixmap();
+ w += pm->width();
+ h += pm->height();
+ } else if (m_buttonBar->mode() != Icons) {
+ TQString s( text );
+ bool empty = s.isEmpty();
+ if ( empty )
+ s = TQString::fromLatin1("XXXX");
+ TQFontMetrics fm = fontMetrics();
+ TQSize sz = fm.size( ShowPrefix, s );
+ if(!empty || !w)
+ w += sz.width();
+ if(!empty || !h)
+ h = TQMAX(h, sz.height());
+ }
+
+ return (style().sizeFromContents(TQStyle::CT_ToolButton, this, TQSize(w, h)).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+void Button::updateSize()
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ setMinimumHeight(sizeHint().width());
+ resize(sizeHint().height(), sizeHint().width());
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ resize(sizeHint().width(), sizeHint().height());
+ break;
+ }
+}
+
+TQString Button::realText() const
+{
+ return m_realText;
+}
+
+void Button::setMode(Ideal::ButtonMode mode)
+{
+ switch (mode)
+ {
+ case Text:
+ disableIconSet();
+ enableText();
+ break;
+ case IconsAndText:
+ enableIconSet();
+ enableText();
+ break;
+ case Icons:
+ disableText();
+ enableIconSet();
+ break;
+ }
+}
+
+void Button::enableIconSet()
+{
+ if (!iconSet())
+ {
+ if (m_realIconSet.isNull())
+ m_realIconSet = SmallIcon("file_new");
+ setIconSet(m_realIconSet);
+ }
+}
+
+void Button::disableIconSet()
+{
+ setIconSet(TQIconSet());
+}
+
+void Button::disableText()
+{
+ if (text().length() > 0)
+ setText("");
+}
+
+void Button::enableText()
+{
+ setText(m_realText);
+}
+
+void Button::contextMenuEvent(TQContextMenuEvent *e)
+{
+/* TQPopupMenu menu;
+
+ m_assignAccelAction->plug(&menu);
+ if (m_realText.contains(TQRegExp("^&[0-9]\\s")))
+ m_clearAccelAction->plug(&menu);
+
+ emit contextMenu( &menu );
+
+ menu.exec(e->globalPos());
+ */
+}
+
+void Button::assignAccel()
+{
+ bool ok;
+ int num = KInputDialog::getInteger(i18n("Change Button Number"), i18n("New accelerator number:"), 1, 0, 10, 1, &ok, this);
+ if (ok)
+ {
+ TQString text = realTextWithoutAccel();
+ text = TQString("&%1 %2").arg(num).arg(text);
+ setRealText(text);
+ }
+}
+
+void Button::setRealText(const TQString &text)
+{
+ m_realText = text;
+ setText(text);
+ updateSize();
+}
+
+void Button::clearAccel()
+{
+ setRealText(realTextWithoutAccel());
+}
+
+TQString Button::realTextWithoutAccel() const
+{
+ TQString text = m_realText;
+ TQRegExp r("^&[0-9]\\s");
+ if (text.contains(r))
+ text.remove(r);
+ return text;
+}
+
+}
+
+#include "button.moc"
diff --git a/src/apps/ktorrent/newui/button.h b/src/apps/ktorrent/newui/button.h
new file mode 100644
index 0000000..23c45c1
--- /dev/null
+++ b/src/apps/ktorrent/newui/button.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef IDEALBUTTON_H
+#define IDEALBUTTON_H
+
+#include <tqpushbutton.h>
+#include <tqiconset.h>
+
+#include "comdefs.h"
+
+class TDEAction;
+
+namespace Ideal {
+
+class ButtonBar;
+
+/**
+@short A button to place onto the ButtonBar
+
+A TQPushButton derivative with a size of a TQToolBar. Button can be rotated
+(placed onto different places in ideal mode).
+*/
+class Button : public TQPushButton {
+ TQ_OBJECT
+
+public:
+ Button(ButtonBar *parent, const TQString text, const TQIconSet &icon = TQIconSet(),
+ const TQString &description = TQString());
+
+ /**Sets the description used as a tooltip.*/
+ void setDescription(const TQString &description);
+ /**Returns the description.*/
+ TQString description() const;
+
+ /**Sets the place of a button.*/
+ void setPlace(Ideal::Place place);
+ /**Sets the mode of a button.*/
+ void setMode(Ideal::ButtonMode mode);
+
+ TQSize sizeHint() const;
+ TQSize sizeHint(const TQString &text) const;
+
+ /**Updates size of a widget. Used after squeezing button's text.*/
+ void updateSize();
+
+ /**Returns the real (i.e. not squeezed) text of a button.*/
+ TQString realText() const;
+ TQString realTextWithoutAccel() const;
+ void setRealText(const TQString &text);
+
+protected:
+ ButtonMode mode();
+
+ virtual void drawButton(TQPainter *p);
+ virtual void drawButtonLabel(TQPainter *p);
+
+ virtual void contextMenuEvent(TQContextMenuEvent *e);
+
+protected slots:
+ void assignAccel();
+ void clearAccel();
+
+signals:
+ void contextMenu(TQPopupMenu*);
+
+private:
+ virtual ~Button();
+
+ void fixDimensions(Place oldPlace);
+
+ void enableIconSet();
+ void disableIconSet();
+ void enableText();
+ void disableText();
+
+ ButtonBar *m_buttonBar;
+
+ TQString m_description;
+ Place m_place;
+
+ TQString m_realText;
+ TQIconSet m_realIconSet;
+
+ TDEAction *m_assignAccelAction;
+ TDEAction *m_clearAccelAction;
+
+friend class ButtonBar;
+};
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/newui/buttonbar.cpp b/src/apps/ktorrent/newui/buttonbar.cpp
new file mode 100644
index 0000000..640fb3e
--- /dev/null
+++ b/src/apps/ktorrent/newui/buttonbar.cpp
@@ -0,0 +1,346 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "buttonbar.h"
+
+#include <tqlayout.h>
+
+#include <kdebug.h>
+#include <tdeconfig.h>
+#include <kstringhandler.h>
+#include <tdelocale.h>
+
+#include "button.h"
+
+namespace Ideal {
+
+//ButtonLayout class
+
+ButtonLayout::ButtonLayout(ButtonBar *parent, Direction d, int margin, int spacing, const char *name)
+ :TQBoxLayout(parent, d, margin, spacing, name), m_buttonBar(parent)
+{
+}
+
+TQSize ButtonLayout::minimumSize() const
+{
+ TQSize size = TQBoxLayout::minimumSize();
+
+ if (!m_buttonBar->autoResize())
+ return size;
+
+ switch (m_buttonBar->place())
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ return TQSize(size.width(),0);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ return TQSize(0,size.height());
+ }
+ return TQBoxLayout::minimumSize();
+}
+
+
+
+//ButtonBar class
+
+
+ButtonBar::ButtonBar(Place place, ButtonMode mode, TQWidget *parent, const char *name)
+ :TQWidget(parent, name), m_place(place), l(0), m_shrinked(false), m_autoResize(true)
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ l = new ButtonLayout(this, TQBoxLayout::TopToBottom, 0, 0);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ l = new ButtonLayout(this, TQBoxLayout::LeftToRight, 0, 0);
+ break;
+ }
+
+ l->setResizeMode(TQLayout::Minimum);
+ setMode(mode);
+
+ l->insertStretch(-1);
+}
+
+ButtonBar::~ButtonBar()
+{
+}
+
+void ButtonBar::addButton(Button *button)
+{
+ int buttonCount = m_buttons.count();
+
+ button->setMode(m_mode);
+ m_buttons.append(button);
+ l->insertWidget(buttonCount, button);
+ button->show();
+ fixDimensions();
+}
+
+void ButtonBar::removeButton(Button *button)
+{
+ m_buttons.remove(button);
+ l->remove(button);
+ delete button;
+}
+
+void ButtonBar::setMode(ButtonMode mode)
+{
+ m_mode = mode;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ (*it)->setMode(mode);
+}
+
+ButtonMode ButtonBar::mode() const
+{
+ return m_mode;
+}
+
+Place ButtonBar::place() const
+{
+ return m_place;
+}
+
+void ButtonBar::fixDimensions()
+{
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ setFixedWidth(sizeHint().width());
+ setMinimumHeight(sizeHint().height());
+ setMaximumHeight(32767);
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ setFixedHeight(sizeHint().height());
+ setMinimumWidth(sizeHint().width());
+ setMaximumWidth(32767);
+ break;
+ }
+}
+
+void ButtonBar::setButtonsPlace(Ideal::Place place)
+{
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ (*it)->setPlace(place);
+}
+
+void ButtonBar::resizeEvent(TQResizeEvent *ev)
+{
+ int preferredDimension = 0;
+ int actualDimension = 0;
+ int oldDimension = 0;
+ switch (m_place)
+ {
+ case Ideal::Left:
+ case Ideal::Right:
+ preferredDimension = l->TQBoxLayout::minimumSize().height();
+ actualDimension = size().height();
+ oldDimension = ev->oldSize().height();
+ break;
+ case Ideal::Top:
+ case Ideal::Bottom:
+ preferredDimension = l->TQBoxLayout::minimumSize().width();
+ actualDimension = size().width();
+ oldDimension = ev->oldSize().width();
+ break;
+ }
+
+ if (preferredDimension > actualDimension)
+ shrink(preferredDimension, actualDimension);
+ else if (m_shrinked && (originalDimension() < actualDimension))
+ unshrink();
+ else if (m_shrinked && actualDimension > oldDimension)
+ deshrink(preferredDimension, actualDimension);
+
+ TQWidget::resizeEvent(ev);
+}
+
+void ButtonBar::shrink(int preferredDimension, int actualDimension)
+{
+ if (!preferredDimension)
+ return;
+
+ m_shrinked = true;
+
+ uint textLength = 0;
+ TQValueList<uint> texts;
+ uint maxLength = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ uint length = (*it)->text().length();
+ maxLength = length > maxLength ? length : maxLength ;
+ texts.append(length);
+ textLength += length;
+ }
+
+ uint newPreferredLength = actualDimension * textLength / preferredDimension;
+
+ uint newMaxLength = maxLength;
+ uint newTextLength;
+ do {
+ newMaxLength -= 1;
+ newTextLength = 0;
+ for (TQValueList<uint>::iterator it = texts.begin(); it != texts.end(); ++it)
+ {
+ if (*it > newMaxLength)
+ *it = newMaxLength;
+ newTextLength += *it;
+ }
+ } while (newTextLength > newPreferredLength);
+
+ int i = 0;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ (*it)->setText(KStringHandler::rsqueeze((*it)->realText(), texts[i++]));
+ (*it)->updateSize();
+ }
+}
+
+void ButtonBar::deshrink(int preferredDimension, int actualDimension)
+{
+ if (!preferredDimension)
+ return;
+
+ m_shrinked = true;
+
+ uint textLength = 0;
+ TQValueList<uint> texts;
+ uint maxLength = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ uint length = (*it)->text().length();
+ maxLength = length > maxLength ? length : maxLength ;
+ texts.append(length);
+ textLength += length;
+ }
+
+ uint newPreferredLength = actualDimension * textLength / preferredDimension;
+
+ if (newPreferredLength <= textLength)
+ return;
+
+ uint newTextLength;
+ uint prevTextLength = 0;
+ do {
+ newTextLength = 0;
+ int i = 0;
+ for (TQValueList<uint>::iterator it = texts.begin(); it != texts.end(); ++it, i++)
+ {
+ if (m_buttons[i]->text().contains("..."))
+ (*it)++;
+ newTextLength += *it;
+ }
+ if (newTextLength == prevTextLength)
+ break;
+ prevTextLength = newTextLength;
+ } while (newTextLength < newPreferredLength);
+
+ int i = 0;
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ if (texts[i] >= (*it)->realText().length())
+ (*it)->setText((*it)->realText());
+ else
+ (*it)->setText(KStringHandler::rsqueeze((*it)->realText(), texts[i]));
+ (*it)->updateSize();
+ ++i;
+ }
+}
+
+void ButtonBar::unshrink()
+{
+ for (ButtonList::iterator it = m_buttons.begin(); it != m_buttons.end(); ++it)
+ {
+ (*it)->setText((*it)->realText());
+ (*it)->updateSize();
+ }
+ m_shrinked = false;
+}
+
+int ButtonBar::originalDimension()
+{
+ int size = 0;
+ for (ButtonList::const_iterator it = m_buttons.constBegin(); it != m_buttons.constEnd(); ++it)
+ {
+ size += (*it)->sizeHint((*it)->realText()).width();
+ }
+ return size;
+}
+
+bool ButtonBar::autoResize() const
+{
+ return m_autoResize;
+}
+
+void ButtonBar::setAutoResize(bool b)
+{
+ m_autoResize = b;
+}
+
+Button *ButtonBar::firstButton()
+{
+ if (!m_buttons.isEmpty())
+ return m_buttons.first();
+ return 0;
+}
+
+Button *ButtonBar::nextTo(Button *button)
+{
+ ButtonList::iterator it = m_buttons.find(button);
+ Button *next = 0;
+ if ((*it) == m_buttons.last())
+ next = m_buttons.first();
+ else
+ {
+ it++;
+ next = *it;
+ }
+ if (next->isVisible())
+ return next;
+ else
+ return nextTo(next);
+}
+
+Button *ButtonBar::prevTo(Button *button)
+{
+ ButtonList::iterator it = m_buttons.find(button);
+ Button *prev = 0;
+ if (it == m_buttons.begin())
+ prev = m_buttons.last();
+ else
+ {
+ it--;
+ prev = *it;
+ }
+ if (prev->isVisible())
+ return prev;
+ else
+ return prevTo(prev);
+}
+
+}
+
+#include "buttonbar.moc"
diff --git a/src/apps/ktorrent/newui/buttonbar.h b/src/apps/ktorrent/newui/buttonbar.h
new file mode 100644
index 0000000..3f23957
--- /dev/null
+++ b/src/apps/ktorrent/newui/buttonbar.h
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef IDEALBUTTONBAR_H
+#define IDEALBUTTONBAR_H
+
+#include <tqwidget.h>
+#include <tqvaluelist.h>
+
+#include "comdefs.h"
+
+#include <tqlayout.h>
+
+namespace Ideal {
+
+class Button;
+class ButtonBar;
+
+/**@short A layout for a ButtonBar class.
+
+Overrides minimumSize method to allow shrinking button bar buttons.*/
+class ButtonLayout: public TQBoxLayout{
+public:
+ ButtonLayout(ButtonBar *parent, Direction d, int margin = 0, int spacing = -1, const char * name = 0);
+
+ virtual TQSize minimumSize() const;
+
+private:
+ ButtonBar *m_buttonBar;
+};
+
+/**
+@short A bar with tool buttons.
+
+Looks like a toolbar but has another behaviour. It is suitable for
+placing on the left(right, bottom, top) corners of a window as a bar with slider.
+*/
+class ButtonBar : public TQWidget {
+ TQ_OBJECT
+
+public:
+ ButtonBar(Place place, ButtonMode mode = IconsAndText,
+ TQWidget *parent = 0, const char *name = 0);
+ virtual ~ButtonBar();
+
+ /**Adds a button to the bar.*/
+ virtual void addButton(Button *button);
+ /**Removes a button from the bar and deletes the button.*/
+ virtual void removeButton(Button *button);
+
+ /**Sets the mode.*/
+ void setMode(ButtonMode mode);
+ /**@returns the mode.*/
+ ButtonMode mode() const;
+
+ /**@returns the place.*/
+ Place place() const;
+
+ bool autoResize() const;
+ void setAutoResize(bool b);
+
+ /**Shrinks the button bar so all buttons are visible. Shrinking is done by
+ reducing the amount of text shown on buttons. Button icon size is a minimum size
+ of a button. If a button does not have an icon, it displays "...".*/
+ virtual void shrink(int preferredDimension, int actualDimension);
+ virtual void deshrink(int preferredDimension, int actualDimension);
+ /**Restores the size of button bar buttons.*/
+ virtual void unshrink();
+
+ Button *firstButton();
+ Button *nextTo(Button *button);
+ Button *prevTo(Button *button);
+
+protected:
+ virtual void resizeEvent ( TQResizeEvent *ev );
+
+ int originalDimension();
+
+private:
+ void fixDimensions();
+ void setButtonsPlace(Ideal::Place place);
+
+ typedef TQValueList<Button*> ButtonList;
+ ButtonList m_buttons;
+
+ ButtonMode m_mode;
+ Place m_place;
+
+ ButtonLayout *l;
+
+ bool m_shrinked;
+ bool m_autoResize;
+};
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/newui/comdefs.h b/src/apps/ktorrent/newui/comdefs.h
new file mode 100644
index 0000000..8233f12
--- /dev/null
+++ b/src/apps/ktorrent/newui/comdefs.h
@@ -0,0 +1,30 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef COMDEFS_H
+#define COMDEFS_H
+
+namespace Ideal {
+
+ enum Place { Left=1, Right=2, Top=4, Bottom=8 };
+ enum ButtonMode { Text, IconsAndText, Icons };
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/newui/ddockwindow.cpp b/src/apps/ktorrent/newui/ddockwindow.cpp
new file mode 100644
index 0000000..b52815f
--- /dev/null
+++ b/src/apps/ktorrent/newui/ddockwindow.cpp
@@ -0,0 +1,418 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "ddockwindow.h"
+
+#include <tqtoolbutton.h>
+#include <tqlayout.h>
+#include <tqstyle.h>
+#include <tqwidgetstack.h>
+#include <tqimage.h>
+#include <tqapplication.h>
+#include <tqpopupmenu.h>
+
+#include <kdebug.h>
+#include <tdeglobal.h>
+#include <tdeconfig.h>
+#include <kcombobox.h>
+#include <tdelocale.h>
+#include <kiconloader.h>
+#include <tdeapplication.h>
+
+#include "buttonbar.h"
+#include "button.h"
+#include "dmainwindow.h"
+
+DDockWindow::DDockWindow(DMainWindow *parent, Position position)
+ :TQDockWindow(TQDockWindow::InDock, parent), m_position(position), m_visible(false),
+ m_mainWindow(parent), m_doNotCloseActiveWidget(false), m_toggledButton(0), m_lastContextMenuButton(0)
+{
+ setMovingEnabled(false);
+ setResizeEnabled(true);
+
+ Ideal::Place place = Ideal::Left;
+ switch (position) {
+ case DDockWindow::Bottom:
+ m_name = "BottomToolWindow";
+ place = Ideal::Bottom;
+ m_internalLayout = new TQVBoxLayout(boxLayout(), 0);
+ m_internalLayout->setDirection(TQBoxLayout::BottomToTop);
+ break;
+ case DDockWindow::Left:
+ m_name = "LeftToolWindow";
+ place = Ideal::Left;
+ m_internalLayout = new TQHBoxLayout(boxLayout(), 0);
+ m_internalLayout->setDirection(TQBoxLayout::LeftToRight);
+ break;
+ case DDockWindow::Right:
+ m_name = "RightToolWindow";
+ place = Ideal::Right;
+ m_internalLayout = new TQHBoxLayout(boxLayout(), 0);
+ m_internalLayout->setDirection(TQBoxLayout::RightToLeft);
+ break;
+ }
+
+ TDEConfig *config = tdeApp->config();
+ config->setGroup("UI");
+ int mode = config->readNumEntry("MDIStyle", 3);
+ Ideal::ButtonMode buttonMode = Ideal::Text;
+ if (mode == 0)
+ buttonMode = Ideal::Icons;
+ else if (mode == 1)
+ buttonMode = Ideal::Text;
+ else if (mode == 3)
+ buttonMode = Ideal::IconsAndText;
+
+ m_bar = new Ideal::ButtonBar(place, buttonMode, this);
+ m_internalLayout->addWidget(m_bar);
+
+ m_widgetStack = new TQWidgetStack(this);
+ m_internalLayout->addWidget(m_widgetStack);
+
+ m_moveToDockLeft = new TDEAction( i18n("Move to left dock"), 0, this, TQ_SLOT(moveToDockLeft()), this );
+ m_moveToDockRight = new TDEAction( i18n("Move to right dock"), 0, this, TQ_SLOT(moveToDockRight()), this );
+ m_moveToDockBottom = new TDEAction( i18n("Move to bottom dock"), 0, this, TQ_SLOT(moveToDockBottom()), this );
+
+ setVisible(m_visible);
+
+ loadSettings();
+}
+
+DDockWindow::~DDockWindow()
+{
+//done in DMainWindow now
+// saveSettings();
+}
+
+void DDockWindow::setVisible(bool v)
+{
+ //write dock width to the config file
+ TDEConfig *config = tdeApp->config();
+ TQString group = TQString("%1").arg(m_name);
+ config->setGroup(group);
+
+ if (m_visible)
+ config->writeEntry("ViewWidth", m_position == DDockWindow::Bottom ? height() : width() );
+ setResizeEnabled(v);
+ setVerticallyStretchable(true);
+ setHorizontallyStretchable(true);
+ v ? m_widgetStack->show() : m_widgetStack->hide();
+ m_visible = v;
+
+ m_internalLayout->invalidate();
+ if (!m_visible)
+ {
+ if (m_position == DDockWindow::Bottom)
+ setFixedExtentHeight(m_internalLayout->sizeHint().height());
+ else
+ setFixedExtentWidth(m_internalLayout->sizeHint().width());
+ emit hidden();
+ }
+ else
+ {
+ //restore widget size from the config
+ int size = 0;
+ if (m_position == DDockWindow::Bottom)
+ {
+ size = config->readNumEntry("ViewWidth", m_internalLayout->minimumSize().height());
+ setFixedExtentHeight(size);
+ }
+ else
+ {
+ size = config->readNumEntry("ViewWidth", m_internalLayout->minimumSize().width());
+ setFixedExtentWidth(size);
+ }
+ }
+}
+
+void DDockWindow::loadSettings()
+{
+}
+
+void DDockWindow::saveSettings()
+{
+ TDEConfig *config = tdeApp->config();
+ TQString group = TQString("%1").arg(m_name);
+ int invisibleWidth = 0;
+ config->setGroup(group);
+ if (config->hasKey("ViewWidth"))
+ invisibleWidth = config->readNumEntry("ViewWidth");
+ config->deleteEntry("ViewWidth");
+ config->deleteEntry("ViewLastWidget");
+ if (m_toggledButton && m_visible)
+ {
+ config->writeEntry("ViewWidth", m_position == DDockWindow::Bottom ? height() : width());
+ config->writeEntry("ViewLastWidget", m_toggledButton->realTextWithoutAccel());
+ }
+ else if (invisibleWidth != 0)
+ config->writeEntry("ViewWidth", invisibleWidth);
+}
+
+TQWidget *DDockWindow::currentWidget() const
+{
+ return m_widgetStack->visibleWidget();
+}
+
+void DDockWindow::addWidget(const TQString &title, TQWidget *widget, bool skipActivation)
+{
+ kdDebug(9000) << k_funcinfo << endl;
+ TQPixmap *pm = const_cast<TQPixmap*>(widget->icon());
+ Ideal::Button *button;
+ if (pm != 0)
+ {
+ //force 16pt for now
+ if (pm->height() > 16)
+ {
+ TQImage img = pm->convertToImage();
+ img = img.smoothScale(16, 16);
+ pm->convertFromImage(img);
+ }
+ button = new Ideal::Button(m_bar, title, *pm);
+ }
+ else
+ button = new Ideal::Button(m_bar, title);
+ m_widgets[button] = widget;
+ m_buttons[widget] = button;
+ m_bar->addButton(button);
+
+ m_widgetStack->addWidget(widget);
+ connect(button, TQ_SIGNAL(clicked()), this, TQ_SLOT(selectWidget()));
+ connect(button, TQ_SIGNAL(contextMenu(TQPopupMenu*)), this, TQ_SLOT(contextMenu(TQPopupMenu*)) );
+
+ if (!skipActivation)
+ {
+ //if the widget was selected last time the dock is deleted
+ //we need to show it
+ TDEConfig *config = tdeApp->config();
+ TQString group = TQString("%1").arg(m_name);
+ config->setGroup(group);
+ if (config->readEntry("ViewLastWidget") == title)
+ {
+ kdDebug(9000) << k_funcinfo << " : activating last widget " << title << endl;
+ button->setOn(true);
+ selectWidget(button);
+ }
+ }
+}
+
+void DDockWindow::raiseWidget(TQWidget *widget)
+{
+ kdDebug(9000) << k_funcinfo << endl;
+
+ if ( !widget ) return;
+
+ Ideal::Button *button = m_buttons[widget];
+ if ((button != 0) && (!button->isOn()))
+ {
+ button->setOn(true);
+ selectWidget(button);
+ }
+}
+
+void DDockWindow::lowerWidget(TQWidget * widget)
+{
+ kdDebug(9000) << k_funcinfo << endl;
+
+ if ( !widget ) return;
+
+ Ideal::Button *button = m_buttons[widget];
+ if ((button != 0) && (button->isOn()))
+ {
+ button->setOn(false);
+ selectWidget(button);
+ }
+}
+
+void DDockWindow::removeWidget(TQWidget *widget)
+{
+ kdDebug(9000) << k_funcinfo << endl;
+ if (m_widgetStack->id(widget) == -1)
+ return; //not in dock
+
+ bool changeVisibility = false;
+ if (m_widgetStack->visibleWidget() == widget)
+ changeVisibility = true;
+
+ Ideal::Button *button = m_buttons[widget];
+ if (button)
+ m_bar->removeButton(button);
+ m_widgets.remove(button);
+ m_buttons.remove(widget);
+ m_widgetStack->removeWidget(widget);
+
+ if (changeVisibility)
+ {
+ m_toggledButton = 0;
+ setVisible(false);
+ }
+}
+
+void DDockWindow::selectWidget(Ideal::Button *button)
+{
+ bool special = m_doNotCloseActiveWidget;
+ m_doNotCloseActiveWidget = false;
+ kdDebug(9000) << k_funcinfo << endl;
+ if (m_toggledButton == button)
+ {
+ if (special && m_visible && (!isActive()))
+ {
+ //special processing for keyboard navigation events
+ m_toggledButton->setOn(true);
+ m_widgets[button]->setFocus();
+ }
+ else
+ {
+ m_widgets[button]->setFocus();
+ setVisible(!m_visible);
+ }
+ return;
+ }
+
+ if (m_toggledButton)
+ m_toggledButton->setOn(false);
+ m_toggledButton = button;
+ setVisible(true);
+ m_widgetStack->raiseWidget(m_widgets[button]);
+ m_widgets[button]->setFocus();
+}
+
+void DDockWindow::selectWidget()
+{
+ selectWidget((Ideal::Button*)sender());
+}
+
+void DDockWindow::hideWidget(TQWidget *widget)
+{
+ Ideal::Button *button = m_buttons[widget];
+ if (button != 0)
+ {
+ button->setOn(false);
+ button->hide();
+ }
+ widget->hide();
+ if (button == m_toggledButton)
+ setVisible(false);
+}
+
+void DDockWindow::showWidget(TQWidget *widget)
+{
+ Ideal::Button *button = m_buttons[widget];
+ if (button != 0)
+ button->show();
+// widget->show();
+}
+
+void DDockWindow::setMovingEnabled(bool)
+{
+ //some operations on TDEMainWindow cause moving to be enabled
+ //but we always don't want DDockWindow instances to be movable
+ TQDockWindow::setMovingEnabled(false);
+}
+
+void DDockWindow::selectLastWidget()
+{
+ m_doNotCloseActiveWidget = true;
+ if (m_toggledButton)
+ m_toggledButton->animateClick();
+ else if (Ideal::Button *button = m_bar->firstButton())
+ button->animateClick();
+}
+
+bool DDockWindow::isActive()
+{
+ if (m_toggledButton)
+ {
+ TQWidget *w = tqApp->focusWidget();
+ if (!w)
+ return false;
+ TQWidget *toolWidget = m_widgets[m_toggledButton];
+ if (toolWidget == w)
+ return true;
+ else
+ {
+ do {
+ w = (TQWidget*)w->parent();
+ if (w && (w == toolWidget)) return true;
+ } while (w);
+ }
+ }
+ return false;
+}
+
+void DDockWindow::selectNextWidget()
+{
+ if (!m_toggledButton)
+ return;
+ Ideal::Button *b = m_bar->nextTo(m_toggledButton);
+ if (b)
+ b->animateClick();
+}
+
+void DDockWindow::selectPrevWidget()
+{
+ if (!m_toggledButton)
+ return;
+ Ideal::Button *b = m_bar->prevTo(m_toggledButton);
+ if (b)
+ b->animateClick();
+}
+
+void DDockWindow::contextMenu(TQPopupMenu * menu)
+{
+ m_lastContextMenuButton = static_cast<Ideal::Button*>( const_cast<TQObject*>( sender() ) );
+
+ menu->insertSeparator();
+
+ if ( position() != DDockWindow::Left )
+ m_moveToDockLeft->plug( menu );
+ if ( position()!= DDockWindow::Right )
+ m_moveToDockRight->plug( menu );
+ if ( position() != DDockWindow::Bottom )
+ m_moveToDockBottom->plug( menu );
+}
+
+void DDockWindow::moveToDockLeft()
+{
+ moveToDock( DDockWindow::Left );
+}
+
+void DDockWindow::moveToDockRight()
+{
+ moveToDock( DDockWindow::Right );
+}
+
+void DDockWindow::moveToDockBottom()
+{
+ moveToDock( DDockWindow::Bottom );
+}
+
+void DDockWindow::moveToDock(DDockWindow::Position position )
+{
+ if ( m_widgets.contains( m_lastContextMenuButton ) )
+ {
+ mainWindow()->moveWidget( position, m_widgets[ m_lastContextMenuButton ], m_lastContextMenuButton->realTextWithoutAccel() );
+ }
+}
+
+bool DDockWindow::hasWidgets() const
+{
+ return m_widgets.count() > 0;
+}
+
+#include "ddockwindow.moc"
diff --git a/src/apps/ktorrent/newui/ddockwindow.h b/src/apps/ktorrent/newui/ddockwindow.h
new file mode 100644
index 0000000..84b5163
--- /dev/null
+++ b/src/apps/ktorrent/newui/ddockwindow.h
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef DDOCKWINDOW_H
+#define DDOCKWINDOW_H
+
+#include <tqdockwindow.h>
+#include <tqvaluelist.h>
+
+class TQBoxLayout;
+class TQToolButton;
+class TQWidgetStack;
+class TQPopupMenu;
+
+class KComboBox;
+class TDEAction;
+
+class DMainWindow;
+
+namespace Ideal {
+ class Button;
+ class ButtonBar;
+}
+
+class DDockWindow : public TQDockWindow {
+ TQ_OBJECT
+
+public:
+ enum Position { Bottom, Left, Right };
+
+ DDockWindow(DMainWindow *parent, Position position);
+ virtual ~DDockWindow();
+
+ virtual void setVisible(bool v);
+ bool visible() const { return m_visible; }
+ Position position() const { return m_position; }
+
+ virtual void addWidget(const TQString &title, TQWidget *widget, bool skipActivation = false);
+ virtual void raiseWidget(TQWidget *widget);
+ virtual void lowerWidget(TQWidget *widget);
+ /**Removes the widget from dock. Does not delete it.*/
+ virtual void removeWidget(TQWidget *widget);
+
+ virtual void hideWidget(TQWidget *widget);
+ virtual void showWidget(TQWidget *widget);
+
+ virtual TQWidget *currentWidget() const;
+
+ virtual void setMovingEnabled(bool b);
+
+ virtual void saveSettings();
+
+ DMainWindow *mainWindow() const { return m_mainWindow; }
+
+ virtual void selectLastWidget();
+ virtual void selectNextWidget();
+ virtual void selectPrevWidget();
+
+ bool isActive();
+ /// Check if this dock has any widgets
+ bool hasWidgets() const;
+
+signals:
+ void hidden();
+
+private slots:
+ void selectWidget();
+ void selectWidget(Ideal::Button *button);
+ void contextMenu(TQPopupMenu*);
+ void moveToDockLeft();
+ void moveToDockRight();
+ void moveToDockBottom();
+ void moveToDock(DDockWindow::Position);
+
+protected:
+ virtual void loadSettings();
+
+ Ideal::ButtonBar *m_bar;
+ TQWidgetStack *m_widgetStack;
+
+ TQMap<Ideal::Button*, TQWidget*> m_widgets;
+ TQMap<TQWidget*, Ideal::Button*> m_buttons;
+
+private:
+ Position m_position;
+ bool m_visible;
+ TQString m_name;
+ DMainWindow *m_mainWindow;
+ bool m_doNotCloseActiveWidget;
+
+ Ideal::Button *m_toggledButton;
+ Ideal::Button *m_lastContextMenuButton;
+ TQBoxLayout *m_internalLayout;
+
+
+ TDEAction * m_moveToDockLeft;
+ TDEAction * m_moveToDockRight;
+ TDEAction * m_moveToDockBottom;
+};
+
+#endif
diff --git a/src/apps/ktorrent/newui/dmainwindow.cpp b/src/apps/ktorrent/newui/dmainwindow.cpp
new file mode 100644
index 0000000..d4a2424
--- /dev/null
+++ b/src/apps/ktorrent/newui/dmainwindow.cpp
@@ -0,0 +1,318 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "dmainwindow.h"
+
+#include <kdebug.h>
+#include <tdeapplication.h>
+#include <tdeconfig.h>
+#include <kiconloader.h>
+
+#include <tqtoolbutton.h>
+
+#include "dtabwidget.h"
+#include "docksplitter.h"
+
+DMainWindow::DMainWindow(TQWidget *parent, const char *name)
+ :KParts::MainWindow(parent, name), m_firstRemoved(false), m_currentWidget(0)
+{
+ loadSettings();
+ createToolWindows();
+ m_central = new Ideal::DockSplitter(TQt::Horizontal, this);
+ m_activeTabWidget = createTab();
+ m_central->addDock(0, 0, m_activeTabWidget);
+ setCentralWidget(m_central);
+}
+
+void DMainWindow::loadSettings()
+{
+ TDEConfig *config = tdeApp->config();
+ config->setGroup("UI");
+ m_openTabAfterCurrent = config->readBoolEntry("OpenNewTabAfterCurrent", true);
+ m_showIconsOnTabs = config->readBoolEntry("ShowTabIcons", false);
+}
+
+void DMainWindow::saveSettings()
+{
+ m_leftDock->saveSettings();
+ m_rightDock->saveSettings();
+ m_bottomDock->saveSettings();
+}
+
+DMainWindow::~DMainWindow()
+{
+/* for (TQValueList<TQWidget*>::iterator it = m_widgets.begin(); it != m_widgets.end(); ++it)
+ removeWidget(*it);*/
+}
+
+DDockWindow *DMainWindow::toolWindow(DDockWindow::Position position) const
+{
+ switch (position) {
+ case DDockWindow::Bottom: return m_bottomDock;
+ case DDockWindow::Left: return m_leftDock;
+ case DDockWindow::Right: return m_rightDock;
+ }
+ return 0;
+}
+
+void DMainWindow::createToolWindows()
+{
+ m_bottomDock = new DDockWindow(this, DDockWindow::Bottom);
+ moveDockWindow(m_bottomDock, TQt::DockBottom);
+ m_leftDock = new DDockWindow(this, DDockWindow::Left);
+ moveDockWindow(m_leftDock, TQt::DockLeft);
+ m_rightDock = new DDockWindow(this, DDockWindow::Right);
+ moveDockWindow(m_rightDock, TQt::DockRight);
+
+ // hide all docks until we add stuff to it
+ m_bottomDock->hide();
+ m_leftDock->hide();
+ m_rightDock->hide();
+}
+
+void DMainWindow::addWidget(TQWidget *widget, const TQString &title)
+{
+// invalidateActiveTabWidget();
+ if (m_firstRemoved && m_activeTabWidget == m_tabs.first())
+ {
+ m_central->addDock(0, 0, m_activeTabWidget);
+ m_firstRemoved = false;
+ }
+
+ addWidget(m_activeTabWidget, widget, title);
+}
+
+void DMainWindow::addWidget(DTabWidget *tab, TQWidget *widget, const TQString &title)
+{
+ static TQPixmap emptyPixmap;
+
+ int idx = -1;
+ if (m_openTabAfterCurrent && (tab->count() > 0))
+ idx = tab->currentPageIndex() + 1;
+ if (m_showIconsOnTabs)
+ {
+ const TQPixmap *pixmap = widget->icon();
+ const TQIconSet &icons = (pixmap && (pixmap->size().height() <= 16)) ? *(pixmap) : SmallIcon("tdevelop");
+ tab->insertTab(widget, icons, title, idx);
+ }
+ else
+ tab->insertTab(widget, emptyPixmap, title, idx);
+ m_widgets.append(widget);
+ m_widgetTabs[widget] = tab;
+ widget->installEventFilter(this);
+ tab->showPage(widget);
+}
+
+void DMainWindow::removeWidget(TQWidget *widget)
+{
+ if (!m_widgets.contains(widget))
+ return; //not a widget in main window
+
+ if (m_widgetTabs.contains(widget))
+ {
+ DTabWidget *tab = m_widgetTabs[widget];
+ if (tab->indexOf(widget) >= 0)
+ {
+ tab->removePage(widget);
+ widget->reparent(0,TQPoint(0,0),false);
+ if (tab->count() == 0)
+ {
+ if (tab->closeButton())
+ tab->closeButton()->hide();
+ //remove and delete tabwidget if it is not the first one
+ if (tab != m_tabs.first())
+ {
+ TQPair<uint, uint> idx = m_central->indexOf(tab);
+ m_tabs.remove(tab);
+ m_activeTabWidget = m_tabs.first();
+ m_central->removeDock(idx.first, idx.second, true);
+ }
+ //only temporarily remove the first tabwidget
+ else
+ {
+ m_central->removeDock(0, 0, false);
+ m_firstRemoved = true;
+ }
+ //focus smth in m_activeTabWidget
+ if (m_activeTabWidget)
+ {
+ if (m_activeTabWidget->currentPage())
+ {
+ m_activeTabWidget->currentPage()->setFocus();
+ }
+ }
+ }
+ }
+ }
+
+ m_widgets.remove(widget);
+ m_widgetTabs.remove(widget);
+ if (m_activeTabWidget && m_activeTabWidget->currentPage())
+ {
+ //a hack to please multibuffer and actually switch the active part
+ TQFocusEvent ev(TQEvent::FocusIn);
+ TQApplication::sendEvent(m_activeTabWidget->currentPage(), &ev);
+ }
+}
+
+DTabWidget *DMainWindow::splitHorizontal()
+{
+ m_activeTabWidget = createTab();
+ m_central->addDock(m_central->numRows(), 0, m_activeTabWidget);
+ return m_activeTabWidget;
+}
+
+DTabWidget *DMainWindow::splitVertical()
+{
+// invalidateActiveTabWidget();
+ int row = m_central->indexOf(m_activeTabWidget).first;
+ m_activeTabWidget = createTab();
+ m_central->addDock(row, m_central->numCols(row), m_activeTabWidget);
+ return m_activeTabWidget;
+}
+
+void DMainWindow::invalidateActiveTabWidget()
+{
+/* TQWidget *focused = m_central->focusWidget();
+ kdDebug(9000) << "invalidate: " << focused << endl;
+ if (focused == 0)
+ return;
+ if (!m_widgets.contains(focused))
+ {
+ kdDebug(9000) << " focused is not in m_widgets" << endl;
+ return;
+ }
+ if (m_widgetTabs.contains(focused))
+ {
+ kdDebug(9000) << " focused is in m_widgets and m_widgetTabs" << endl;
+ DTabWidget *tab = m_widgetTabs[focused];
+ if (tab->indexOf(focused) >= 0)
+ m_activeTabWidget = tab;
+ kdDebug(9000) << " tab: " << tab << endl;
+ }*/
+}
+
+DTabWidget *DMainWindow::createTab()
+{
+ DTabWidget *tab = new DTabWidget(m_central);
+ m_tabs.append(tab);
+ if (tab->closeButton())
+ connect(tab->closeButton(), TQ_SIGNAL(clicked()), this, TQ_SLOT(closeTab()));
+ connect(tab, TQ_SIGNAL(closeRequest(TQWidget*)), this, TQ_SLOT(closeTab(TQWidget*)));
+ connect(tab, TQ_SIGNAL(contextMenu(TQWidget*,const TQPoint &)),
+ this, TQ_SLOT(tabContext(TQWidget*,const TQPoint &)));
+ return tab;
+}
+
+bool DMainWindow::eventFilter(TQObject *obj, TQEvent *ev)
+{
+ TQWidget *w = (TQWidget*)obj;
+ if (!m_widgets.contains(w))
+ return KParts::MainWindow::eventFilter(obj, ev);
+
+ if ((m_currentWidget != w) && (ev->type() == TQEvent::FocusIn))
+ {
+ m_currentWidget = w;
+ emit widgetChanged(w);
+ }
+ else if (ev->type() == TQEvent::IconChange)
+ {
+ if (m_widgetTabs.contains(w))
+ {
+ DTabWidget *tab = m_widgetTabs[w];
+ tab->setTabIconSet(w, w->icon() ? (*(w->icon())) : TQPixmap());
+ }
+ }
+ else if (ev->type() == TQEvent::CaptionChange)
+ {
+ kdDebug(9000) << "caption change" << endl;
+ DTabWidget *tab = m_widgetTabs[w];
+ tab->changeTab(w, w->caption());
+ }
+
+ return KParts::MainWindow::eventFilter(obj, ev);
+}
+
+void DMainWindow::closeTab()
+{
+ //nothing to do here, should be reimplemented
+}
+
+void DMainWindow::tabContext(TQWidget *, const TQPoint &)
+{
+ //nothing to do here, should be reimplemented
+}
+
+void DMainWindow::closeTab(TQWidget *)
+{
+ //nothing to do here, should be reimplemented
+}
+
+void DMainWindow::moveWidget(DDockWindow::Position position, TQWidget * view, const TQString & title)
+{
+ if (m_docks.contains(view))
+ {
+ toolWindow(m_docks[view])->removeWidget(view);
+
+ toolWindow(position)->addWidget( title, view, true );
+ m_docks[view] = position;
+ }
+}
+
+void DMainWindow::addDockWidget(DDockWindow::Position position, TQWidget *view, const TQString &title)
+{
+ DDockWindow* dock = toolWindow(position);
+ dock->addWidget(title, view);
+ m_docks[view] = position;
+ connect(view, TQ_SIGNAL(destroyed()), this, TQ_SLOT(widgetDestroyed()));
+ if (dock->isHidden())
+ dock->show();
+}
+
+void DMainWindow::removeDockWidget(TQWidget *view)
+{
+ DDockWindow* dock = toolWindow(m_docks[view]);
+ dock->removeWidget(view);
+ m_docks.remove(view);
+ if (!dock->hasWidgets())
+ dock->hide();
+}
+
+bool DMainWindow::hasDockWidget(TQWidget *view)
+{
+ return m_docks.contains(view);
+}
+
+DDockWindow::Position DMainWindow::dockWidgetPosition(TQWidget *view)
+{
+ return m_docks[view];
+}
+
+void DMainWindow::widgetDestroyed()
+{
+ TQWidget *w = static_cast<TQWidget*>(const_cast<TQObject*>(sender()));
+
+ if (m_docks.contains(w))
+ {
+ kdError() << "Widget destroyed before being removed from UI!" << endl;
+ m_docks.remove(w);
+ }
+}
+
+#include "dmainwindow.moc"
diff --git a/src/apps/ktorrent/newui/dmainwindow.h b/src/apps/ktorrent/newui/dmainwindow.h
new file mode 100644
index 0000000..7483971
--- /dev/null
+++ b/src/apps/ktorrent/newui/dmainwindow.h
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef DMAINWINDOW_H
+#define DMAINWINDOW_H
+
+#include <kxmlguiclient.h>
+#include <tdeparts/mainwindow.h>
+
+#include "ddockwindow.h"
+
+class DTabWidget;
+namespace Ideal {
+ class DockSplitter;
+}
+
+/**Main window which provides simplified IDEA mode.*/
+class DMainWindow: public KParts::MainWindow {
+ TQ_OBJECT
+
+public:
+ DMainWindow(TQWidget *parent = 0, const char *name = 0);
+ virtual ~DMainWindow();
+
+ /**@return The tool window in given @p position.*/
+ DDockWindow *toolWindow(DDockWindow::Position position) const;
+
+ /**Adds a tabbed widget into the active (focused) tab widget.
+ If @p widget is null then only tab is created.*/
+ virtual void addWidget(TQWidget *widget, const TQString &title);
+ virtual void addWidget(DTabWidget *tab, TQWidget *widget, const TQString &title);
+ /**Removes widget. Does not delete it.*/
+ virtual void removeWidget(TQWidget *widget);
+ /**Moves a widget from an existing dockposition to a new position**/
+ virtual void moveWidget(DDockWindow::Position newPosition, TQWidget *widget, const TQString & title);
+
+ /**Adds a dock widget into given position.*/
+ virtual void addDockWidget(DDockWindow::Position position, TQWidget *view, const TQString &title);
+ /**Removes a dock widget.*/
+ virtual void removeDockWidget(TQWidget *view);
+
+ virtual void saveSettings();
+
+ bool hasDockWidget(TQWidget *view);
+ DDockWindow::Position dockWidgetPosition(TQWidget *view);
+
+public slots:
+ DTabWidget *splitHorizontal();
+ DTabWidget *splitVertical();
+
+protected slots:
+ /**This does nothing. Reimplement in subclass to close the tab
+ when corner close button is pressed.*/
+ virtual void closeTab();
+ /**This does nothing. Reimplement in subclass to close the tab
+ when hover close button is pressed.*/
+ virtual void closeTab(TQWidget*);
+ /**This does nothing. Reimplement in subclass to show tab context menu.*/
+ virtual void tabContext(TQWidget*,const TQPoint &);
+
+ void widgetDestroyed();
+
+signals:
+ void widgetChanged(TQWidget *);
+
+protected:
+ bool eventFilter(TQObject *obj, TQEvent *ev);
+
+ virtual void loadSettings();
+
+ virtual void createToolWindows();
+ virtual DTabWidget *createTab();
+
+ DDockWindow *m_leftDock;
+ DDockWindow *m_rightDock;
+ DDockWindow *m_bottomDock;
+
+ TQMap<TQWidget*, DDockWindow::Position> m_docks;
+
+ Ideal::DockSplitter *m_central;
+ DTabWidget *m_activeTabWidget;
+
+ TQValueList<DTabWidget*> m_tabs;
+
+ bool m_openTabAfterCurrent;
+ bool m_showIconsOnTabs;
+ bool m_firstRemoved;
+
+ TQValueList<TQWidget*> m_widgets;
+ TQMap<TQWidget*, DTabWidget*> m_widgetTabs;
+ TQWidget *m_currentWidget;
+
+private slots:
+ void invalidateActiveTabWidget();
+
+};
+
+#endif
diff --git a/src/apps/ktorrent/newui/docksplitter.cpp b/src/apps/ktorrent/newui/docksplitter.cpp
new file mode 100644
index 0000000..115abf2
--- /dev/null
+++ b/src/apps/ktorrent/newui/docksplitter.cpp
@@ -0,0 +1,175 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "docksplitter.h"
+
+#include <kdebug.h>
+
+namespace Ideal {
+
+DockSplitter::DockSplitter(TQt::Orientation orientation, TQWidget *parent, const char *name)
+ :TQSplitter(parent, name), m_orientation(orientation)
+{
+ switch (m_orientation)
+ {
+ case TQt::Horizontal:
+ setOrientation(TQt::Vertical);
+ break;
+ case TQt::Vertical:
+ setOrientation(TQt::Horizontal);
+ break;
+ }
+ setOpaqueResize(true);
+ appendSplitter();
+}
+
+DockSplitter::~DockSplitter()
+{
+}
+
+void DockSplitter::addDock(uint row, uint col, TQWidget *dock)
+{
+ if (m_docks.count() <= row)
+ for (uint i = m_docks.count(); i <= row ; ++i)
+ m_docks.append(TQValueList<TQWidget*>());
+
+ if (m_docks[row].count() <= col)
+ {
+ for (uint i = m_docks[row].count(); i <= col ; ++i)
+ m_docks[row].append(0);
+ m_docks[row][col] = dock;
+ }
+ else if (m_docks[row][col] == 0)
+ m_docks[row][col] = dock;
+ else
+ m_docks[row].insert(m_docks[row].at(col), dock);
+
+ if (m_splitters.count() <= row)
+ createSplitters(row);
+ TQSplitter *splitter = m_splitters[row];
+
+ dock->reparent(splitter, TQPoint(0,0), true);
+ if (col < m_docks[row].count()-1)
+ shiftWidgets(splitter, row, col+1);
+}
+
+void DockSplitter::appendSplitter()
+{
+ switch (m_orientation)
+ {
+ case TQt::Horizontal:
+ m_splitters.append(new TQSplitter(TQt::Horizontal, this));
+ break;
+ case TQt::Vertical:
+ m_splitters.append(new TQSplitter(TQt::Vertical, this));
+ break;
+ }
+ m_splitters[m_splitters.size()-1]->setOpaqueResize(true);
+ m_splitters[m_splitters.size()-1]->show();
+}
+
+void DockSplitter::createSplitters(uint index)
+{
+ kdDebug(9000) << "DockSplitter::createSplitters index = " << index << " count = " << m_splitters.count() << endl;
+ for (uint i = m_splitters.count(); i <= index; ++i)
+ {
+ kdDebug(9000) << " appendSplitter..." << endl;
+ appendSplitter();
+ }
+}
+
+void DockSplitter::removeDock(uint row, uint col, bool alsoDelete)
+{
+ if ((row >= m_docks.count()) || (col >= m_docks[row].count()))
+ return;
+
+ TQWidget *w = m_docks[row][col];
+ m_docks[row].remove(m_docks[row].at(col));
+
+ if (alsoDelete)
+ {
+ delete w;
+ w = 0;
+ }
+ else
+ {
+ w->reparent(0, TQPoint(0,0), false);
+ w->hide();
+ }
+
+ m_splitters[row]->setMinimumSize(m_splitters[row]->minimumSizeHint());
+
+ if (isRowEmpty(row))
+ {
+ m_docks.remove(m_docks.at(row));
+ delete m_splitters[row];
+ m_splitters[row] = 0;
+ m_splitters.remove(m_splitters.at(row));
+ }
+}
+
+bool DockSplitter::isRowEmpty(int row)
+{
+ if (m_docks[row].count() == 0)
+ return true;
+ for (uint i = 0; i < m_docks[row].count(); ++i)
+ if (m_docks[row][i] != 0)
+ return false;
+ return true;
+}
+
+void DockSplitter::shiftWidgets(TQSplitter *splitter, uint row, uint fromCol)
+{
+ kdDebug(9000) << "shiftWidgets: row=" << row << " from col=" << fromCol << endl;
+ kdDebug(9000) << "row size is: " << m_docks[row].count() << endl;
+
+ for (uint i = fromCol; i < m_docks[row].count(); ++i)
+ {
+ kdDebug(9000) << "move from " << i << " to last" << endl;
+ if (m_docks[row][i])
+ splitter->moveToLast(m_docks[row][i]);
+ else
+ kdDebug(9000) << "m_docks[" << row << "][" << i << "] is 0" << endl;
+ }
+}
+
+int DockSplitter::numRows() const
+{
+ return m_docks.count();
+}
+
+int DockSplitter::numCols(int row) const
+{
+ if (row < numRows())
+ return m_docks[row].count();
+ return 0;
+}
+
+TQPair<uint, uint> DockSplitter::indexOf(TQWidget *dock)
+{
+ for (uint i = 0; i < m_docks.count(); ++i)
+ for (uint j = 0; j < m_docks[i].count(); ++j)
+ if (dock == m_docks[i][j])
+ return qMakePair(i, j);
+ return qMakePair(0u, 0u);
+}
+
+}
+
+#include "docksplitter.moc"
diff --git a/src/apps/ktorrent/newui/docksplitter.h b/src/apps/ktorrent/newui/docksplitter.h
new file mode 100644
index 0000000..3856c4c
--- /dev/null
+++ b/src/apps/ktorrent/newui/docksplitter.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2004 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef IDEALDOCKSPLITTER_H
+#define IDEALDOCKSPLITTER_H
+
+#include <tqsplitter.h>
+#include <tqvaluelist.h>
+
+namespace Ideal {
+
+class DockWidget;
+
+/**
+@short Splitter for docks
+*/
+class DockSplitter: public TQSplitter {
+ TQ_OBJECT
+
+public:
+ DockSplitter(TQt::Orientation orientation, TQWidget *parent = 0, const char *name = 0);
+ ~DockSplitter();
+
+ void addDock(uint row, uint col, TQWidget *dock);
+ void removeDock(uint row, uint col, bool alsoDelete = false);
+
+ TQPair<uint, uint> indexOf(TQWidget *dock);
+
+ int numRows() const;
+ int numCols(int row) const;
+
+protected:
+ void appendSplitter();
+ void createSplitters(uint index);
+ void shiftWidgets(TQSplitter *splitter, uint row, uint fromCol);
+
+ bool isRowEmpty(int row);
+
+private:
+ TQt::Orientation m_orientation;
+ TQValueList<TQSplitter*> m_splitters;
+ TQValueList<TQValueList<TQWidget*> > m_docks;
+};
+
+}
+
+#endif
diff --git a/src/apps/ktorrent/newui/dtabwidget.cpp b/src/apps/ktorrent/newui/dtabwidget.cpp
new file mode 100644
index 0000000..c74e1d6
--- /dev/null
+++ b/src/apps/ktorrent/newui/dtabwidget.cpp
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "dtabwidget.h"
+
+#include <tqtoolbutton.h>
+#include <tqtabbar.h>
+
+#include <tdeconfig.h>
+#include <kiconloader.h>
+#include <tdeapplication.h>
+
+DTabWidget::DTabWidget(TQWidget *parent, const char *name)
+ :KTabWidget(parent, name), m_closeButton(0)
+{
+ setFocusPolicy(TQWidget::NoFocus);
+ setMargin(0);
+
+ loadSettings();
+
+ if (!m_tabBarShown)
+ tabBar()->hide();
+ else {
+ m_closeButton = new TQToolButton(this);
+ m_closeButton->setIconSet(SmallIconSet("tab_remove"));
+ m_closeButton->adjustSize();
+ m_closeButton->hide();
+ setCornerWidget(m_closeButton, TopRight);
+
+ if (m_closeOnHover)
+ setHoverCloseButton(true);
+
+ setTabReorderingEnabled(true);
+ }
+
+ connect(this, TQ_SIGNAL(currentChanged(TQWidget*)), this, TQ_SLOT(setFocus(TQWidget*)));
+// connect(this, TQ_SIGNAL(currentChanged(TQWidget*)), this, TQ_SLOT(updateHistory(TQWidget*)));
+}
+
+void DTabWidget::loadSettings()
+{
+ /*
+ TDEConfig *config = tdeApp->config();
+ config->setGroup("UI");
+// m_tabBarShown = config->readBoolEntry("TabBarShown", true);
+ m_tabBarShown = ! config->readNumEntry("TabWidgetVisibility", 0);
+ m_closeOnHover = config->readBoolEntry("CloseOnHover", false);
+ m_closeButtonShown = config->readBoolEntry("ShowCloseTabsButton", true);
+ //we do not delay hover close buttons - that looks and feels ugly
+ setHoverCloseButtonDelayed(false);
+ */
+ m_tabBarShown = true;
+ m_closeOnHover = false;
+ m_closeButtonShown = true;
+}
+
+void DTabWidget::saveSettings()
+{
+}
+
+TQToolButton *DTabWidget::closeButton() const
+{
+ return m_closeButton;
+}
+
+void DTabWidget::setFocus(TQWidget *w)
+{
+ if (w)
+ w->setFocus();
+}
+
+void DTabWidget::insertTab(TQWidget *child, const TQString &label, int index)
+{
+ if (m_closeButton && m_closeButtonShown)
+ m_closeButton->show();
+ KTabWidget::insertTab(child, label, index);
+ if (index != -1) tabBar()->repaint();
+}
+
+void DTabWidget::insertTab(TQWidget *child, const TQIconSet &iconset,
+ const TQString &label, int index)
+{
+ if (m_closeButton && m_closeButtonShown)
+ m_closeButton->show();
+ KTabWidget::insertTab(child, iconset, label, index);
+ if (index != -1) tabBar()->repaint();
+}
+
+/*void DTabWidget::updateHistory(TQWidget *w)
+{
+ if (m_history.top() != w)
+ m_history.push(w);
+}*/
+
+#include "dtabwidget.moc"
diff --git a/src/apps/ktorrent/newui/dtabwidget.h b/src/apps/ktorrent/newui/dtabwidget.h
new file mode 100644
index 0000000..529a42d
--- /dev/null
+++ b/src/apps/ktorrent/newui/dtabwidget.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Alexander Dymo *
+ * adymo@kdevelop.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library 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 Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef DTABWIDGET_H
+#define DTABWIDGET_H
+
+#include <ktabwidget.h>
+
+class TQToolButton;
+
+class DTabWidget: public KTabWidget {
+ TQ_OBJECT
+
+public:
+ DTabWidget(TQWidget *parent=0, const char *name=0);
+
+ /**@return The close button at the top right corner.
+ May be 0 if the configuration do not allow close buttons or the tabbar.*/
+ TQToolButton *closeButton() const;
+
+ virtual void insertTab(TQWidget *child, const TQString &label, int index = -1 );
+ virtual void insertTab(TQWidget *child, const TQIconSet &iconset,
+ const TQString &label, int index = -1);
+
+protected:
+ virtual void loadSettings();
+ virtual void saveSettings();
+
+private slots:
+ void setFocus(TQWidget *w);
+// void updateHistory(TQWidget *w);
+
+private:
+ bool m_tabBarShown;
+ bool m_closeOnHover;
+ bool m_closeButtonShown;
+
+ TQToolButton *m_closeButton;
+// TQValueStack<TQWidget*> *m_history;
+
+};
+
+#endif
diff --git a/src/apps/ktorrent/pastedialog.cpp b/src/apps/ktorrent/pastedialog.cpp
new file mode 100644
index 0000000..82cf6df
--- /dev/null
+++ b/src/apps/ktorrent/pastedialog.cpp
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * 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 "pastedialog.h"
+#include "ktorrentcore.h"
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include <tqclipboard.h>
+#include <tqapplication.h>
+#include <kurl.h>
+#include <klineedit.h>
+#include <tdemessagebox.h>
+#include <tdelocale.h>
+
+PasteDialog::PasteDialog(KTorrentCore* core, TQWidget *parent, const char *name)
+ :PasteDlgBase(parent, name)
+{
+ m_core = core;
+ TQClipboard *cb = TQApplication::clipboard();
+ TQString text = cb->text(TQClipboard::Clipboard);
+ KURL url = KURL::fromPathOrURL(text);
+ if ( url.isValid() )
+ m_url->setText(url.url());
+
+ btnOK->setGuiItem(KStdGuiItem::ok());
+ btnCancel->setGuiItem(KStdGuiItem::cancel());
+}
+
+void PasteDialog::btnOK_clicked()
+{
+ KURL url = KURL::fromPathOrURL(m_url->text());
+ if ( url.isValid() )
+ {
+ m_core->load(url);
+ TQDialog::accept();
+ }
+ else
+ {
+ KMessageBox::error(this,i18n("Malformed URL."));
+ }
+}
+
+
+
+#include "pastedialog.moc"
diff --git a/src/apps/ktorrent/pastedialog.h b/src/apps/ktorrent/pastedialog.h
new file mode 100644
index 0000000..cb31cd2
--- /dev/null
+++ b/src/apps/ktorrent/pastedialog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * 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. *
+ ***************************************************************************/
+#ifndef PASTEDIALOG_H
+#define PASTEDIALOG_H
+
+#include "pastedlgbase.h"
+class KTorrentCore;
+
+/**
+ * @author Ivan Vasic
+ * @brief Torrent URL paste dialog
+ **/
+class PasteDialog: public PasteDlgBase
+{
+ TQ_OBJECT
+
+public slots:
+ virtual void btnOK_clicked();
+
+ public:
+ PasteDialog(KTorrentCore* core, TQWidget *parent = 0, const char *name = 0);
+
+ private:
+ KTorrentCore* m_core;
+};
+
+#endif
diff --git a/src/apps/ktorrent/pastedlgbase.ui b/src/apps/ktorrent/pastedlgbase.ui
new file mode 100644
index 0000000..4c9539a
--- /dev/null
+++ b/src/apps/ktorrent/pastedlgbase.ui
@@ -0,0 +1,142 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>PasteDlgBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>PasteDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>467</width>
+ <height>84</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>Paste URL</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>URL:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_url</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>297</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnOK</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnCancel</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>btnOK</sender>
+ <signal>clicked()</signal>
+ <receiver>PasteDlgBase</receiver>
+ <slot>btnOK_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>PasteDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>btnOK_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/pref.cpp b/src/apps/ktorrent/pref.cpp
new file mode 100644
index 0000000..da52905
--- /dev/null
+++ b/src/apps/ktorrent/pref.cpp
@@ -0,0 +1,508 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdelocale.h>
+#include <tdestandarddirs.h>
+#include <kactivelabel.h>
+#include <tdeglobal.h>
+#include <kcombobox.h>
+#include <tqlayout.h>
+#include <tqlabel.h>
+#include <tqcheckbox.h>
+#include <knuminput.h>
+#include <kurlrequester.h>
+#include <kurl.h>
+#include <tdefiledialog.h>
+#include <tdemessagebox.h>
+#include <klineedit.h>
+#include <tqlistview.h>
+#include <torrent/globals.h>
+#include <util/functions.h>
+#include <tdeglobal.h>
+#include <kiconloader.h>
+#include <tqdir.h>
+#include <tqslider.h>
+#include <kresolver.h>
+
+#include "downloadpref.h"
+#include "generalpref.h"
+#include "pref.h"
+#include "downloadpref.h"
+#include "advancedpref.h"
+#include "settings.h"
+#include "ktorrent.h"
+
+
+using namespace bt;
+
+using namespace KNetwork;
+
+
+KTorrentPreferences::KTorrentPreferences(KTorrent & ktor)
+ : KDialogBase(IconList, i18n("Preferences"), Help | Ok | Apply | Cancel, Ok), ktor(ktor)
+{
+ validation_err = false;
+ enableButtonSeparator(true);
+
+ page_one = new DownloadPrefPage();
+ page_two = new GeneralPrefPage();
+ page_three = new AdvancedPrefPage();
+ addPrefPage(page_one);
+ addPrefPage(page_two);
+ addPrefPage(page_three);
+}
+
+KTorrentPreferences::~KTorrentPreferences()
+{
+ delete page_one;
+ delete page_two;
+ delete page_three;
+}
+
+void KTorrentPreferences::slotOk()
+{
+ slotApply();
+
+ if (!validation_err)
+ accept();
+}
+
+void KTorrentPreferences::slotApply()
+{
+ validation_err = false;
+ TQMap<kt::PrefPageInterface*, TQFrame*>::iterator i = pages.begin();
+
+ while (i != pages.end())
+ {
+ kt::PrefPageInterface* p = i.key();
+
+ if (!p->apply())
+ {
+ validation_err = true;
+ return;
+ }
+
+ i++;
+ }
+
+ Settings::writeConfig();
+
+ ktor.applySettings(true);
+}
+
+void KTorrentPreferences::updateData()
+{
+ TQMap<kt::PrefPageInterface*, TQFrame*>::iterator i = pages.begin();
+
+ while (i != pages.end())
+ {
+ kt::PrefPageInterface* p = i.key();
+ p->updateData();
+ i++;
+ }
+}
+
+void KTorrentPreferences::addPrefPage(kt::PrefPageInterface* prefInterface)
+{
+ TQFrame* frame = addPage(prefInterface->getItemName(), prefInterface->getHeader(), prefInterface->getPixmap());
+ TQVBoxLayout* vbox = new TQVBoxLayout(frame);
+ vbox->setAutoAdd(true);
+ prefInterface->createWidget(frame);
+
+ pages.insert(prefInterface, frame);
+}
+
+void KTorrentPreferences::removePrefPage(kt::PrefPageInterface* pp)
+{
+ if (!pages.contains(pp))
+ return;
+
+ TQFrame* fr = pages[pp];
+
+ pages.remove(pp);
+
+ pp->deleteWidget();
+
+ delete fr;
+}
+
+///////////////////////////////////////////////////////
+
+DownloadPrefPage::DownloadPrefPage() : kt::PrefPageInterface(i18n("Downloads"), i18n("Download Options"), TDEGlobal::iconLoader()->loadIcon("go-down", TDEIcon::NoGroup)), dp(0)
+{}
+
+DownloadPrefPage::~ DownloadPrefPage()
+{
+ delete dp;
+}
+
+void DownloadPrefPage::createWidget(TQWidget* parent)
+{
+ dp = new DownloadPref(parent);
+ updateData();
+}
+
+bool DownloadPrefPage::apply()
+{
+ Settings::setMaxDownloads(dp->max_downloads->value());
+ Settings::setMaxSeeds(dp->max_seeds->value());
+ Settings::setStartDownloadsOnLowDiskSpace(dp->cmbDiskSpace->currentItem());
+ Settings::setMaxConnections(dp->max_conns->value());
+ Settings::setMaxTotalConnections(dp->max_total_conns->value());
+ Settings::setMaxUploadRate(dp->max_upload_rate->value());
+ Settings::setMaxDownloadRate(dp->max_download_rate->value());
+ Settings::setMaxRatio(dp->num_max_ratio->value());
+ Settings::setKeepSeeding(dp->keep_seeding->isChecked());
+ Settings::setPort(dp->port->value());
+ Settings::setNumUploadSlots(dp->num_upload_slots->value());
+ Settings::setMinDiskSpace(dp->intMinDiskSpace->value());
+ Settings::setMaxSeedTime(dp->max_seed_time->value());
+
+ if (Settings::dhtSupport() && dp->udp_tracker_port->value() == Settings::dhtPort())
+ {
+ TQString msg = i18n("The DHT port needs to be different from the UDP tracker port!");
+ KMessageBox::error(0, msg, i18n("Error"));
+ return false;
+ }
+
+ Settings::setUdpTrackerPort(dp->udp_tracker_port->value());
+
+ return true;
+}
+
+void DownloadPrefPage::updateData()
+{
+ //setMinimumSize(400,400);
+ dp->max_downloads->setValue(Settings::maxDownloads());
+ dp->max_seeds->setValue(Settings::maxSeeds());
+ dp->cmbDiskSpace->setCurrentItem(Settings::startDownloadsOnLowDiskSpace());
+ dp->max_conns->setValue(Settings::maxConnections());
+ dp->max_total_conns->setValue(Settings::maxTotalConnections());
+ dp->max_upload_rate->setValue(Settings::maxUploadRate());
+ dp->max_download_rate->setValue(Settings::maxDownloadRate());
+ dp->num_max_ratio->setValue(Settings::maxRatio());
+ dp->keep_seeding->setChecked(Settings::keepSeeding());
+ dp->udp_tracker_port->setValue(Settings::udpTrackerPort());
+ dp->port->setValue(Settings::port());
+ dp->num_upload_slots->setValue(Settings::numUploadSlots());
+ dp->intMinDiskSpace->setValue(Settings::minDiskSpace());
+ dp->max_seed_time->setValue(Settings::maxSeedTime());
+}
+
+void DownloadPrefPage::deleteWidget()
+{
+ delete dp;
+ dp = 0;
+}
+
+//////////////////////////////////////
+GeneralPrefPage::GeneralPrefPage() :
+ kt::PrefPageInterface(i18n("General"), i18n("General Options"),
+ TDEGlobal::iconLoader()->loadIcon("package_settings", TDEIcon::NoGroup)), gp(0)
+{}
+
+GeneralPrefPage::~GeneralPrefPage()
+{
+ delete gp;
+}
+
+void GeneralPrefPage::createWidget(TQWidget* parent)
+{
+ gp = new GeneralPref(parent);
+ updateData();
+ connect(gp->custom_ip_check, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(customIPChecked(bool)));
+ connect(gp->use_dht, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(dhtChecked(bool)));
+ connect(gp->use_encryption, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(useEncryptionChecked(bool)));
+}
+
+bool GeneralPrefPage::apply()
+{
+ Settings::setShowSystemTrayIcon(gp->show_systray_icon->isChecked());
+ Settings::setShowSpeedBarInTrayIcon(gp->show_speedbar->isChecked());
+ Settings::setDownloadBandwidth(gp->downloadBandwidth->value());
+ Settings::setUploadBandwidth(gp->uploadBandwidth->value());
+ Settings::setShowPopups(gp->show_popups->isChecked());
+ TQString ourl = Settings::tempDir();
+
+ KURLRequester* u = gp->temp_dir;
+
+ if (ourl != u->url())
+ {
+ Settings::setTempDir(u->url());
+ }
+
+ Settings::setSaveDir(gp->autosave_location->url());
+
+ bool useSaveDir = gp->autosave_downloads_check->isChecked();
+ Settings::setUseSaveDir(useSaveDir);
+
+ //check completed dir
+ Settings::setCompletedDir(gp->urlCompletedDir->url());
+
+ bool useCompletedDir = gp->checkCompletedDir->isChecked();
+ Settings::setUseCompletedDir(useCompletedDir);
+
+ //.torrent copy dir
+ bool useTorrentCopyDir = gp->checkTorrentDir->isChecked();
+ Settings::setUseTorrentCopyDir(useTorrentCopyDir);
+ Settings::setTorrentCopyDir(gp->urlTorrentDir->url());
+
+ bool useExternalIP = gp->custom_ip_check->isChecked();
+
+ Settings::setUseExternalIP(useExternalIP);
+ TQString externalIP = gp->custom_ip->text();
+ Settings::setExternalIP(externalIP);
+
+ if (useExternalIP)
+ {
+
+ KResolverResults res = KResolver::resolve(externalIP, TQString());
+
+ if (res.error())
+ {
+ TQString err = KResolver::errorString(res.error());
+ TQString msg = i18n("Cannot lookup %1: %2\n"
+ "Please provide a valid IP address or hostname.").arg(externalIP).arg(err);
+ KMessageBox::error(0, msg, i18n("Error"));
+ return false;
+ }
+ }
+
+
+
+ if (gp->use_dht->isChecked() && gp->dht_port->value() == Settings::udpTrackerPort())
+ {
+ TQString msg = i18n("The DHT port needs to be different from the UDP tracker port!");
+ KMessageBox::error(0, msg, i18n("Error"));
+ return false;
+ }
+
+ Settings::setDhtSupport(gp->use_dht->isChecked());
+
+ Settings::setDhtPort(gp->dht_port->value());
+ Settings::setUseEncryption(gp->use_encryption->isChecked());
+ Settings::setAllowUnencryptedConnections(gp->allow_unencrypted->isChecked());
+ return true;
+}
+
+void GeneralPrefPage::useEncryptionChecked(bool on)
+{
+ gp->allow_unencrypted->setEnabled(on);
+}
+
+void GeneralPrefPage::autosaveChecked(bool on)
+{
+ gp->autosave_location->setEnabled(on);
+}
+
+void GeneralPrefPage::customIPChecked(bool on)
+{
+ gp->custom_ip->setEnabled(on);
+ gp->custom_ip_label->setEnabled(on);
+}
+
+void GeneralPrefPage::dhtChecked(bool on)
+{
+ gp->dht_port->setEnabled(on);
+ gp->dht_port_label->setEnabled(on);
+}
+
+void GeneralPrefPage::updateData()
+{
+ gp->show_systray_icon->setChecked(Settings::showSystemTrayIcon());
+ gp->show_speedbar->setChecked(Settings::showSpeedBarInTrayIcon());
+ gp->downloadBandwidth->setValue(Settings::downloadBandwidth());
+ gp->uploadBandwidth->setValue(Settings::uploadBandwidth());
+ gp->show_popups->setChecked(Settings::showPopups());
+ KURLRequester* u = gp->temp_dir;
+ u->fileDialog()->setMode(KFile::Directory);
+
+ if (Settings::tempDir() == TQString())
+ {
+ TQString data_dir = TDEGlobal::dirs()->saveLocation("data", "ktorrent");
+
+ if (!data_dir.endsWith(bt::DirSeparator()))
+ data_dir += bt::DirSeparator();
+
+ u->setURL(data_dir);
+ }
+ else
+ {
+ u->setURL(Settings::tempDir());
+ }
+
+ u = gp->autosave_location;
+
+ u->fileDialog()->setMode(KFile::Directory);
+
+ bool useSaveDir = Settings::useSaveDir();
+ TQString saveDir = Settings::saveDir();
+
+ gp->autosave_downloads_check->setChecked(useSaveDir);
+ u->setEnabled(useSaveDir);
+
+ u->setURL(!saveDir.isEmpty() ? saveDir : TQDir::homeDirPath());
+
+
+ //completed dir
+ u = gp->urlCompletedDir;
+ u->fileDialog()->setMode(KFile::Directory);
+ bool useCompletedDir = Settings::useCompletedDir();
+ TQString completedDir = Settings::completedDir();
+ gp->checkCompletedDir->setChecked(useCompletedDir);
+ u->setEnabled(useCompletedDir);
+ u->setURL(!completedDir.isEmpty() ? completedDir : TQDir::homeDirPath());
+
+ //copy .torrent dir
+ u = gp->urlTorrentDir;
+ u->fileDialog()->setMode(KFile::Directory);
+ bool useTorrentDir = Settings::useTorrentCopyDir();
+ TQString torrentDir = Settings::torrentCopyDir();
+ gp->checkTorrentDir->setChecked(useTorrentDir);
+ u->setEnabled(useTorrentDir);
+ u->setURL(!torrentDir.isEmpty() ? torrentDir : TQDir::homeDirPath());
+
+
+ gp->custom_ip->setText(Settings::externalIP());
+
+ bool useExternalIP = Settings::useExternalIP();
+ gp->custom_ip_check->setChecked(useExternalIP);
+ gp->custom_ip->setEnabled(useExternalIP);
+ gp->custom_ip_label->setEnabled(useExternalIP);
+
+ gp->use_dht->setChecked(Settings::dhtSupport());
+ gp->dht_port->setValue(Settings::dhtPort());
+ gp->dht_port->setEnabled(Settings::dhtSupport());
+ gp->dht_port_label->setEnabled(Settings::dhtSupport());
+
+ gp->use_encryption->setChecked(Settings::useEncryption());
+ gp->allow_unencrypted->setChecked(Settings::allowUnencryptedConnections());
+ gp->allow_unencrypted->setEnabled(Settings::useEncryption());
+}
+
+void GeneralPrefPage::deleteWidget()
+{
+ delete gp;
+ gp = 0;
+}
+
+/////////////////////////////////
+
+AdvancedPrefPage::AdvancedPrefPage() :
+ kt::PrefPageInterface(i18n("Advanced"), i18n("Advanced Options"),
+ TDEGlobal::iconLoader()->loadIcon("package_settings", TDEIcon::NoGroup)), ap(0)
+{}
+
+AdvancedPrefPage::~AdvancedPrefPage()
+{
+ delete ap;
+}
+
+bool AdvancedPrefPage::apply()
+{
+ Settings::setMemoryUsage(ap->mem_usage->currentItem());
+ Settings::setGuiUpdateInterval(ap->gui_interval->currentItem());
+ Settings::setDSCP(ap->dscp->value());
+ Settings::setAllwaysDoUploadDataCheck(!ap->no_recheck->isChecked());
+ Settings::setMaxSizeForUploadDataCheck(ap->recheck_size->value());
+ Settings::setAutoRecheck(ap->auto_recheck->isChecked());
+ Settings::setMaxCorruptedBeforeRecheck(ap->num_corrupted->value());
+ Settings::setDoNotUseKDEProxy(ap->do_not_use_kde_proxy->isChecked());
+ Settings::setHttpTrackerProxy(ap->http_proxy->text());
+ Settings::setEta(ap->eta->currentItem());
+ Settings::setFullDiskPrealloc(ap->full_prealloc->isChecked());
+ Settings::setFullDiskPreallocMethod(ap->full_prealloc_method->currentItem());
+ Settings::setCpuUsage(ap->cpu_usage->value());
+ Settings::setDiskPrealloc(!ap->prealloc_disabled->isChecked());
+ Settings::setMaxConnectingSockets(ap->max_con_setups->value());
+ return true;
+}
+
+void AdvancedPrefPage::updateData()
+{
+ ap->mem_usage->setCurrentItem(Settings::memoryUsage());
+ ap->gui_interval->setCurrentItem(Settings::guiUpdateInterval());
+ ap->dscp->setValue(Settings::dSCP());
+ ap->no_recheck->setChecked(!Settings::allwaysDoUploadDataCheck());
+ ap->recheck_size->setEnabled(!Settings::allwaysDoUploadDataCheck());
+ ap->recheck_size->setValue(Settings::maxSizeForUploadDataCheck());
+ ap->auto_recheck->setChecked(Settings::autoRecheck());
+ ap->num_corrupted->setValue(Settings::maxCorruptedBeforeRecheck());
+ ap->num_corrupted->setEnabled(Settings::autoRecheck());
+ ap->do_not_use_kde_proxy->setChecked(Settings::doNotUseKDEProxy());
+ ap->http_proxy->setText(Settings::httpTrackerProxy());
+ ap->http_proxy->setEnabled(Settings::doNotUseKDEProxy());
+ ap->eta->setCurrentItem(Settings::eta());
+ ap->full_prealloc->setChecked(Settings::fullDiskPrealloc());
+ ap->full_prealloc_method->setCurrentItem(Settings::fullDiskPreallocMethod());
+ ap->cpu_usage->setValue(Settings::cpuUsage());
+ ap->prealloc_disabled->setChecked(!Settings::diskPrealloc());
+ ap->max_con_setups->setValue(Settings::maxConnectingSockets());
+}
+
+void AdvancedPrefPage::createWidget(TQWidget* parent)
+{
+ ap = new AdvancedPref(parent);
+ updateData();
+ connect(ap->no_recheck, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(noDataCheckChecked(bool)));
+ connect(ap->auto_recheck, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(autoRecheckChecked(bool)));
+ connect(ap->do_not_use_kde_proxy, TQ_SIGNAL(toggled(bool)),
+ this, TQ_SLOT(doNotUseKDEProxyChecked(bool)));
+ connect(ap->prealloc_disabled,TQ_SIGNAL(toggled(bool)),
+ this,TQ_SLOT(preallocDisabledChecked(bool)));
+
+ preallocDisabledChecked(ap->prealloc_disabled->isChecked());
+}
+
+void AdvancedPrefPage::deleteWidget()
+{
+ delete ap;
+ ap = 0;
+}
+
+void AdvancedPrefPage::noDataCheckChecked(bool on)
+{
+ ap->recheck_size->setEnabled(on);
+}
+
+void AdvancedPrefPage::autoRecheckChecked(bool on)
+{
+ ap->num_corrupted->setEnabled(on);
+}
+
+void AdvancedPrefPage::doNotUseKDEProxyChecked(bool on)
+{
+ ap->http_proxy->setEnabled(on);
+}
+
+void AdvancedPrefPage::preallocDisabledChecked(bool on)
+{
+ ap->full_prealloc->setEnabled(!on);
+ if (!on && ap->full_prealloc->isChecked())
+ ap->full_prealloc_method->setEnabled(true);
+ else
+ ap->full_prealloc_method->setEnabled(false);
+}
+
+#include "pref.moc"
diff --git a/src/apps/ktorrent/pref.h b/src/apps/ktorrent/pref.h
new file mode 100644
index 0000000..f9a4331
--- /dev/null
+++ b/src/apps/ktorrent/pref.h
@@ -0,0 +1,124 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+
+
+#ifndef _KTORRENTPREF_H_
+#define _KTORRENTPREF_H_
+
+#include <kdialogbase.h>
+#include <tqframe.h>
+#include <tqmap.h>
+#include <interfaces/prefpageinterface.h>
+
+
+class DownloadPref;
+class GeneralPref;
+class AdvancedPref;
+class KTorrent;
+class TQListViewItem;
+
+
+class DownloadPrefPage : public kt::PrefPageInterface
+{
+ DownloadPref* dp;
+public:
+ DownloadPrefPage();
+ virtual ~DownloadPrefPage();
+
+ virtual bool apply();
+ virtual void updateData();
+ virtual void createWidget(TQWidget* parent);
+ virtual void deleteWidget();
+};
+
+class GeneralPrefPage : public TQObject,public kt::PrefPageInterface
+{
+ TQ_OBJECT
+
+ GeneralPref* gp;
+public:
+ GeneralPrefPage();
+ virtual ~GeneralPrefPage();
+
+ virtual bool apply();
+ virtual void updateData();
+ virtual void createWidget(TQWidget* parent);
+ virtual void deleteWidget();
+
+private slots:
+ void autosaveChecked(bool on);
+ void customIPChecked(bool on);
+ void dhtChecked(bool on);
+ void useEncryptionChecked(bool on);
+};
+
+class AdvancedPrefPage : public TQObject,public kt::PrefPageInterface
+{
+ TQ_OBJECT
+
+
+ AdvancedPref* ap;
+public:
+ AdvancedPrefPage();
+ virtual ~AdvancedPrefPage();
+
+ virtual bool apply();
+ virtual void updateData();
+ virtual void createWidget(TQWidget* parent);
+ virtual void deleteWidget();
+
+private slots:
+ void noDataCheckChecked(bool on);
+ void autoRecheckChecked(bool on);
+ void doNotUseKDEProxyChecked(bool on);
+ void preallocDisabledChecked(bool on);
+};
+
+
+class KTorrentPreferences : public KDialogBase
+{
+ TQ_OBJECT
+
+public:
+ KTorrentPreferences(KTorrent & ktor);
+ virtual ~KTorrentPreferences();
+
+ void updateData();
+ void addPrefPage(kt::PrefPageInterface* prefInterface);
+ void removePrefPage(kt::PrefPageInterface* prefInterface);
+private:
+ virtual void slotOk();
+ virtual void slotApply();
+
+
+private:
+ KTorrent & ktor;
+ DownloadPrefPage* page_one;
+ GeneralPrefPage* page_two;
+ AdvancedPrefPage* page_three;
+ TQMap<kt::PrefPageInterface*,TQFrame*> pages;
+ bool validation_err;
+};
+
+
+
+
+
+#endif // _KTORRENTPREF_H_
diff --git a/src/apps/ktorrent/queuedialog.cpp b/src/apps/ktorrent/queuedialog.cpp
new file mode 100644
index 0000000..69bb1ea
--- /dev/null
+++ b/src/apps/ktorrent/queuedialog.cpp
@@ -0,0 +1,391 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Ivan Vasić *
+ * 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 "queuedialog.h"
+#include <interfaces/torrentinterface.h>
+#include <interfaces/functions.h>
+#include <torrent/queuemanager.h>
+
+#include <tqlistview.h>
+#include <tqstring.h>
+#include <tqmessagebox.h>
+#include <tqptrlist.h>
+#include <tqlabel.h>
+#include <tqtabwidget.h>
+#include <tqgroupbox.h>
+#include <tqpushbutton.h>
+#include <tqlayout.h>
+
+#include <tdelocale.h>
+#include <tdeglobal.h>
+#include <kurl.h>
+#include <kiconloader.h>
+#include <ksqueezedtextlabel.h>
+#include <ktabwidget.h>
+#include <kpushbutton.h>
+#include <kiconloader.h>
+
+using namespace bt;
+using namespace kt;
+
+QueueItem::QueueItem(kt::TorrentInterface* t, TQListView* parent)
+ :TQListViewItem(parent), tc(t)
+{
+ setPriority(tc->getPriority());
+ setText(0, TQString(tc->getStats().torrent_name));
+}
+
+int QueueItem::compare(TQListViewItem *i, int , bool ) const
+{
+ QueueItem* it = (QueueItem*) i;
+ if(it->getPriority() == torrentPriority)
+ {
+ const TorrentInterface* ti = it->getTC();
+ TQString name1 = tc->getStats().torrent_name;
+ TQString name2 = ti->getStats().torrent_name;
+ return name1.compare(name2);
+ }
+
+ return it->getPriority() < torrentPriority ? -1 : 1;
+}
+
+void QueueItem::setPriority(int p)
+{
+ torrentPriority = p;
+
+ if(p==0)
+ setText(1, i18n("User"));
+ else
+ setText(1, i18n("Queue Manager"));
+}
+
+void QueueItem::setTorrentPriority(int p)
+{
+ tc->setPriority(p);
+}
+
+void QueueItem::paintCell(TQPainter* p,const TQColorGroup & cg,int column,int width,int align)
+{
+ TQColorGroup colorGrp( cg );
+ TQColor txt = colorGrp.text();
+
+ //if (column == 1)
+ if(torrentPriority == 0)
+ colorGrp.setColor(TQColorGroup::Text, TQt::gray);
+ else
+ colorGrp.setColor(TQColorGroup::Text, txt);
+
+
+ TQListViewItem::paintCell(p,colorGrp,column,width,align);
+}
+
+QueueDialog::QueueDialog(bt::QueueManager* qm, TQWidget *parent, const char *name)
+ :QueueDlg(parent, name)
+{
+ TDEIconLoader* iload = TDEGlobal::iconLoader();
+
+ m_tabs->setTabIconSet(m_tabs->page(0), iload->loadIconSet("go-down", TDEIcon::Small));
+ m_tabs->setTabIconSet(m_tabs->page(1), iload->loadIconSet("go-up", TDEIcon::Small));
+
+ logo->setPixmap(iload->loadIcon("ktqueuemanager", TDEIcon::Desktop));
+
+ connect(downloadList, TQ_SIGNAL(selectionChanged(TQListViewItem*)), this, TQ_SLOT(downloadList_currentChanged( TQListViewItem* )));
+ connect(seedList, TQ_SIGNAL(selectionChanged(TQListViewItem*)), this, TQ_SLOT(seedList_currentChanged( TQListViewItem* )));
+
+ if(downloadList->firstChild())
+ downloadList->setCurrentItem(downloadList->firstChild());
+
+ if(seedList->firstChild())
+ seedList->setCurrentItem(seedList->firstChild());
+
+ btnMoveUp->setPixmap(iload->loadIcon("go-up", TDEIcon::Small));
+ btnMoveDown->setPixmap(iload->loadIcon("go-down", TDEIcon::Small));
+
+ this->qman = qm;
+
+ TQPtrList<kt::TorrentInterface>::iterator it = qman->begin();
+ for( ; it != qman->end(); ++it)
+ {
+ TorrentInterface* tc = *it;
+ TorrentStatus ts = tc->getStats().status;
+
+ if(ts == kt::SEEDING || ts == kt::DOWNLOAD_COMPLETE ||
+ ts == kt::SEEDING_COMPLETE || tc->getStats().completed)
+ {
+ QueueItem* item = new QueueItem(tc, seedList);
+ seedList->insertItem(item);
+ }
+ else
+ {
+ QueueItem* item = new QueueItem(tc, downloadList);
+ downloadList->insertItem(item);
+ }
+ }
+}
+
+void QueueDialog::btnMoveUp_clicked()
+{
+ QueueItem* current = (QueueItem*) getCurrentList()->selectedItem();
+ if(current == 0)
+ return;
+
+ if(current->getPriority() == 0)
+ return;
+
+ QueueItem* previous = (QueueItem*) current->itemAbove();
+ if(previous == 0)
+ return;
+ else
+ {
+ int tmp = previous->getPriority();
+ previous->setPriority(current->getPriority());
+ current->setPriority(tmp);
+ getCurrentList()->sort();
+ }
+}
+
+void QueueDialog::btnMoveDown_clicked()
+{
+ QueueItem* current = (QueueItem*) getCurrentList()->selectedItem();
+ if(current == 0)
+ return;
+
+ if(current->getPriority() == 0)
+ return;
+
+ QueueItem* previous = (QueueItem*) current->itemBelow();
+ if(previous == 0)
+ return;
+ else
+ {
+ int tmp = previous->getPriority();
+ if(tmp == 0)
+ return;
+ previous->setPriority(current->getPriority());
+ current->setPriority(tmp);
+ getCurrentList()->sort();
+ }
+}
+
+void QueueDialog::btnClose_clicked()
+{
+ this->close();
+}
+
+void QueueDialog::btnEnqueue_clicked()
+{
+ enqueue();
+}
+
+void QueueDialog::btnDequeue_clicked()
+{
+ QueueItem* current = (QueueItem*) getCurrentList()->selectedItem();
+ if(current == 0)
+ return;
+ if(current->getPriority() == 0)
+ return;
+
+ current->setPriority(0);
+ getCurrentList()->sort();
+}
+
+void QueueDialog::enqueue(QueueItem* curr)
+{
+ QueueItem* current = curr == 0 ? (QueueItem*) getCurrentList()->selectedItem() : curr;
+ if(current == 0)
+ return;
+ if(current->getPriority() != 0)
+ return;
+
+ QueueItem* item = (QueueItem*) getCurrentList()->firstChild();
+ if(item == 0)
+ return;
+
+ while(item != 0)
+ {
+ if(item->getPriority() != 0)
+ item->setPriority(item->getPriority() + 1);
+ item = (QueueItem*) item->itemBelow();
+ }
+
+ current->setPriority(1);
+ getCurrentList()->sort();
+}
+
+void QueueDialog::writeQueue()
+{
+ downloadList->sort();
+ seedList->sort();
+
+ int p = 0;
+
+ QueueItem* item = (QueueItem*) downloadList->lastItem();
+ if(item != 0)
+ {
+ while(item != 0)
+ {
+ if(item->getPriority() != 0)
+ item->setTorrentPriority(++p);
+ else
+ item->setTorrentPriority(0);
+ item = (QueueItem*) item->itemAbove();
+ }
+ }
+
+ item = (QueueItem*) seedList->lastItem();
+ if(item == 0)
+ {
+ qman->orderQueue();
+ return;
+ }
+
+ p = 0;
+
+ while(item != 0)
+ {
+ if(item->getPriority() != 0)
+ item->setTorrentPriority(++p);
+ else
+ item->setTorrentPriority(0);
+ item = (QueueItem*) item->itemAbove();
+ }
+ qman->orderQueue();
+}
+
+void QueueDialog::btnApply_clicked()
+{
+ writeQueue();
+}
+
+void QueueDialog::btnOk_clicked()
+{
+ writeQueue();
+ this->close();
+}
+
+TQListView* QueueDialog::getCurrentList()
+{
+ return m_tabs->currentPageIndex() == 0 ? downloadList : seedList;
+}
+
+void QueueDialog::downloadList_currentChanged(TQListViewItem* item)
+{
+ if(!item)
+ {
+ dlStatus->clear();
+ dlTracker->clear();
+ dlRatio->clear();
+ dlDHT->clear();
+ return;
+ }
+
+ const TorrentInterface* tc = ((QueueItem*)item)->getTC();
+ TorrentStats s = tc->getStats();
+
+ dlStatus->setText(tc->statusToString());
+ dlTracker->setText(tc->getTrackersList()->getTrackerURL().prettyURL());
+ dlRatio->setText(TQString("%1").arg((float)s.bytes_uploaded / s.bytes_downloaded,0,'f',2));
+ dlBytes->setText(BytesToString(s.bytes_left_to_download));
+ dlDHT->setText(s.priv_torrent ? i18n("No (private torrent)") : i18n("Yes"));
+}
+
+void QueueDialog::seedList_currentChanged(TQListViewItem* item)
+{
+ if(!item)
+ {
+ ulStatus->clear();
+ ulTracker->clear();
+ ulRatio->clear();
+ ulDHT->clear();
+ return;
+ }
+
+ const TorrentInterface* tc = ((QueueItem*)item)->getTC();
+ TorrentStats s = tc->getStats();
+
+ ulStatus->setText(tc->statusToString());
+ ulTracker->setText(tc->getTrackersList()->getTrackerURL().prettyURL());
+ ulRatio->setText(TQString("%1").arg((float)s.bytes_uploaded / s.bytes_downloaded,0,'f',2));
+ ulBytes->setText(BytesToString(s.bytes_uploaded));
+ ulDHT->setText(s.priv_torrent ? i18n("No (private torrent)") : i18n("Yes"));
+}
+
+void QueueDialog::btnMoveTop_clicked()
+{
+ QueueItem* current = (QueueItem*) getCurrentList()->selectedItem();
+ if(current == 0)
+ return;
+
+ if(current->getPriority() == 0)
+ return;
+
+ QueueItem* previous = (QueueItem*) current->itemAbove();
+
+ if(previous == 0)
+ return;
+
+ int p = previous->getPriority();
+
+ while(previous != 0)
+ {
+ p = previous->getPriority();
+ previous->setPriority(p - 1);
+
+ previous = (QueueItem*) previous->itemAbove();
+ }
+
+ current->setPriority(p);
+ getCurrentList()->sort();
+}
+
+void QueueDialog::btnMoveBottom_clicked()
+{
+ QueueItem* current = (QueueItem*) getCurrentList()->selectedItem();
+ if(current == 0)
+ return;
+
+ if(current->getPriority() == 0)
+ return;
+
+ QueueItem* previous = (QueueItem*) current->itemBelow();
+
+ if(previous == 0)
+ return;
+
+ if(previous->getPriority() == 0)
+ return;
+
+ int p = previous->getPriority();
+
+ while(previous != 0 && previous->getPriority() != 0)
+ {
+ p = previous->getPriority();
+ previous->setPriority(p + 1);
+
+ previous = (QueueItem*) previous->itemBelow();
+ }
+
+ current->setPriority(p);
+ getCurrentList()->sort();
+}
+
+
+
+#include "queuedialog.moc"
+
diff --git a/src/apps/ktorrent/queuedialog.h b/src/apps/ktorrent/queuedialog.h
new file mode 100644
index 0000000..ae8629c
--- /dev/null
+++ b/src/apps/ktorrent/queuedialog.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Ivan Vasić *
+ * 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. *
+ ***************************************************************************/
+#ifndef QUEUEDIALOG_H
+#define QUEUEDIALOG_H
+
+#include "queuedlg.h"
+#include <interfaces/torrentinterface.h>
+#include <torrent/queuemanager.h>
+
+#include <tqlistview.h>
+#include <tqstring.h>
+
+class QueueItem: public TQListViewItem
+{
+ public:
+ QueueItem(kt::TorrentInterface* t, TQListView* parent);
+
+ int getPriority() { return torrentPriority; }
+ void setPriority(int p);
+ int compare(TQListViewItem *i, int col, bool ascending ) const;
+
+ void setTorrentPriority(int p);
+
+ const kt::TorrentInterface* getTC() { return tc; }
+
+ private:
+ //void updatePriorities(QueueItem* to, bool from_end, int val);
+ void paintCell(TQPainter* p,const TQColorGroup & cg,int column,int width,int align);
+
+ kt::TorrentInterface* tc;
+ int torrentPriority;
+};
+
+class QueueDialog: public QueueDlg
+{
+ TQ_OBJECT
+
+ public:
+ QueueDialog(bt::QueueManager* qm, TQWidget *parent = 0, const char *name = 0);
+ public slots:
+ virtual void btnMoveUp_clicked();
+ virtual void btnClose_clicked();
+ virtual void btnMoveDown_clicked();
+ virtual void btnDequeue_clicked();
+ virtual void btnEnqueue_clicked();
+ virtual void btnApply_clicked();
+ virtual void btnOk_clicked();
+ virtual void seedList_currentChanged(TQListViewItem*);
+ virtual void downloadList_currentChanged(TQListViewItem*);
+ virtual void btnMoveBottom_clicked();
+ virtual void btnMoveTop_clicked();
+
+
+ private:
+ ///Enqueue item curr
+ void enqueue(QueueItem* curr = 0);
+
+ ///Writes the queue order into QueueManager
+ void writeQueue();
+
+ ///Gets the pointer to currently visible torrentList (download or seed)
+ TQListView* getCurrentList();
+
+ bt::QueueManager* qman;
+};
+
+#endif
diff --git a/src/apps/ktorrent/queuedlg.ui b/src/apps/ktorrent/queuedlg.ui
new file mode 100644
index 0000000..9bd5532
--- /dev/null
+++ b/src/apps/ktorrent/queuedlg.ui
@@ -0,0 +1,720 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>QueueDlg</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>QueueDlg</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>631</width>
+ <height>482</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>KT Queue Dialog</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>m_tabs</cstring>
+ </property>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Downloads</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>InfoDownload</cstring>
+ </property>
+ <property name="title">
+ <string>Info</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout25</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Status:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Tracker:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>DHT:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Share ratio:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Bytes left:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout26</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>dlStatus</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KSqueezedTextLabel">
+ <property name="name">
+ <cstring>dlTracker</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>dlDHT</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>dlRatio</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>dlBytes</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQListView" row="0" column="0">
+ <column>
+ <property name="text">
+ <string>Torrent</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Controlled by</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>downloadList</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>Upload&amp;s</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQListView" row="0" column="0">
+ <column>
+ <property name="text">
+ <string>Torrent</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Controlled by</string>
+ </property>
+ <property name="clickable">
+ <bool>false</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>seedList</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="TQGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>InfoSeed</cstring>
+ </property>
+ <property name="title">
+ <string>Info</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout15</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Status:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Tracker:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_4_2</cstring>
+ </property>
+ <property name="text">
+ <string>DHT:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Share ratio:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Uploaded:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout27</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>ulStatus</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KSqueezedTextLabel">
+ <property name="name">
+ <cstring>ulTracker</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>ulDHT</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>ulRatio</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>ulBytes</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout49</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer28</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>logo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer29</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnMoveUp</cstring>
+ </property>
+ <property name="text">
+ <string>M&amp;ove up</string>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnMoveDown</cstring>
+ </property>
+ <property name="text">
+ <string>Move dow&amp;n</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnMoveTop</cstring>
+ </property>
+ <property name="text">
+ <string>Move to top</string>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnMoveBottom</cstring>
+ </property>
+ <property name="text">
+ <string>Move to &amp;bottom</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnEnqueue</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;QM Controlled</string>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>btnDequeue</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;User Controlled</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnApply</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Apply</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>9</number>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>btnClose</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>2</number>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="4833">789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>btnMoveUp</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnMoveUp_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnMoveDown</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnMoveDown_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnEnqueue</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnEnqueue_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnDequeue</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnDequeue_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>downloadList</sender>
+ <signal>currentChanged(TQListViewItem*)</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>downloadList_currentChanged(TQListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>seedList</sender>
+ <signal>currentChanged(TQListViewItem*)</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>seedList_currentChanged(TQListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>btnOk</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnOk_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnApply</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnApply_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnClose</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>btnMoveTop</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnMoveTop_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnMoveBottom</sender>
+ <signal>clicked()</signal>
+ <receiver>QueueDlg</receiver>
+ <slot>btnMoveBottom_clicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>btnOk</tabstop>
+ <tabstop>btnApply</tabstop>
+ <tabstop>btnClose</tabstop>
+ <tabstop>m_tabs</tabstop>
+ <tabstop>downloadList</tabstop>
+ <tabstop>btnMoveUp</tabstop>
+ <tabstop>btnMoveDown</tabstop>
+ <tabstop>btnEnqueue</tabstop>
+ <tabstop>btnDequeue</tabstop>
+ <tabstop>seedList</tabstop>
+</tabstops>
+<slots>
+ <slot>btnMoveUp_clicked()</slot>
+ <slot>btnMoveDown_clicked()</slot>
+ <slot>btnEnqueue_clicked()</slot>
+ <slot>btnDequeue_clicked()</slot>
+ <slot>downloadList_currentChanged(TQListViewItem*)</slot>
+ <slot>seedList_currentChanged(TQListViewItem*)</slot>
+ <slot>btnOk_clicked()</slot>
+ <slot>btnApply_clicked()</slot>
+ <slot>btnClose_clicked()</slot>
+ <slot>btnMoveTop_clicked()</slot>
+ <slot>btnMoveBottom_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">ksqueezedtextlabel.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/scandialog.cpp b/src/apps/ktorrent/scandialog.cpp
new file mode 100644
index 0000000..834539d
--- /dev/null
+++ b/src/apps/ktorrent/scandialog.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tqlabel.h>
+#include <tdelocale.h>
+#include <kprogress.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include <tdemessagebox.h>
+#include <util/error.h>
+#include <torrent/queuemanager.h>
+#include <torrent/torrentcontrol.h>
+
+#include "scandialog.h"
+#include "ktorrentcore.h"
+
+using namespace bt;
+using namespace kt;
+
+
+
+ScanDialog::ScanDialog(KTorrentCore* core,bool auto_import,
+ TQWidget* parent, const char* name, bool modal, WFlags fl)
+ : ScanDlgBase(parent,name, modal,fl),DataCheckerListener(auto_import),mutex(true),core(core)
+{
+ m_cancel->setGuiItem(KStdGuiItem::cancel());
+ connect(m_cancel,TQ_SIGNAL(clicked()),this,TQ_SLOT(onCancelPressed()));
+ connect(&timer,TQ_SIGNAL(timeout()),this,TQ_SLOT(update()));
+ tc = 0;
+ silently = false;
+ restart = false;
+ qm_controlled = false;
+ scanning = false;
+ num_chunks = 0;
+ total_chunks = 0;
+ num_downloaded = 0;
+ num_failed = 0;
+}
+
+ScanDialog::~ScanDialog()
+{
+}
+
+void ScanDialog::scan()
+{
+ try
+ {
+ tc->startDataCheck(this,auto_import);
+ timer.start(500);
+ scanning = true;
+ }
+ catch (bt::Error & err)
+ {
+ KMessageBox::error(0,i18n("Error scanning data: %1").arg(err.toString()));
+ }
+
+}
+
+void ScanDialog::execute(kt::TorrentInterface* tc,bool silently)
+{
+ m_torrent_label->setText(i18n("Scanning data of <b>%1</b> :").arg(tc->getStats().torrent_name));
+ adjustSize();
+ m_cancel->setEnabled(true);
+ this->silently = silently;
+ this->tc = tc;
+ num_chunks = 0;
+ total_chunks = 0;
+ num_downloaded = 0;
+ num_failed = 0;
+ if (auto_import || tc->getStats().running)
+ restart = true;
+
+ qm_controlled = !tc->getStats().user_controlled;
+ qm_priority = tc->getPriority();
+
+ if (tc->getStats().running)
+ {
+ if (qm_controlled)
+ core->getQueueManager()->stop(tc,true);
+ else
+ tc->stop(true);
+ }
+
+
+ scan();
+}
+
+void ScanDialog::finished()
+{
+ TQMutexLocker lock(&mutex);
+ scanning = false;
+ timer.stop();
+ progress(100,100);
+ update();
+ if (!isStopped())
+ {
+ if (restart)
+ {
+ if (!qm_controlled)
+ tc->start();
+ else
+ {
+ tc->setPriority(qm_priority);
+ core->getQueueManager()->orderQueue();
+ }
+ }
+
+ if (silently)
+ accept();
+ else
+ {
+ // cancel now becomes a close button
+ m_cancel->setGuiItem(KStdGuiItem::close());
+ disconnect(m_cancel,TQ_SIGNAL(clicked()),this,TQ_SLOT(onCancelPressed()));
+ connect(m_cancel,TQ_SIGNAL(clicked()),this,TQ_SLOT(accept()));
+ }
+ }
+ else
+ {
+ if (restart)
+ {
+ if (!qm_controlled)
+ tc->start();
+ else
+ {
+ tc->setPriority(qm_priority);
+ core->getQueueManager()->orderQueue();
+ }
+ }
+
+ TQDialog::reject();
+ }
+}
+
+void ScanDialog::progress(bt::Uint32 num,bt::Uint32 total)
+{
+ TQMutexLocker lock(&mutex);
+ num_chunks = num;
+ total_chunks = total;
+
+}
+
+void ScanDialog::update()
+{
+ TQMutexLocker lock(&mutex);
+ m_progress->setTotalSteps(total_chunks);
+ m_progress->setProgress(num_chunks);
+ m_chunks_found->setText(TQString::number(num_downloaded));
+ m_chunks_failed->setText(TQString::number(num_failed));
+}
+
+void ScanDialog::status(bt::Uint32 failed,bt::Uint32 downloaded)
+{
+ TQMutexLocker lock(&mutex);
+ num_failed = failed;
+ num_downloaded = downloaded;
+}
+
+void ScanDialog::reject()
+{
+ if (scanning)
+ stop();
+ else
+ TQDialog::reject();
+}
+
+void ScanDialog::onCancelPressed()
+{
+ stop();
+}
+
+void ScanDialog::accept()
+{
+ TQDialog::accept();
+}
+
+void ScanDialog::closeEvent(TQCloseEvent* e)
+{
+ if (scanning)
+ reject();
+ else
+ accept();
+}
+
+#include "scandialog.moc"
+
diff --git a/src/apps/ktorrent/scandialog.h b/src/apps/ktorrent/scandialog.h
new file mode 100644
index 0000000..b22e1b8
--- /dev/null
+++ b/src/apps/ktorrent/scandialog.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+
+#ifndef SCANDIALOG_H
+#define SCANDIALOG_H
+
+#include <tqmutex.h>
+#include <tqtimer.h>
+#include <datachecker/datacheckerlistener.h>
+#include "scandlgbase.h"
+
+
+namespace kt
+{
+ class TorrentInterface;
+}
+
+class KTorrentCore;
+
+class ScanDialog : public ScanDlgBase, public bt::DataCheckerListener
+{
+ TQ_OBJECT
+
+public:
+ ScanDialog(KTorrentCore* core,bool auto_import,TQWidget* parent = 0, const char* name = 0, bool modal = false, WFlags fl = WDestructiveClose );
+ virtual ~ScanDialog();
+
+ /// Starts the scan thread
+ void execute(kt::TorrentInterface* tc,bool silently);
+
+protected:
+ /// Update progress info, runs in scan thread
+ virtual void progress(bt::Uint32 num,bt::Uint32 total);
+
+ /// Update status info, runs in scan thread
+ virtual void status(bt::Uint32 num_failed,bt::Uint32 num_downloaded);
+
+ /// Scan finished, runs in app thread
+ virtual void finished();
+
+ /// Handle the close event
+ virtual void closeEvent(TQCloseEvent* e);
+
+
+protected slots:
+ virtual void reject();
+ virtual void accept();
+ void onCancelPressed();
+ /// Updates the GUI in app thread
+ void update();
+ void scan();
+
+private:
+ kt::TorrentInterface* tc;
+ TQMutex mutex;
+ TQTimer timer;
+ bt::Uint32 num_chunks;
+ bt::Uint32 total_chunks;
+ bt::Uint32 num_downloaded;
+ bt::Uint32 num_failed;
+ bool silently;
+ bool restart;
+ bool qm_controlled;
+ int qm_priority;
+ bool scanning;
+ KTorrentCore* core;
+};
+
+
+#endif
+
diff --git a/src/apps/ktorrent/scandlgbase.ui b/src/apps/ktorrent/scandlgbase.ui
new file mode 100644
index 0000000..44facbb
--- /dev/null
+++ b/src/apps/ktorrent/scandlgbase.ui
@@ -0,0 +1,193 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ScanDlgBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>ScanDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>441</width>
+ <height>182</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Scanning data</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="resizeMode">
+ <enum>Minimum</enum>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>m_torrent_label</cstring>
+ </property>
+ <property name="text">
+ <string>Scanning data of torrent :</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Number of chunks found :</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Number of chunks failed / not downloaded :</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>m_chunks_found</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>m_chunks_failed</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>100</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="text">
+ <string>0</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="KProgress">
+ <property name="name">
+ <cstring>m_progress</cstring>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>181</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>m_cancel</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kprogress.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/speedlimitsdlg.cpp b/src/apps/ktorrent/speedlimitsdlg.cpp
new file mode 100644
index 0000000..70e2f1c
--- /dev/null
+++ b/src/apps/ktorrent/speedlimitsdlg.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tqlabel.h>
+#include <tdelocale.h>
+#include <knuminput.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include <util/constants.h>
+#include <interfaces/torrentinterface.h>
+
+#include "speedlimitsdlg.h"
+
+using namespace bt;
+using namespace kt;
+
+SpeedLimitsDlg::SpeedLimitsDlg(kt::TorrentInterface* ti,TQWidget* parent, const char* name)
+ : SpeedLimitsDlgBase(parent,name,true,0),tor(ti)
+{
+ m_main_caption->setText(i18n("Speed limits for <b>%1</b>:").arg(tor->getStats().torrent_name));
+ Uint32 up,down;
+ tor->getTrafficLimits(up,down);
+ m_upload_rate->setValue(up / 1024);
+ m_upload_rate->setMinValue(0);
+ m_download_rate->setValue(down / 1024);
+ m_download_rate->setMinValue(0);
+ m_ok->setGuiItem(KStdGuiItem::ok());
+ m_cancel->setGuiItem(KStdGuiItem::cancel());
+ adjustSize();
+}
+
+SpeedLimitsDlg::~SpeedLimitsDlg()
+{}
+
+
+void SpeedLimitsDlg::accept()
+{
+ Uint32 up = m_upload_rate->value() * 1024;
+ Uint32 down = m_download_rate->value() * 1024;
+ tor->setTrafficLimits(up,down);
+ TQDialog::accept();
+}
+
+
+
+#include "speedlimitsdlg.moc"
+
diff --git a/src/apps/ktorrent/speedlimitsdlg.h b/src/apps/ktorrent/speedlimitsdlg.h
new file mode 100644
index 0000000..01d3e31
--- /dev/null
+++ b/src/apps/ktorrent/speedlimitsdlg.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+
+#ifndef SPEEDLIMITSDLG_H
+#define SPEEDLIMITSDLG_H
+
+#include "speedlimitsdlgbase.h"
+
+namespace kt
+{
+ class TorrentInterface;
+}
+
+class SpeedLimitsDlg : public SpeedLimitsDlgBase
+{
+ TQ_OBJECT
+
+
+ kt::TorrentInterface* tor;
+public:
+ SpeedLimitsDlg(kt::TorrentInterface* ti,TQWidget* parent = 0, const char* name = 0);
+ virtual ~SpeedLimitsDlg();
+
+
+protected slots:
+ virtual void accept();
+
+};
+
+#endif
+
diff --git a/src/apps/ktorrent/speedlimitsdlgbase.ui b/src/apps/ktorrent/speedlimitsdlgbase.ui
new file mode 100644
index 0000000..c3997a7
--- /dev/null
+++ b/src/apps/ktorrent/speedlimitsdlgbase.ui
@@ -0,0 +1,192 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>SpeedLimitsDlgBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>SpeedLimitsDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>362</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Speed Limits</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>m_main_caption</cstring>
+ </property>
+ <property name="text">
+ <string>Set the speed limits for torrent</string>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Max upload rate:</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Max download rate:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>m_upload_rate</cstring>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>m_download_rate</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>KB/s (0 is no limit)</string>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>KB/s (0 is no limit)</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>121</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>m_ok</cstring>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>m_cancel</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>m_cancel</sender>
+ <signal>clicked()</signal>
+ <receiver>SpeedLimitsDlgBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>m_ok</sender>
+ <signal>clicked()</signal>
+ <receiver>SpeedLimitsDlgBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/torrentcreatordlg.cpp b/src/apps/ktorrent/torrentcreatordlg.cpp
new file mode 100644
index 0000000..25c5e37
--- /dev/null
+++ b/src/apps/ktorrent/torrentcreatordlg.cpp
@@ -0,0 +1,152 @@
+//
+// C++ Implementation: $MODULE$
+//
+// Description:
+//
+//
+// Author: Joris Guisson <joris.guisson@gmail.com>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#include <tqcheckbox.h>
+#include <tqstringlist.h>
+#include <tqmap.h>
+#include <tdelocale.h>
+#include <tdemessagebox.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <kurlrequester.h>
+#include <keditlistbox.h>
+#include <kpushbutton.h>
+#include <tdefiledialog.h>
+#include <kprogress.h>
+#include <tdelistview.h>
+#include <knuminput.h>
+#include "torrentcreatordlg.h"
+#include "ktorrentcore.h"
+#include <torrent/globals.h>
+#include <kademlia/dhtbase.h>
+
+TorrentCreatorDlg::TorrentCreatorDlg(KTorrentCore* core,TQWidget *parent, const char *name)
+ :TorrentCreatorDlgBase(parent, name),core(core)
+{
+ KURLRequester* r = m_file_or_dir;
+ r->fileDialog()->setMode(
+ KFile::ExistingOnly|KFile::Directory|KFile::File|KFile::LocalOnly);
+
+ KComboBox* cb = m_chunk_size;
+ cb->setCurrentItem(3);
+
+ connect(m_create_btn,TQ_SIGNAL(clicked()),this,TQ_SLOT(onCreate()));
+ connect(m_cancel_btn,TQ_SIGNAL(clicked()),this,TQ_SLOT(reject()));
+
+ m_nodes->setHidden(true);
+
+ TQMap<TQString, int> n = bt::Globals::instance().getDHT().getClosestGoodNodes(10);
+
+ for(TQMap<TQString, int>::iterator it = n.begin(); it!=n.end(); ++it)
+ new TQListViewItem(m_nodeList, it.key(), TQString("%1").arg(it.data()));
+}
+
+TorrentCreatorDlg::~TorrentCreatorDlg()
+{
+}
+
+void TorrentCreatorDlg::onCreate()
+{
+ KURLRequester* r = m_file_or_dir;
+ KComboBox* cb = m_chunk_size;
+ KEditListBox* eb = m_trackers;
+
+ if (r->url().length() == 0)
+ {
+ errorMsg(i18n("You must select a file or a folder."));
+ return;
+ }
+
+ if (eb->items().count() == 0 && !m_decentralized->isChecked())
+ {
+ //errorMsg(i18n("You must add at least one tracker."));
+ TQString msg = i18n("You have not added a tracker, "
+ "are you sure you want to create this torrent ?");
+ if (KMessageBox::warningYesNo(this,msg) == KMessageBox::No)
+ return;
+ }
+
+ if (m_nodeList->childCount() == 0 && m_decentralized->isChecked())
+ {
+ errorMsg(i18n("You must add at least one node."));
+ return;
+ }
+
+ TQString url = r->url();
+ int chunk_size = cb->currentText().toInt();
+ TQString name = KURL::fromPathOrURL(r->url()).fileName();
+
+ TQStringList trackers;
+
+ if(m_decentralized->isChecked())
+ {
+ for(int i=0; i<m_nodeList->childCount(); ++i)
+ trackers.append(m_nodeList->itemAtIndex(i)->text(0) + "," + m_nodeList->itemAtIndex(i)->text(1));
+ }
+ else
+ trackers = eb->items();
+
+ TQString s = KFileDialog::getSaveFileName(
+ TQString(),"*.torrent|" + i18n("Torrent Files (*.torrent)"),
+ 0,i18n("Choose File to Save Torrent"));
+
+ if (s.isNull())
+ return;
+
+ if (!s.endsWith(".torrent"))
+ s += ".torrent";
+
+ KProgressDialog* dlg = new KProgressDialog(this,0);
+ dlg->setLabel(i18n("Creating %1...").arg(s));
+ dlg->setModal(true);
+ dlg->setAllowCancel(false);
+ dlg->show();
+ core->makeTorrent(
+ url,trackers,chunk_size,
+ name,m_comments->text(),
+ m_start_seeding->isChecked(),s,
+ m_private->isChecked(),
+ dlg->progressBar(),
+ m_decentralized->isChecked());
+ delete dlg;
+ accept();
+}
+
+void TorrentCreatorDlg::errorMsg(const TQString & text)
+{
+ KMessageBox::error(this,text,i18n("Error"));
+}
+
+void TorrentCreatorDlg::btnRemoveNode_clicked()
+{
+ TQListViewItem* item = m_nodeList->currentItem();
+ if(!item)
+ return;
+
+ m_nodeList->removeItem(item);
+}
+
+void TorrentCreatorDlg::btnAddNode_clicked()
+{
+ new TQListViewItem(m_nodeList, m_node->text(), TQString("%1").arg(m_port->value()));
+}
+
+void TorrentCreatorDlg::m_nodeList_selectionChanged(TQListViewItem*)
+{
+ btnRemoveNode->setEnabled(m_nodeList->selectedItem()!=0);
+}
+
+void TorrentCreatorDlg::m_node_textChanged(const TQString& txt)
+{
+ btnAddNode->setEnabled(!txt.isEmpty());
+}
+
+#include "torrentcreatordlg.moc"
diff --git a/src/apps/ktorrent/torrentcreatordlg.h b/src/apps/ktorrent/torrentcreatordlg.h
new file mode 100644
index 0000000..76ce111
--- /dev/null
+++ b/src/apps/ktorrent/torrentcreatordlg.h
@@ -0,0 +1,40 @@
+//
+// C++ Interface: $MODULE$
+//
+// Description:
+//
+//
+// Author: Joris Guisson <joris.guisson@gmail.com>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef TORENTCREATORDLG_H
+#define TORENTCREATORDLG_H
+
+#include "torrentcreatordlgbase.h"
+
+class KTorrentCore;
+
+class TorrentCreatorDlg: public TorrentCreatorDlgBase
+{
+ TQ_OBJECT
+
+public:
+ TorrentCreatorDlg(KTorrentCore* core,TQWidget *parent = 0, const char *name = 0);
+ virtual ~TorrentCreatorDlg();
+
+public slots:
+ void onCreate();
+ virtual void btnAddNode_clicked();
+ virtual void btnRemoveNode_clicked();
+ virtual void m_nodeList_selectionChanged(TQListViewItem*);
+ virtual void m_node_textChanged(const TQString&);
+private:
+ void errorMsg(const TQString & text);
+
+private:
+ KTorrentCore* core;
+};
+
+#endif
diff --git a/src/apps/ktorrent/torrentcreatordlgbase.ui b/src/apps/ktorrent/torrentcreatordlgbase.ui
new file mode 100644
index 0000000..97488be
--- /dev/null
+++ b/src/apps/ktorrent/torrentcreatordlgbase.ui
@@ -0,0 +1,527 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>TorrentCreatorDlgBase</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>TorrentCreatorDlgBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>503</width>
+ <height>669</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Create Torrent</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>The file or folder of which you want to create a torrent:</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>m_file_or_dir</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQLabel" row="2" column="0">
+ <property name="name">
+ <cstring>m_label1</cstring>
+ </property>
+ <property name="text">
+ <string>You must add at least one tracker or node.</string>
+ </property>
+ </widget>
+ <widget class="TQGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>File Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Size of each chunk:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <item>
+ <property name="text">
+ <string>32</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>64</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>128</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>256</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>512</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>1024</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>2048</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>4096</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>8192</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>m_chunk_size</cstring>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>KB</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>m_start_seeding</cstring>
+ </property>
+ <property name="text">
+ <string>Start seedin&amp;g the torrent</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="3" column="0">
+ <property name="name">
+ <cstring>m_decentralized</cstring>
+ </property>
+ <property name="text">
+ <string>Decentrali&amp;zed (DHT only)</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>m_private</cstring>
+ </property>
+ <property name="text">
+ <string>Private torrent (DHT not allowed)</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="TQLayoutWidget" row="5" column="0">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Comments:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_comments</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQLayoutWidget" row="6" column="0">
+ <property name="name">
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>m_create_btn</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Create</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>m_cancel_btn</cstring>
+ </property>
+ <property name="text">
+ <string>Ca&amp;ncel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="KEditListBox" row="3" column="0">
+ <property name="name">
+ <cstring>m_trackers</cstring>
+ </property>
+ <property name="title">
+ <string>Trackers</string>
+ </property>
+ </widget>
+ <widget class="TQGroupBox" row="4" column="0">
+ <property name="name">
+ <cstring>m_nodes</cstring>
+ </property>
+ <property name="title">
+ <string>DHT nodes</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>btnRemoveNode</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>28</number>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="1" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>btnAddNode</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Add</string>
+ </property>
+ <property name="stdItem" stdset="0">
+ <number>27</number>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Node:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit">
+ <property name="name">
+ <cstring>m_node</cstring>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>textLabel1_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="KIntNumInput">
+ <property name="name">
+ <cstring>m_port</cstring>
+ </property>
+ <property name="value">
+ <number>6882</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="maxValue">
+ <number>65535</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Maximum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TDEListView" row="1" column="0" rowspan="3" colspan="1">
+ <column>
+ <property name="text">
+ <string>IP or hostname</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>m_nodeList</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQLabel" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>NOTE: Some known good DHT nodes are already inserted. You should probably insert your own IP address and port too if you plan to seed this torrent.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>m_private</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_decentralized</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_decentralized</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_private</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_decentralized</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_trackers</receiver>
+ <slot>setHidden(bool)</slot>
+ </connection>
+ <connection>
+ <sender>m_decentralized</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>m_nodes</receiver>
+ <slot>setShown(bool)</slot>
+ </connection>
+ <connection>
+ <sender>btnRemoveNode</sender>
+ <signal>clicked()</signal>
+ <receiver>TorrentCreatorDlgBase</receiver>
+ <slot>btnRemoveNode_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>btnAddNode</sender>
+ <signal>clicked()</signal>
+ <receiver>TorrentCreatorDlgBase</receiver>
+ <slot>btnAddNode_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>m_node</sender>
+ <signal>textChanged(const TQString&amp;)</signal>
+ <receiver>TorrentCreatorDlgBase</receiver>
+ <slot>m_node_textChanged(const TQString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>m_nodeList</sender>
+ <signal>selectionChanged(TQListViewItem*)</signal>
+ <receiver>TorrentCreatorDlgBase</receiver>
+ <slot>m_nodeList_selectionChanged(TQListViewItem*)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>m_file_or_dir</tabstop>
+ <tabstop>m_chunk_size</tabstop>
+ <tabstop>m_start_seeding</tabstop>
+ <tabstop>m_private</tabstop>
+ <tabstop>m_decentralized</tabstop>
+ <tabstop>m_node</tabstop>
+ <tabstop>m_port</tabstop>
+ <tabstop>btnAddNode</tabstop>
+ <tabstop>btnRemoveNode</tabstop>
+ <tabstop>m_comments</tabstop>
+ <tabstop>m_create_btn</tabstop>
+ <tabstop>m_cancel_btn</tabstop>
+</tabstops>
+<forwards>
+ <forward>class TQListViewItem;</forward>
+</forwards>
+<slots>
+ <slot>btnRemoveNode_clicked()</slot>
+ <slot>btnAddNode_clicked()</slot>
+ <slot>m_node_textChanged(const TQString&amp;)</slot>
+ <slot>m_nodeList_selectionChanged(TQListViewItem*)</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kcombobox.h</include>
+ <include location="global" impldecl="in implementation">keditlistbox.h</include>
+ <include location="global" impldecl="in implementation">klineedit.h</include>
+ <include location="global" impldecl="in implementation">knuminput.h</include>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+ <include location="global" impldecl="in implementation">kurlrequester.h</include>
+ <include location="global" impldecl="in implementation">tdelistview.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktorrent/trayhoverpopup.cpp b/src/apps/ktorrent/trayhoverpopup.cpp
new file mode 100644
index 0000000..b325184
--- /dev/null
+++ b/src/apps/ktorrent/trayhoverpopup.cpp
@@ -0,0 +1,136 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tqvbox.h>
+#include <tqhbox.h>
+#include <tqlabel.h>
+#include <tqtooltip.h>
+#include <tqpixmap.h>
+#include <kdialog.h>
+#include <util/log.h>
+#include "trayhoverpopup.h"
+
+using namespace bt;
+
+TrayHoverPopup::TrayHoverPopup(const TQPixmap & pix,TQWidget *parent, const char *name )
+ : KPassivePopup(KPassivePopup::Boxed,parent,name),pix(pix)
+{
+ setTimeout(0);
+ setAutoDelete(false);
+ connect(&hover_timer,TQ_SIGNAL(timeout()),this,TQ_SLOT(onHoverTimeout()));
+ connect(&show_timer,TQ_SIGNAL(timeout()),this,TQ_SLOT(onShowTimeout()));
+ create();
+ setPalette(TQToolTip::palette());
+ setLineWidth(1);
+ context_menu_shown = false;
+ cursor_over_icon = false;
+}
+
+
+TrayHoverPopup::~TrayHoverPopup()
+{}
+
+void TrayHoverPopup::contextMenuAboutToShow()
+{
+ context_menu_shown = true;
+ if (isShown())
+ {
+ hide();
+ hover_timer.stop();
+ }
+}
+
+void TrayHoverPopup::contextMenuAboutToHide()
+{
+ context_menu_shown = false;
+}
+
+
+void TrayHoverPopup::enterEvent()
+{
+ cursor_over_icon = true;
+ if (isHidden() && !context_menu_shown)
+ {
+ // start the show timer
+ show_timer.start(1000,true);
+ }
+ else
+ hover_timer.stop(); // stop timeout
+}
+
+void TrayHoverPopup::leaveEvent()
+{
+ cursor_over_icon = false;
+ // to avoid problems with a quick succession of enter and leave events, because the cursor
+ // is on the edge, use a timer to expire the popup
+ // in enterEvent we will stop the timer
+ if (isShown())
+ hover_timer.start(200,true);
+}
+
+void TrayHoverPopup::onHoverTimeout()
+{
+ hide();
+ show_timer.stop();
+}
+
+void TrayHoverPopup::onShowTimeout()
+{
+ if (!context_menu_shown && cursor_over_icon)
+ show();
+}
+
+void TrayHoverPopup::updateText(const TQString & msg)
+{
+ text->setText(msg);
+}
+
+void TrayHoverPopup::create()
+{
+ TQVBox *vb = new TQVBox(this);
+ vb->setSpacing(KDialog::spacingHint());
+
+ TQHBox *hb=0;
+ if (!pix.isNull())
+ {
+ hb = new TQHBox(vb);
+ hb->setMargin(0);
+ hb->setSpacing(KDialog::spacingHint());
+ TQLabel* pix_lbl = new TQLabel(hb,"title_icon");
+ pix_lbl->setPixmap(pix);
+ pix_lbl->setAlignment(AlignLeft);
+ }
+
+
+ TQLabel* title = new TQLabel("KTorrent", hb ? hb : vb, "title_label" );
+ TQFont fnt = title->font();
+ fnt.setBold( true );
+ title->setFont( fnt );
+ title->setAlignment( TQt::AlignHCenter );
+ if ( hb )
+ hb->setStretchFactor(title, 10 ); // enforce centering
+
+ // text will be filled later
+ text = new TQLabel( "Dummy", vb, "msg_label" );
+ text->setAlignment( AlignLeft );
+ setView(vb);
+}
+
+
+#include "trayhoverpopup.moc"
diff --git a/src/apps/ktorrent/trayhoverpopup.h b/src/apps/ktorrent/trayhoverpopup.h
new file mode 100644
index 0000000..c3cf9fb
--- /dev/null
+++ b/src/apps/ktorrent/trayhoverpopup.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef TRAYHOVERPOPUP_H
+#define TRAYHOVERPOPUP_H
+
+#include <tqtimer.h>
+#include <kpassivepopup.h>
+
+class TQLabel;
+class TQPixmap;
+
+/**
+ @author Joris Guisson <joris.guisson@gmail.com>
+
+ This is the passive popup which is shown when the mouse cursor is hovered over the tray icon
+*/
+class TrayHoverPopup : public KPassivePopup
+{
+ TQ_OBJECT
+
+public:
+ TrayHoverPopup(const TQPixmap & pix,TQWidget *parent = 0, const char *name = 0 );
+ virtual ~TrayHoverPopup();
+
+ /// Cursor entered system tray icon
+ void enterEvent();
+
+ /// Cursor left system tray icon
+ void leaveEvent();
+
+ /// Update the text which is shown
+ void updateText(const TQString & msg);
+
+public slots:
+ void contextMenuAboutToShow();
+ void contextMenuAboutToHide();
+
+private:
+ void create();
+
+private slots:
+ void onHoverTimeout();
+ void onShowTimeout();
+
+
+private:
+ const TQPixmap & pix;
+ TQTimer hover_timer;
+ TQTimer show_timer;
+ TQLabel* text;
+ bool context_menu_shown;
+ bool cursor_over_icon;
+};
+
+#endif
diff --git a/src/apps/ktorrent/trayicon.cpp b/src/apps/ktorrent/trayicon.cpp
new file mode 100644
index 0000000..19667ab
--- /dev/null
+++ b/src/apps/ktorrent/trayicon.cpp
@@ -0,0 +1,380 @@
+/***************************************************************************
+ * 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()),tdeApp,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"
diff --git a/src/apps/ktorrent/trayicon.h b/src/apps/ktorrent/trayicon.h
new file mode 100644
index 0000000..f31767d
--- /dev/null
+++ b/src/apps/ktorrent/trayicon.h
@@ -0,0 +1,143 @@
+/***************************************************************************
+ * 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. *
+ ***************************************************************************/
+#ifndef TRAYICON_H
+#define TRAYICON_H
+
+
+#include <ksystemtray.h>
+#include <tdepopupmenu.h>
+#include <tqpainter.h>
+
+#include "ktorrentcore.h"
+#include "settings.h"
+#include "interfaces/torrentinterface.h"
+#include <util/constants.h>
+
+using namespace bt;
+class TQString;
+class TrayHoverPopup;
+
+struct TrayStats
+{
+ bt::Uint32 download_speed;
+ bt::Uint32 upload_speed;
+ bt::Uint64 bytes_downloaded;
+ bt::Uint64 bytes_uploaded;
+};
+
+/**
+ * @author Joris Guisson
+ * @author Ivan Vasic
+*/
+class TrayIcon : public KSystemTray
+{
+ TQ_OBJECT
+
+public:
+ TrayIcon(KTorrentCore* tc, TQWidget *parent = 0, const char *name = 0);
+ virtual ~TrayIcon();
+
+ /// Update stats for system tray icon
+ void updateStats(const CurrentStats stats, bool showBars=false, int downloadBandwidth=0, int uploadBandwidth=0);
+
+private:
+ void drawSpeedBar(int downloadSpeed, int uploadSpeed, int downloadBandwidth, int uploadBandwidth);
+ void showPassivePopup(const TQString & msg,const TQString & titile);
+ virtual void enterEvent(TQEvent* ev);
+ virtual void leaveEvent(TQEvent* ev);
+
+private slots:
+ /**
+ * Show a passive popup, that the torrent has stopped downloading.
+ * @param tc The torrent
+ */
+ void finished(kt::TorrentInterface* tc);
+
+ /**
+ * Show a passive popup that a torrent has reached it's max share ratio.
+ * @param tc The torrent
+ */
+ void maxShareRatioReached(kt::TorrentInterface* tc);
+
+ /**
+ * Show a passive popup that a torrent has reached it's max seed time
+ * @param tc The torrent
+ */
+ void maxSeedTimeReached(kt::TorrentInterface* tc);
+
+ /**
+ * Show a passive popup when a torrent has been stopped by an error.
+ * @param tc The torrent
+ * @param msg Error message
+ */
+ void torrentStoppedByError(kt::TorrentInterface* tc, TQString msg);
+
+ /**
+ * Corrupted data has been found.
+ * @param tc The torrent
+ */
+ void corruptedData(kt::TorrentInterface* tc);
+
+ /**
+ * User tried to enqueue a torrent that has reached max share ratio or max seed time
+ * Show passive popup message.
+ */
+ void queuingNotPossible(kt::TorrentInterface* tc);
+
+ /**
+ * We failed to start a torrent
+ * @param tc The torrent
+ * @param reason The reason it failed
+ */
+ void canNotStart(kt::TorrentInterface* tc,kt::TorrentStartResponse reason);
+
+ ///Shows passive popup message
+ void lowDiskSpace(kt::TorrentInterface* tc, bool stopped);
+
+private:
+ KTorrentCore* m_core;
+ TQPainter *paint;
+ int previousDownloadHeight;
+ int previousUploadHeight;
+ TrayHoverPopup* m_hover_popup;
+ TQPixmap m_kt_pix;
+};
+
+class SetMaxRate : public TDEPopupMenu
+{
+ TQ_OBJECT
+
+ public:
+ SetMaxRate(KTorrentCore* tc, int t, TQWidget *parent=0, const char *name=0); // type: 0 Upload; 1 Download
+ ~SetMaxRate()
+ {}
+ ;
+
+ void update();
+ private:
+ KTorrentCore* m_core;
+ int type;
+ void makeMenu();
+ private slots:
+ void rateSelected(int id);
+};
+
+#endif
diff --git a/src/apps/ktorrent/viewmanager.cpp b/src/apps/ktorrent/viewmanager.cpp
new file mode 100644
index 0000000..eef9d06
--- /dev/null
+++ b/src/apps/ktorrent/viewmanager.cpp
@@ -0,0 +1,265 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <tdeconfig.h>
+#include <tdelocale.h>
+#include <ktabwidget.h>
+#include <interfaces/torrentinterface.h>
+#include <groups/group.h>
+#include "viewmanager.h"
+#include "ktorrentview.h"
+#include "ktorrent.h"
+
+typedef TQValueList<KTorrentView*>::iterator ViewItr;
+
+ViewManager::ViewManager ( TQObject *parent, const char *name )
+ : TQObject ( parent, name ),current(0)
+{}
+
+
+ViewManager::~ViewManager()
+{}
+
+KTorrentView* ViewManager::newView()
+{
+ KTorrentView* v = new KTorrentView(0);
+ views.append(v);
+ return v;
+}
+
+void ViewManager::saveViewState(TDEConfig* cfg)
+{
+ TQStringList cv;
+ int idx = 0;
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ cv.append((*i)->getCurrentGroup()->groupName());
+ (*i)->saveSettings(cfg,idx++);
+ }
+ cfg->setGroup("ViewManager");
+ cfg->writeEntry("current_views",cv);
+}
+
+void ViewManager::restoreViewState(TDEConfig* cfg,KTorrent* ktor)
+{
+ TQStringList def;
+ def.append(i18n("Downloads"));
+ def.append(i18n("Uploads"));
+
+ cfg->setGroup("ViewManager");
+
+ TQStringList to_load = cfg->readListEntry("current_views",def);
+ if (to_load.empty())
+ to_load = def;
+
+ for (TQStringList::iterator i = to_load.begin();i != to_load.end();i++)
+ {
+ ktor->openView(*i);
+ }
+
+ if (views.count() == 0)
+ {
+ // no view open, so open default ones
+ for (TQStringList::iterator i = def.begin();i != def.end();i++)
+ ktor->openView(*i);
+ }
+
+ // load status for each view
+ int idx = 0;
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ (*i)->loadSettings(cfg,idx++);
+ }
+}
+
+void ViewManager::updateActions()
+{
+ if (current)
+ current->updateActions();
+}
+
+void ViewManager::addTorrent(kt::TorrentInterface* tc)
+{
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ (*i)->addTorrent(tc);
+ }
+}
+
+void ViewManager::removeTorrent(kt::TorrentInterface* tc)
+{
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ (*i)->removeTorrent(tc);
+ }
+}
+
+void ViewManager::startDownloads()
+{
+ if (current)
+ current->startDownloads();
+}
+
+void ViewManager::stopDownloads()
+{
+ if (current)
+ current->stopDownloads();
+}
+
+void ViewManager::startAllDownloads()
+{
+ if (current)
+ current->startAllDownloads();
+}
+
+void ViewManager::stopAllDownloads()
+{
+ if (current)
+ current->stopAllDownloads();
+}
+
+void ViewManager::removeDownloads()
+{
+ if (current)
+ current->removeDownloads();
+}
+
+kt::TorrentInterface* ViewManager::getCurrentTC()
+{
+ return current ? current->getCurrentTC() : 0;
+}
+
+void ViewManager::update()
+{
+ // update the caption of each view if necessary
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ if (*i != current)
+ {
+ KTorrentView* w = *i;
+ w->updateCaption();
+ }
+ }
+
+ if (current)
+ current->update();
+}
+
+void ViewManager::queueAction()
+{
+ if (current)
+ current->queueSlot();
+}
+
+void ViewManager::checkDataIntegrity()
+{
+ if (current)
+ current->checkDataIntegrity();
+}
+
+void ViewManager::getSelection(TQValueList<kt::TorrentInterface*> & sel)
+{
+ if (current)
+ current->getSelection(sel);
+}
+
+void ViewManager::onCurrentTabChanged(TQWidget* w)
+{
+ KTorrentView* old = current;
+ current = 0;
+ for (ViewItr i = views.begin();i != views.end() && !current;i++)
+ {
+ if (w == *i)
+ current = *i;
+ }
+
+ if (!current)
+ current = old;
+ else
+ {
+ current->update();
+ current->updateActions();
+ }
+}
+
+bool ViewManager::closeAllowed(TQWidget* )
+{
+ return views.count() > 1;
+}
+
+void ViewManager::tabCloseRequest(kt::GUIInterface* gui,TQWidget* tab)
+{
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ if (tab == *i)
+ {
+ if (current == *i)
+ current = 0;
+
+ gui->removeTabPage(tab);
+ delete tab;
+ views.erase(i);
+ break;
+ }
+ }
+}
+
+void ViewManager::groupRenamed(kt::Group* g,KTabWidget* mtw)
+{
+ for (ViewItr i = views.begin();i != views.end();i++)
+ {
+ KTorrentView* v = *i;
+ if (v->getCurrentGroup() == g)
+ {
+ mtw->changeTab(v,g->groupName());
+ v->setIcon(g->groupIcon());
+ v->setCurrentGroup(g);
+ }
+ }
+}
+
+void ViewManager::groupRemoved(kt::Group* g,KTabWidget* mtw,kt::GUIInterface* gui,kt::Group* all_group)
+{
+ for (ViewItr i = views.begin();i != views.end();)
+ {
+ KTorrentView* v = *i;
+ if (v->getCurrentGroup() == g)
+ {
+ if (views.count() > 1)
+ {
+ // close the tab
+ gui->removeTabPage(v);
+ delete v;
+ i = views.erase(i);
+ }
+ else
+ {
+ mtw->changeTab(v,all_group->groupName());
+ v->setIcon(all_group->groupIcon());
+ v->setCurrentGroup(all_group);
+ i++;
+ }
+ }
+ else
+ i++;
+ }
+}
+
+
+#include "viewmanager.moc"
diff --git a/src/apps/ktorrent/viewmanager.h b/src/apps/ktorrent/viewmanager.h
new file mode 100644
index 0000000..e402a92
--- /dev/null
+++ b/src/apps/ktorrent/viewmanager.h
@@ -0,0 +1,115 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef VIEWMANAGER_H
+#define VIEWMANAGER_H
+
+#include <tqobject.h>
+#include <tqvaluelist.h>
+#include <interfaces/guiinterface.h>
+
+class TDEConfig;
+class KTabWidget;
+class KTorrentView;
+class KTorrent;
+
+/**
+ @author Joris Guisson <joris.guisson@gmail.com>
+*/
+class ViewManager : public TQObject, public kt::CloseTabListener
+{
+ TQ_OBJECT
+
+public:
+ ViewManager(TQObject *parent = 0, const char *name = 0);
+ virtual ~ViewManager();
+
+ /// Create a new view
+ KTorrentView* newView();
+
+ /// Save all views
+ void saveViewState(TDEConfig* cfg);
+
+ /// Restore all views from configuration
+ void restoreViewState(TDEConfig* cfg,KTorrent* ktor);
+
+ /// Start all selected downloads in the current view
+ void startDownloads();
+
+ /// Stop all selected downloads in the current view
+ void stopDownloads();
+
+ /// Start all downloads in the current view
+ void startAllDownloads();
+
+ /// Stop all downloads in the current view
+ void stopAllDownloads();
+
+ /// Get the current torrent in the current view
+ kt::TorrentInterface* getCurrentTC();
+
+ /// Remove selected downloads in the current view
+ void removeDownloads();
+
+ /// Update the current view
+ void update();
+
+ /**
+ * Put the current selection of the current view in a list.
+ * @param sel The list to put it in
+ */
+ void getSelection(TQValueList<kt::TorrentInterface*> & sel);
+
+ /// Get the current view
+ KTorrentView* getCurrentView() {return current;}
+
+ virtual bool closeAllowed(TQWidget* tab);
+ virtual void tabCloseRequest(kt::GUIInterface* gui,TQWidget* tab);
+
+ /// A group was renamed, modify all view which where showing this group
+ void groupRenamed(kt::Group* g,KTabWidget* mtw);
+
+ /// A group has been removed, close any tab showing it (in case it is the last tab, switch to All Torrents)
+ void groupRemoved(kt::Group* g,KTabWidget* mtw,kt::GUIInterface* gui,kt::Group* all_group);
+
+ /// Call updateActions on the current view
+ void updateActions();
+
+public slots:
+ /// Add a torrent to all views
+ void addTorrent(kt::TorrentInterface* tc);
+
+ /// Remove a torernt from all views
+ void removeTorrent(kt::TorrentInterface* tc);
+
+ /// Enqueue/Dequeue selected torrents in current view
+ void queueAction();
+
+ /// Check data integrity of current torrent
+ void checkDataIntegrity();
+
+ /// The current tab has changed
+ void onCurrentTabChanged(TQWidget* w);
+
+private:
+ TQValueList<KTorrentView*> views;
+ KTorrentView* current;
+};
+
+#endif
diff --git a/src/apps/ktorrent/x-bittorrent.desktop b/src/apps/ktorrent/x-bittorrent.desktop
new file mode 100644
index 0000000..5180adf
--- /dev/null
+++ b/src/apps/ktorrent/x-bittorrent.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Comment=BitTorrent Download
+
+Type=MimeType
+Hidden=false
+Icon=torrent
+MimeType=application/x-bittorrent
+Patterns=*.torrent;*.tor
+X-TDE-AutoEmbed=false
diff --git a/src/apps/kttorinfo/CMakeLists.txt b/src/apps/kttorinfo/CMakeLists.txt
new file mode 100644
index 0000000..0dba8e0
--- /dev/null
+++ b/src/apps/kttorinfo/CMakeLists.txt
@@ -0,0 +1,13 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+)
+
+
+##### kttorinfo (executable)
+
+tde_add_executable( kttorinfo
+ SOURCES main.cpp
+ LINK ktorrent-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
diff --git a/src/apps/kttorinfo/main.cpp b/src/apps/kttorinfo/main.cpp
new file mode 100644
index 0000000..2208f7f
--- /dev/null
+++ b/src/apps/kttorinfo/main.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <stdlib.h>
+#include <tqstring.h>
+#include <util/log.h>
+#include <util/error.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+
+using namespace bt;
+
+void help()
+{
+ Out() << "Usage : kttorinfo <torrent>" << endl;
+ exit(0);
+}
+
+int main(int argc,char** argv)
+{
+ Globals::instance().setDebugMode(true);
+ Globals::instance().initLog("kttorinfo.log");
+ if (argc < 2)
+ help();
+
+ try
+ {
+ Torrent tor;
+ tor.load(TQString(argv[1]),false);
+ tor.debugPrintInfo();
+ }
+ catch (Error & e)
+ {
+ Out() << "Error : " << e.toString() << endl;
+ }
+ Globals::cleanup();
+ return 0;
+}
diff --git a/src/apps/ktupnptest/CMakeLists.txt b/src/apps/ktupnptest/CMakeLists.txt
new file mode 100644
index 0000000..674d951
--- /dev/null
+++ b/src/apps/ktupnptest/CMakeLists.txt
@@ -0,0 +1,15 @@
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/src
+ ${CMAKE_SOURCE_DIR}/src/libktorrent
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+##### ktupnptest (executable)
+
+tde_add_executable( ktupnptest AUTOMOC
+ SOURCES main.cpp upnptestapp.cpp mainwidget.ui
+ LINK ktupnp-static ktorrent-shared tdecore-shared tdeui-shared tdeio-shared DCOP-shared
+ DESTINATION ${BIN_INSTALL_DIR}
+)
diff --git a/src/apps/ktupnptest/main.cpp b/src/apps/ktupnptest/main.cpp
new file mode 100644
index 0000000..2493f36
--- /dev/null
+++ b/src/apps/ktupnptest/main.cpp
@@ -0,0 +1,97 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <stdio.h>
+#include <stdlib.h>
+#include <tdelocale.h>
+#include <tdeaboutdata.h>
+#include <tdeapplication.h>
+#include <tdecmdlineargs.h>
+#include <libktorrent/functions.h>
+
+
+#include "upnptestapp.h"
+
+using namespace kt;
+using namespace bt;
+
+static const char description[] =
+ I18N_NOOP("A TDE KPart Application");
+
+static const char version[] = "1.3dev";
+
+static TDECmdLineOptions options[] =
+{
+// { "+[URL]", I18N_NOOP( "Document to open" ), 0 },
+ TDECmdLineLastOption
+};
+
+
+
+
+int main(int argc,char** argv)
+{
+ Globals::instance().setDebugMode(true);
+ TDEAboutData about("ktupnptest", I18N_NOOP("KTUPnPTest"), version, description,
+ TDEAboutData::License_GPL, "(C) 2005 Joris Guisson", 0);
+ TDECmdLineArgs::init(argc, argv,&about);
+ TDECmdLineArgs::addCmdLineOptions( options );
+ TDEApplication app;
+ Globals::instance().initLog(kt::DataDir() + "ktupnptest.log");
+ UPnPTestApp* mwnd = new UPnPTestApp();
+
+ app.setMainWidget(mwnd);
+ mwnd->show();
+ app.exec();
+ Globals::cleanup();
+ return 0;
+
+ /*
+ if (argc >= 2)
+ {
+ kt::UPnPRouter router(TQString(),"http://foobar.com");
+ kt::UPnPDescriptionParser dp;
+
+ if (!dp.parse(argv[1],&router))
+ {
+ Out() << "Cannot parse " << TQString(argv[1]) << endl;
+ }
+ else
+ {
+ Out() << "Succesfully parsed the UPnP contents" << endl;
+ router.debugPrintData();
+ }
+ }
+
+
+ Out() << "Doing second test" << endl;
+ UPnPMCastSocket mcast;
+ UPnPRouter* r = mcast.parseResponse(TQCString(test_ps));
+ if (r)
+ {
+ Out() << "Succesfully parsed test_ps" << endl;
+ delete r;
+ }
+ else
+ {
+ Out() << "Failed to parse test_ps" << endl;
+ }
+ */
+
+}
diff --git a/src/apps/ktupnptest/mainwidget.ui b/src/apps/ktupnptest/mainwidget.ui
new file mode 100644
index 0000000..7faa40d
--- /dev/null
+++ b/src/apps/ktupnptest/mainwidget.ui
@@ -0,0 +1,75 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MainWidget</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>MainWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQTextBrowser">
+ <property name="name">
+ <cstring>output</cstring>
+ </property>
+ </widget>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>61</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>test_btn</cstring>
+ </property>
+ <property name="text">
+ <string>Test</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>close_btn</cstring>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includes>
+ <include location="global" impldecl="in implementation">kpushbutton.h</include>
+</includes>
+</UI>
diff --git a/src/apps/ktupnptest/upnptestapp.cpp b/src/apps/ktupnptest/upnptestapp.cpp
new file mode 100644
index 0000000..a6e0852
--- /dev/null
+++ b/src/apps/ktupnptest/upnptestapp.cpp
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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 <kpushbutton.h>
+#include <tdelocale.h>
+#include <tdeapplication.h>
+#include <tdemessagebox.h>
+#include <tqtextbrowser.h>
+#include <util/error.h>
+#include "upnptestapp.h"
+#include "mainwidget.h"
+
+using namespace bt;
+using namespace kt;
+
+UPnPTestApp::UPnPTestApp(TQWidget *parent, const char *name)
+ : TDEMainWindow(parent, name)
+{
+ sock = new UPnPMCastSocket(true);
+ connect(sock,TQ_SIGNAL(discovered( UPnPRouter* )),this,TQ_SLOT(discovered( UPnPRouter* )));
+ mwnd = new MainWidget(this);
+ setCentralWidget(mwnd);
+ connect(mwnd->test_btn,TQ_SIGNAL(clicked()),this,TQ_SLOT(onTestBtn()));
+ connect(mwnd->close_btn,TQ_SIGNAL(clicked()),this,TQ_SLOT(onCloseBtn()));
+ bt::Log & lg = bt::Globals::instance().getLog(0);
+ lg.addMonitor(this);
+ Out() << "UPnPTestApp started up !" << endl;
+}
+
+
+UPnPTestApp::~UPnPTestApp()
+{
+ sock->deleteLater();
+}
+
+void UPnPTestApp::discovered(kt::UPnPRouter* router)
+{
+ try
+ {
+ router->forward(net::Port(9999,net::TCP,false));
+ }
+ catch (Error & e)
+ {
+ KMessageBox::error(this,e.toString());
+ }
+}
+
+void UPnPTestApp::onTestBtn()
+{
+ sock->discover();
+}
+
+void UPnPTestApp::onCloseBtn()
+{
+ tdeApp->quit();
+}
+
+bool UPnPTestApp::queryExit()
+{
+ bt::Log & lg = bt::Globals::instance().getLog(0);
+ lg.removeMonitor(this);
+ return true;
+}
+
+void UPnPTestApp::message(const TQString& line, unsigned int arg)
+{
+ mwnd->output->append(line);
+}
+
+
+#include "upnptestapp.moc"
diff --git a/src/apps/ktupnptest/upnptestapp.h b/src/apps/ktupnptest/upnptestapp.h
new file mode 100644
index 0000000..7c5ac98
--- /dev/null
+++ b/src/apps/ktupnptest/upnptestapp.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@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. *
+ ***************************************************************************/
+#ifndef UPNPTESTAPP_H
+#define UPNPTESTAPP_H
+
+#include <tdemainwindow.h>
+#include <libktorrent/util/log.h>
+#include <libktorrent/torrent/globals.h>
+#include <plugins/upnp/upnprouter.h>
+#include <plugins/upnp/upnpdescriptionparser.h>
+#include <plugins/upnp/upnpmcastsocket.h>
+#include <interfaces/logmonitorinterface.h>
+
+class MainWidget;
+
+using kt::UPnPRouter;
+
+/**
+ @author Joris Guisson <joris.guisson@gmail.com>
+*/
+class UPnPTestApp : public TDEMainWindow, public kt::LogMonitorInterface
+{
+ TQ_OBJECT
+
+public:
+ UPnPTestApp(TQWidget *parent = 0, const char *name = 0);
+ virtual ~UPnPTestApp();
+
+ virtual void message(const TQString& line, unsigned int arg);
+ bool queryExit();
+
+private slots:
+ void discovered(UPnPRouter* router);
+ void onTestBtn();
+ void onCloseBtn();
+
+private:
+ kt::UPnPMCastSocket* sock;
+ MainWidget* mwnd;
+};
+
+#endif