diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 02:37:40 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 02:37:40 +0000 |
commit | 9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0 (patch) | |
tree | d088b5210e77d9fa91d954d8550e00e372b47378 /plugins/infowidget | |
download | ktorrent-9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0.tar.gz ktorrent-9ad5c7b5e23b4940e7a3ea3ca3a6fb77e6a8fab0.zip |
Updated to final KDE3 ktorrent release (2.2.6)
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/ktorrent@1077377 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'plugins/infowidget')
288 files changed, 6711 insertions, 0 deletions
diff --git a/plugins/infowidget/GeoIP.c b/plugins/infowidget/GeoIP.c new file mode 100644 index 0000000..f71f830 --- /dev/null +++ b/plugins/infowidget/GeoIP.c @@ -0,0 +1,825 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.c + * + * Copyright (C) 2003 MaxMind LLC All Rights Reserved. + * + * This library 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 library 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 library; if not, write to the Free Software + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "GeoIP.h" + +#include <netdb.h> +#include <sys/socket.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifndef _WIN32 +#include <netdb.h> +#include <netinet/in.h> /* For ntohl */ +#include <arpa/inet.h> +#else +#include <windows.h> +#endif +#include <assert.h> +#include <sys/types.h> /* for fstat */ +#include <sys/stat.h> /* for fstat */ + +#ifdef HAVE_STDINT_H +#include <stdint.h> /* For uint32_t */ +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +#define COUNTRY_BEGIN 16776960 +#define STATE_BEGIN_REV0 16700000 +#define STATE_BEGIN_REV1 16000000 +#define STRUCTURE_INFO_MAX_SIZE 20 +#define DATABASE_INFO_MAX_SIZE 100 +#define MAX_ORG_RECORD_LENGTH 300 +#define US_OFFSET 1 +#define CANADA_OFFSET 677 +#define WORLD_OFFSET 1353 +#define FIPS_RANGE 360 + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +const char GeoIP_country_code[247][3] = { "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN","AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB","BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO","BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD","CF","CG","CH","CI","CK","CL","CM","CN","CO","CR","CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO","DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ","FK","FM","FO","FR","FX","GA","GB","GD","GE","GF","GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT","GU","GW","GY","HK","HM","HN","HR","HT","HU","ID","IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO","JP","KE","KG","KH","KI","KM","KN","KP","KR","KW","KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT","LU","LV","LY","MA","MC","MD","MG","MH","MK","ML","MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV","MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI","NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF","PG","PH","PK","PL","PM","PN","PR","PS","PT","PW","PY","QA","RE","RO","RU","RW","SA","SB","SC","SD","SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO","SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH","TJ","TK","TM","TN","TO","TP","TR","TT","TV","TW","TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE","VG","VI","VN","VU","WF","WS","YE","YT","CS","ZA","ZM","ZR","ZW","A1","A2","O1"}; + +const char GeoIP_country_code3[247][4] = { "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC","COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV","CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD","GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM","GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO","IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU","LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF","TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA","UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT","WLF","WSM","YEM","YT","SCG","ZAF","ZMB","ZR","ZWE","A1","A2","O1"}; + +const char * GeoIP_country_name[247] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles","Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados","Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia","Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the","Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica","Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic","Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji","Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana","Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala","Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia","Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan","Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis", +"Korea, Democratic People's Republic of","Korea, Republic of","Kuwait","Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania","Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali","Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives","Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua","Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia","Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau","Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan","Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname","Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand","Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","East Timor","Turkey","Trinidad and Tobago","Tuvalu","Taiwan","Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela","Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia and Montenegro","South Africa","Zambia","Zaire","Zimbabwe", +"Anonymous Proxy","Satellite Provider","Other"}; + +const char GeoIP_country_continent[247][3] = {"--","AS","EU","EU","AS","AS","SA","SA","EU","AS","SA","AF","AN","SA","OC","EU","OC","SA","AS","EU","SA","AS","EU","AF","EU","AS","AF","AF","SA","AS","SA","SA","SA","AS","AF","AF","EU","SA","NA","AS","AF","AF","AF","EU","AF","OC","SA","AF","AS","SA","SA","SA","AF","AS","AS","EU","EU","AF","EU","SA","SA","AF","SA","EU","AF","AF","AF","EU","AF","EU","OC","SA","OC","EU","EU","EU","AF","EU","SA","AS","SA","AF","EU","SA","AF","AF","SA","AF","EU","SA","SA","OC","AF","SA","AS","AF","SA","EU","SA","EU","AS","EU","AS","AS","AS","AS","AS","EU","EU","SA","AS","AS","AF","AS","AS","OC","AF","SA","AS","AS","AS","SA","AS","AS","AS","SA","EU","AS","AF","AF","EU","EU","EU","AF","AF","EU","EU","AF","OC","EU","AF","AS","AS","AS","OC","SA","AF","SA","EU","AF","AS","AF","NA","AS","AF","AF","OC","AF","OC","AF","SA","EU","EU","AS","OC","OC","OC","AS","SA","SA","OC","OC","AS","AS","EU","SA","OC","SA","AS","EU","OC","SA","AS","AF","EU","AS","AF","AS","OC","AF","AF","EU","AS","AF","EU","EU","EU","AF","EU","AF","AF","SA","AF","SA","AS","AF","SA","AF","AF","AF","AS","AS","OC","AS","AF","OC","AS","AS","SA","OC","AS","AF","EU","AF","OC","NA","SA","AS","EU","SA","SA","SA","SA","AS","OC","OC","OC","AS","AF","EU","AF","AF","AF","AF"}; + +const char * GeoIPDBDescription[NUM_DB_TYPES] = {NULL, "GeoIP Country Edition", "GeoIP City Edition, Rev 1", "GeoIP Region Edition, Rev 1", "GeoIP ISP Edition", "GeoIP Organization Edition", "GeoIP City Edition, Rev 0", "GeoIP Region Edition, Rev 0","GeoIP Proxy Edition","GeoIP ASNum Edition","GeoIP Netspeed Edition"}; + +char *_GeoIP_full_path_to(const char *file_name) { + char *path = malloc(sizeof(char) * 1024); + +#ifndef _WIN32 + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", "/home/ivan/geoip.dat", file_name); +#else + char buf[MAX_PATH], *p, *q = NULL; + int len; + memset(buf, 0, sizeof(buf)); + len = GetModuleFileName(GetModuleHandle(NULL), buf, sizeof(buf) - 1); + for (p = buf + len; p > buf; p--) + if (*p == '\\') + { + if (!q) + q = p; + else + *p = '/'; + } + *q = 0; + memset(path, 0, sizeof(char) * 1024); + snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name); +#endif + + return path; +} + +char ** GeoIPDBFileName = NULL; + +void _GeoIP_setup_dbfilename() { + if (NULL == GeoIPDBFileName) { + GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES); + memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES); + + GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = _GeoIP_full_path_to("GeoIPRegion.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = _GeoIP_full_path_to("GeoIPCity.dat"); + GeoIPDBFileName[GEOIP_ISP_EDITION] = _GeoIP_full_path_to("GeoIPISP.dat"); + GeoIPDBFileName[GEOIP_ORG_EDITION] = _GeoIP_full_path_to("GeoIPOrg.dat"); + GeoIPDBFileName[GEOIP_PROXY_EDITION] = _GeoIP_full_path_to("GeoIPProxy.dat"); + GeoIPDBFileName[GEOIP_ASNUM_EDITION] = _GeoIP_full_path_to("GeoIPASNum.dat"); + GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = _GeoIP_full_path_to("GeoIPNetSpeed.dat"); + } +} + +static +int _file_exists(const char *file_name) { + struct stat file_stat; + return( (stat(file_name, &file_stat) == 0) ? 1:0); +} + +int GeoIP_db_avail(int type) { + const char * filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + return 0; + } + filePath = GeoIPDBFileName[type]; + if (NULL == filePath) { + return 0; + } + return _file_exists(filePath); +} + +static +void _setup_segments(GeoIP * gi) { + int i, j; + unsigned char delim[3]; + unsigned char buf[SEGMENT_RECORD_LENGTH]; + + /* default to GeoIP Country Edition */ + gi->databaseType = GEOIP_COUNTRY_EDITION; + gi->record_length = STANDARD_RECORD_LENGTH; + fseek(gi->GeoIPDatabase, -3l, SEEK_END); + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + fread(delim, 1, 3, gi->GeoIPDatabase); + if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { + fread(&gi->databaseType, 1, 1, gi->GeoIPDatabase); + if (gi->databaseType >= 106) { + /* backwards compatibility with databases from April 2003 and earlier */ + gi->databaseType -= 105; + } + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = STATE_BEGIN_REV0; + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = STATE_BEGIN_REV1; + } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 || + gi->databaseType == GEOIP_CITY_EDITION_REV1 || + gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ISP_EDITION || + gi->databaseType == GEOIP_ASNUM_EDITION) { + /* City/Org Editions have two segments, read offset of second segment */ + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = 0; + fread(buf, SEGMENT_RECORD_LENGTH, 1, gi->GeoIPDatabase); + for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) { + gi->databaseSegments[0] += (buf[j] << (j * 8)); + } + if (gi->databaseType == GEOIP_ORG_EDITION || + gi->databaseType == GEOIP_ISP_EDITION) + gi->record_length = ORG_RECORD_LENGTH; + } + break; + } else { + fseek(gi->GeoIPDatabase, -4l, SEEK_CUR); + } + } + if (gi->databaseType == GEOIP_COUNTRY_EDITION || + gi->databaseType == GEOIP_PROXY_EDITION || + gi->databaseType == GEOIP_NETSPEED_EDITION) { + gi->databaseSegments = malloc(sizeof(int)); + gi->databaseSegments[0] = COUNTRY_BEGIN; + } +} + +static +int _check_mtime(GeoIP *gi) { + struct stat buf; + + if (gi->flags & GEOIP_CHECK_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) != -1) { + if (buf.st_mtime > gi->mtime) { + /* GeoIP Database file updated */ + if (gi->flags & GEOIP_MEMORY_CACHE) { + /* reload database into memory cache */ + if (realloc(gi->cache, buf.st_size) != NULL) { + if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != (size_t) buf.st_size) { + fprintf(stderr,"Error reading file %s\n",gi->file_path); + return -1; + } + gi->mtime = buf.st_mtime; + } + } else { + /* refresh filehandle */ + fclose(gi->GeoIPDatabase); + if (gi->databaseSegments != NULL) + free(gi->databaseSegments); + gi->GeoIPDatabase = fopen(gi->file_path,"rb"); + if (gi->GeoIPDatabase == NULL) { + fprintf(stderr,"Error Opening file %s\n",gi->file_path); + return -1; + } + _setup_segments(gi); + } + } + } + } + return 0; +} + +unsigned int _GeoIP_seek_record (GeoIP *gi, unsigned long ipnum) { + int depth; + unsigned int x; + unsigned char stack_buffer[2 * MAX_RECORD_LENGTH]; + const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL; + unsigned int offset = 0; + + const unsigned char * p; + int j; + + _check_mtime(gi); + for (depth = 31; depth >= 0; depth--) { + if (gi->cache == NULL && gi->index_cache == NULL) { + /* read from disk */ + fseek(gi->GeoIPDatabase, (long)gi->record_length * 2 * offset, SEEK_SET); + fread(stack_buffer,gi->record_length,2,gi->GeoIPDatabase); + } else if (gi->index_cache == NULL) { + /* simply point to record in memory */ + buf = gi->cache + (long)gi->record_length * 2 *offset; + } else { + buf = gi->index_cache + (long)gi->record_length * 2 * offset; + } + + if (ipnum & (1 << depth)) { + /* Take the right-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*1 + 0] << (0*8)) + + (buf[3*1 + 1] << (1*8)) + + (buf[3*1 + 2] << (2*8)); + + } else { + /* General case */ + j = gi->record_length; + p = &buf[2*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + + } else { + /* Take the left-hand branch */ + if ( gi->record_length == 3 ) { + /* Most common case is completely unrolled and uses constants. */ + x = (buf[3*0 + 0] << (0*8)) + + (buf[3*0 + 1] << (1*8)) + + (buf[3*0 + 2] << (2*8)); + } else { + /* General case */ + j = gi->record_length; + p = &buf[1*j]; + x = 0; + do { + x <<= 8; + x += *(--p); + } while ( --j ); + } + } + + if (x >= gi->databaseSegments[0]) { + return x; + } + offset = x; + } + + /* shouldn't reach here */ + fprintf(stderr,"Error Traversing Database for ipnum = %lu - Perhaps database is corrupt?\n",ipnum); + return 0; +} + +unsigned long _GeoIP_addr_to_num (const char *addr) { + int i; + char tok[4]; + int octet; + int j = 0, k = 0; + unsigned long ipnum = 0; + char c = 0; + + for (i=0; i<4; i++) { + for (;;) { + c = addr[k++]; + if (c == '.' || c == '\0') { + tok[j] = '\0'; + octet = atoi(tok); + if (octet > 255) + return 0; + ipnum += (octet << ((3-i)*8)); + j = 0; + break; + } else if (c >= '0' && c<= '9') { + if (j > 2) { + return 0; + } + tok[j++] = c; + } else { + return 0; + } + } + if(c == '\0' && i<3) { + return 0; + } + } + return ipnum; +} + +GeoIP* GeoIP_open_type (int type, int flags) { + GeoIP * gi; + const char * filePath; + if (type < 0 || type >= NUM_DB_TYPES) { + printf("Invalid database type %d\n", type); + return NULL; + } + _GeoIP_setup_dbfilename(); + filePath = GeoIPDBFileName[type]; + if (filePath == NULL) { + printf("Invalid database type %d\n", type); + return NULL; + } + gi = GeoIP_open (filePath, flags); + return gi; +} + +GeoIP* GeoIP_new (int flags) { + GeoIP * gi; + _GeoIP_setup_dbfilename(); + gi = GeoIP_open (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags); + return gi; +} + +GeoIP* GeoIP_open (const char * filename, int flags) { + struct stat buf; +#ifdef _WIN32 + WSADATA wsa; + if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0) + return NULL; +#endif + + GeoIP *gi = (GeoIP *)malloc(sizeof(GeoIP)); + if (gi == NULL) + return NULL; + gi->file_path = malloc(sizeof(char) * (strlen(filename)+1)); + if (gi->file_path == NULL) + return NULL; + strcpy(gi->file_path, filename); + gi->GeoIPDatabase = fopen(filename,"rb"); + if (gi->GeoIPDatabase == NULL) { + fprintf(stderr,"Error Opening file %s\n",filename); + free(gi->file_path); + free(gi); + return NULL; + } else { + if (flags & GEOIP_MEMORY_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + fprintf(stderr,"Error stating file %s\n",filename); + free(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + gi->cache = (unsigned char *) malloc(sizeof(unsigned char) * buf.st_size); + if (gi->cache != NULL) { + if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != (size_t) buf.st_size) { + fprintf(stderr,"Error reading file %s\n",filename); + free(gi->cache); + free(gi); + return NULL; + } + } + } else { + if (flags & GEOIP_CHECK_CACHE) { + if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) { + fprintf(stderr,"Error stating file %s\n",filename); + free(gi); + return NULL; + } + gi->mtime = buf.st_mtime; + } + gi->cache = NULL; + } + gi->flags = flags; + _setup_segments(gi); + if (flags & GEOIP_INDEX_CACHE) { + gi->index_cache = (unsigned char *) malloc(sizeof(unsigned char) * ((gi->databaseSegments[0] * (long)gi->record_length * 2))); + if (gi->index_cache != NULL) { + fseek(gi->GeoIPDatabase, 0, SEEK_SET); + if (fread(gi->index_cache, sizeof(unsigned char), gi->databaseSegments[0] * (long)gi->record_length * 2, gi->GeoIPDatabase) != (size_t) (gi->databaseSegments[0]*(long)gi->record_length * 2)) { + fprintf(stderr,"Error reading file %s\n",filename); + free(gi->index_cache); + free(gi); + return NULL; + } + } + } else { + gi->index_cache = NULL; + } + return gi; + } +} + +void GeoIP_delete (GeoIP *gi) { + if (gi->GeoIPDatabase != NULL) + fclose(gi->GeoIPDatabase); + if (gi->cache != NULL) + free(gi->cache); + if (gi->index_cache != NULL) + free(gi->index_cache); + if (gi->file_path != NULL) + free(gi->file_path); + if (gi->databaseSegments != NULL) + free(gi->databaseSegments); + free(gi); +} + +const char *GeoIP_country_code_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +const char *GeoIP_country_name_by_name (GeoIP* gi, const char *name) { + int country_id; + country_id = GeoIP_id_by_name(gi, name); + return (country_id > 0) ? GeoIP_country_name[country_id] : NULL; +} + +unsigned long _GeoIP_lookupaddress (const char *host) { + unsigned long addr = inet_addr(host); + struct hostent phe2; + struct hostent * phe = &phe2; + char *buf = NULL; + int buflength = 16384; + int herr = 0; + int result = 0; +#ifdef HAVE_GETHOSTBYNAME_R + buf = malloc(buflength); +#endif + if (addr == INADDR_NONE) { +#ifdef HAVE_GETHOSTBYNAME_R + while (1) { + /* we use gethostbyname_r here because it is thread-safe and gethostbyname is not */ +#ifdef GETHOSTBYNAME_R_RETURNS_INT + result = gethostbyname_r(host,&phe2,buf,buflength,&phe,&herr); +#else + phe = gethostbyname_r(host,&phe2,buf,buflength,&herr); +#endif + if (herr != ERANGE) + break; + if (result == 0) + break; + /* double the buffer if the buffer is too small */ + buflength = buflength * 2; + buf = realloc(buf,buflength); + } +#endif +#ifndef HAVE_GETHOSTBYNAME_R + /* Some systems do not support gethostbyname_r, such as Mac OS X */ + phe = gethostbyname(host); +#endif + if (!phe || result != 0) { + free(buf); + return 0; + } + addr = *((unsigned long *) phe->h_addr_list[0]); + } +#ifdef HAVE_GETHOSTBYNAME_R + free(buf); +#endif + return ntohl(addr); +} + +int GeoIP_id_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + int ret; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && gi->databaseType != GEOIP_PROXY_EDITION && gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN; + return ret; + +} + +const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; + return GeoIP_country_code3[country_id]; +} + +const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr) { + int country_id; + country_id = GeoIP_id_by_addr(gi, addr); + return (country_id > 0) ? GeoIP_country_name[country_id] : NULL; + return GeoIP_country_name[country_id]; +} + +const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return (country_id > 0) ? GeoIP_country_name[country_id] : NULL; +} + +const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code[country_id] : NULL; +} + +const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int country_id; + country_id = GeoIP_id_by_ipnum(gi, ipnum); + return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL; +} + +int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr) { + return GeoIP_id_by_addr(gi, addr); +} + +int GeoIP_country_id_by_name (GeoIP* gi, const char *host) { + return GeoIP_id_by_name(gi, host); +} + +int GeoIP_id_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + int ret; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + ipnum = _GeoIP_addr_to_num(addr); + ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN; + return ret; +} + +int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum) { + int ret; + if (ipnum == 0) { + return 0; + } + if (gi->databaseType != GEOIP_COUNTRY_EDITION && + gi->databaseType != GEOIP_PROXY_EDITION && + gi->databaseType != GEOIP_NETSPEED_EDITION) { + printf("Invalid database type %s, expected %s\n", + GeoIPDBDescription[(int)gi->databaseType], + GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); + return 0; + } + ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN; + return ret; +} + +char *GeoIP_database_info (GeoIP* gi) { + int i; + unsigned char buf[3]; + char *retval; + int hasStructureInfo = 0; + + if(gi == NULL) + return NULL; + + _check_mtime(gi); + fseek(gi->GeoIPDatabase, -3l, SEEK_END); + + /* first get past the database structure information */ + for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) { + fread(buf, 1, 3, gi->GeoIPDatabase); + if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) { + hasStructureInfo = 1; + break; + } + fseek(gi->GeoIPDatabase, -4l, SEEK_CUR); + } + if (hasStructureInfo == 1) { + fseek(gi->GeoIPDatabase, -3l, SEEK_CUR); + } else { + /* no structure info, must be pre Sep 2002 database, go back to end */ + fseek(gi->GeoIPDatabase, -3l, SEEK_END); + } + + for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) { + fread(buf, 1, 3, gi->GeoIPDatabase); + if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) { + retval = malloc(sizeof(char) * (i+1)); + if (retval == NULL) { + return NULL; + } + fread(retval, 1, i, gi->GeoIPDatabase); + retval[i] = '\0'; + return retval; + } + fseek(gi->GeoIPDatabase, -4l, SEEK_CUR); + } + return NULL; +} + +/* GeoIP Region Edition functions */ + +void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *region) { + unsigned int seek_region; + + /* This also writes in the terminating NULs (if you decide to + * keep them) and clear any fields that are not set. */ + memset(region, 0, sizeof(GeoIPRegion)); + + seek_region = _GeoIP_seek_record(gi, ntohl(inetaddr)); + + if (gi->databaseType == GEOIP_REGION_EDITION_REV0) { + /* Region Edition, pre June 2003 */ + seek_region -= STATE_BEGIN_REV0; + if (seek_region >= 1000) { + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - 1000)/26 + 65); + region->region[1] = (char) ((seek_region - 1000)%26 + 65); + } else { + memcpy(region->country_code, GeoIP_country_code[seek_region], 2); + } + } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) { + /* Region Edition, post June 2003 */ + seek_region -= STATE_BEGIN_REV1; + if (seek_region < US_OFFSET) { + /* Unknown */ + /* we don't need to do anything here b/c we memset region to 0 */ + } else if (seek_region < CANADA_OFFSET) { + /* USA State */ + region->country_code[0] = 'U'; + region->country_code[1] = 'S'; + region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65); + } else if (seek_region < WORLD_OFFSET) { + /* Canada Province */ + region->country_code[0] = 'C'; + region->country_code[1] = 'A'; + region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65); + region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65); + } else { + /* Not US or Canada */ + memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2); + } + } +} + +static +GeoIPRegion * _get_region(GeoIP* gi, unsigned long ipnum) { + GeoIPRegion * region; + + region = malloc(sizeof(GeoIPRegion)); + if (region) { + GeoIP_assign_region_by_inetaddr(gi, htonl(ipnum), region); + } + return region; +} + +GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + if (addr == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + ipnum = _GeoIP_addr_to_num(addr); + return _get_region(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + return _get_region(gi, ipnum); +} + +GeoIPRegion * GeoIP_region_by_ipnum (GeoIP* gi, unsigned long ipnum) { + if (gi->databaseType != GEOIP_REGION_EDITION_REV0 && + gi->databaseType != GEOIP_REGION_EDITION_REV1) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]); + return 0; + } + return _get_region(gi, ipnum); +} + +void GeoIPRegion_delete (GeoIPRegion *gir) { + free(gir); +} + +/* GeoIP Organization, ISP and AS Number Edition private method */ +static +char *_get_name (GeoIP* gi, unsigned long ipnum) { + int seek_org; + char buf[MAX_ORG_RECORD_LENGTH]; + char * org_buf, * buf_pointer; + int record_pointer; + + if (gi->databaseType != GEOIP_ORG_EDITION && + gi->databaseType != GEOIP_ISP_EDITION && + gi->databaseType != GEOIP_ASNUM_EDITION) { + printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_ORG_EDITION]); + return 0; + } + + seek_org = _GeoIP_seek_record(gi, ipnum); + if (seek_org == gi->databaseSegments[0]) + return NULL; + + record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0]; + + if (gi->cache == NULL) { + fseek(gi->GeoIPDatabase, record_pointer, SEEK_SET); + fread(buf, sizeof(char), MAX_ORG_RECORD_LENGTH, gi->GeoIPDatabase); + org_buf = malloc(sizeof(char) * (strlen(buf)+1)); + strcpy(org_buf, buf); + } else { + buf_pointer = gi->cache + (long)record_pointer; + org_buf = malloc(sizeof(char) * (strlen(buf_pointer)+1)); + strcpy(org_buf, buf_pointer); + } + return org_buf; +} + +char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum) { + return _get_name(gi,ipnum); +} + +char *GeoIP_name_by_addr (GeoIP* gi, const char *addr) { + unsigned long ipnum; + if (addr == NULL) { + return 0; + } + ipnum = _GeoIP_addr_to_num(addr); + return _get_name(gi, ipnum); +} + +char *GeoIP_name_by_name (GeoIP* gi, const char *name) { + unsigned long ipnum; + if (name == NULL) { + return 0; + } + if (!(ipnum = _GeoIP_lookupaddress(name))) + return 0; + return _get_name(gi, ipnum); +} + +char *GeoIP_org_by_ipnum (GeoIP* gi, unsigned long ipnum) { + return GeoIP_name_by_ipnum(gi, ipnum); +} + +char *GeoIP_org_by_addr (GeoIP* gi, const char *addr) { + return GeoIP_name_by_addr(gi, addr); +} + +char *GeoIP_org_by_name (GeoIP* gi, const char *name) { + return GeoIP_name_by_name(gi, name); +} + +unsigned char GeoIP_database_edition (GeoIP* gi) { + return gi->databaseType; +} diff --git a/plugins/infowidget/GeoIP.h b/plugins/infowidget/GeoIP.h new file mode 100644 index 0000000..1403e4d --- /dev/null +++ b/plugins/infowidget/GeoIP.h @@ -0,0 +1,161 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* GeoIP.h + * + * Copyright (C) 2003 MaxMind LLC + * + * This library 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.1 of the License, or (at your option) any later version. + * + * This library 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 library; if not, write to the Free Software + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef GEOIP_H +#define GEOIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include <sys/types.h> /* for fstat */ +#include <sys/stat.h> /* for fstat */ + +#define SEGMENT_RECORD_LENGTH 3 +#define STANDARD_RECORD_LENGTH 3 +#define ORG_RECORD_LENGTH 4 +#define MAX_RECORD_LENGTH 4 +#define NUM_DB_TYPES 16 + +typedef struct GeoIPTag { + FILE *GeoIPDatabase; + char *file_path; + unsigned char *cache; + unsigned char *index_cache; + unsigned int *databaseSegments; + char databaseType; + time_t mtime; + int flags; + char record_length; + int record_iter; /* used in GeoIP_next_record */ +} GeoIP; + +typedef struct GeoIPRegionTag { + char country_code[3]; + char region[3]; +} GeoIPRegion; + +typedef enum { + GEOIP_STANDARD = 0, + GEOIP_MEMORY_CACHE = 1, + GEOIP_CHECK_CACHE = 2, + GEOIP_INDEX_CACHE = 4 +} GeoIPOptions; + +typedef enum { + GEOIP_COUNTRY_EDITION = 1, + GEOIP_REGION_EDITION_REV0 = 7, + GEOIP_CITY_EDITION_REV0 = 6, + GEOIP_ORG_EDITION = 5, + GEOIP_ISP_EDITION = 4, + GEOIP_CITY_EDITION_REV1 = 2, + GEOIP_REGION_EDITION_REV1 = 3, + GEOIP_PROXY_EDITION = 8, + GEOIP_ASNUM_EDITION = 9, + GEOIP_NETSPEED_EDITION = 10 +} GeoIPDBTypes; + +typedef enum { + GEOIP_ANON_PROXY = 1, + GEOIP_HTTP_X_FORWARDED_FOR_PROXY = 2, + GEOIP_HTTP_CLIENT_IP_PROXY = 3 +} GeoIPProxyTypes; + +typedef enum { + GEOIP_UNKNOWN_SPEED = 0, + GEOIP_DIALUP_SPEED = 1, + GEOIP_CABLEDSL_SPEED = 2, + GEOIP_CORPORATE_SPEED = 3 +} GeoIPNetspeedValues; + +extern char **GeoIPDBFileName; +extern const char * GeoIPDBDescription[NUM_DB_TYPES]; +extern const char *GeoIPCountryDBFileName; +extern const char *GeoIPRegionDBFileName; +extern const char *GeoIPCityDBFileName; +extern const char *GeoIPOrgDBFileName; +extern const char *GeoIPISPDBFileName; + +extern const char GeoIP_country_code[247][3]; +extern const char GeoIP_country_code3[247][4]; +extern const char * GeoIP_country_name[247]; +extern const char GeoIP_country_continent[247][3]; + +#ifdef DLL +#define GEOIP_API __declspec(dllexport) +#else +#define GEOIP_API +#endif /* DLL */ + +GEOIP_API GeoIP* GeoIP_open_type (int type, int flags); +GEOIP_API GeoIP* GeoIP_new(int flags); +GEOIP_API GeoIP* GeoIP_open(const char * filename, int flags); +GEOIP_API int GeoIP_db_avail(int type); +GEOIP_API void GeoIP_delete(GeoIP* gi); +GEOIP_API const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr); +GEOIP_API const char *GeoIP_country_name_by_name (GeoIP* gi, const char *host); +GEOIP_API const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum); + +/* Deprecated - for backwards compatibility only */ +GEOIP_API int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_country_id_by_name (GeoIP* gi, const char *host); +GEOIP_API char *GeoIP_org_by_addr (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_org_by_name (GeoIP* gi, const char *host); +/* End deprecated */ + +GEOIP_API int GeoIP_id_by_addr (GeoIP* gi, const char *addr); +GEOIP_API int GeoIP_id_by_name (GeoIP* gi, const char *host); +GEOIP_API int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum); + +GEOIP_API GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr); +GEOIP_API GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *host); +GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum (GeoIP *gi, unsigned long ipnum); + +/* Warning - don't call this after GeoIP_assign_region_by_inetaddr calls */ +GEOIP_API void GeoIPRegion_delete (GeoIPRegion *gir); + +GEOIP_API void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *gir); + +/* Used to query GeoIP Organization, ISP and AS Number databases */ +GEOIP_API char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum); +GEOIP_API char *GeoIP_name_by_addr (GeoIP* gi, const char *addr); +GEOIP_API char *GeoIP_name_by_name (GeoIP* gi, const char *host); + +GEOIP_API char *GeoIP_database_info (GeoIP* gi); +GEOIP_API unsigned char GeoIP_database_edition (GeoIP* gi); + +#ifdef BSD +#define memcpy(dest, src, n) bcopy(src, dest, n) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* GEOIP_H */ diff --git a/plugins/infowidget/Makefile.am b/plugins/infowidget/Makefile.am new file mode 100644 index 0000000..66a5820 --- /dev/null +++ b/plugins/infowidget/Makefile.am @@ -0,0 +1,40 @@ +INCLUDES = -I$(srcdir)/../../libktorrent $(all_includes) +METASOURCES = AUTO +kde_module_LTLIBRARIES = ktinfowidgetplugin.la +noinst_HEADERS = infowidgetplugin.h infowidgetprefpage.h trackerview.h GeoIP.h \ + statustab.h fileview.h +ktinfowidgetplugin_la_SOURCES = infowidgetplugin.cpp availabilitychunkbar.cpp \ + chunkbar.cpp chunkdownloadview.cpp downloadedchunkbar.cpp flagdb.cpp peerview.cpp \ + ktorrentmonitor.cpp iwfiletreediritem.cpp iwfiletreeitem.cpp infowidgetprefpage.cpp \ + infowidgetpluginsettings.kcfgc iwpref.ui trackerviewbase.ui trackerview.cpp floatspinbox.cpp \ + localefloatvalidator.cpp chunkdownloadviewbase.ui statustabbase.ui statustab.cpp fileview.cpp + +# Libs needed by the plugin +ktinfowidgetplugin_la_LIBADD = ../../libktorrent/libktorrent.la \ + $(LIB_KHTML) $(LIB_KPARTS) $(LIB_QT) \ + $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KFILE) + + +# LD flags for the plugin +# -module says: this is a module, i.e. something you're going to dlopen +# so e.g. it has no version number like a normal shared lib would have. +ktinfowidgetplugin_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) +if USE_SYSTEM_GEOIP +ktinfowidgetplugin_la_LDFLAGS += -lGeoIP +else +ktinfowidgetplugin_la_SOURCES += GeoIP.c +endif + +# rc file containing the GUI for the plugin +# pluginsdir = $(kde_datadir)/ktsearchplugin +# plugins_DATA = ktsearchpluginui.rc + +# Install the desktop file needed to detect the plugin +kde_services_DATA = ktinfowidgetplugin.desktop + +kde_kcfg_DATA = ktinfowidgetplugin.kcfg + +ktdatadir = $(kde_datadir)/ktorrent/geoip + +SUBDIRS = geoip +KDE_CXXFLAGS = $(USE_EXCEPTIONS) $(USE_RTTI) diff --git a/plugins/infowidget/availabilitychunkbar.cpp b/plugins/infowidget/availabilitychunkbar.cpp new file mode 100644 index 0000000..9d96268 --- /dev/null +++ b/plugins/infowidget/availabilitychunkbar.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * 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 <qtooltip.h> +#include <klocale.h> + +#include <util/bitset.h> +#include <interfaces/torrentinterface.h> +#include "availabilitychunkbar.h" + +namespace kt +{ + +AvailabilityChunkBar::AvailabilityChunkBar(QWidget* parent, const char* name): ChunkBar(parent, name) +{ + QToolTip::add(this, i18n("<img src=\"available_color\"> - Available Chunks<br><img src=\"unavailable_color\"> - Unavailable Chunks<br><img src=\"excluded_color\"> - Excluded Chunks")); +} + + +AvailabilityChunkBar::~AvailabilityChunkBar() +{ +} + + +const bt::BitSet & AvailabilityChunkBar::getBitSet() const +{ + if (curr_tc) + return curr_tc->availableChunksBitSet(); + else + return bt::BitSet::null; +} +} + +#include "availabilitychunkbar.moc" diff --git a/plugins/infowidget/availabilitychunkbar.h b/plugins/infowidget/availabilitychunkbar.h new file mode 100644 index 0000000..a5ae625 --- /dev/null +++ b/plugins/infowidget/availabilitychunkbar.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 AVAILABILITYCHUNKBAR_H +#define AVAILABILITYCHUNKBAR_H + +#include "chunkbar.h" + +namespace kt +{ + + /** + @author Joris Guisson + */ + class AvailabilityChunkBar : public ChunkBar + { + Q_OBJECT + public: + AvailabilityChunkBar(QWidget* parent, const char* name); + virtual ~AvailabilityChunkBar(); + + virtual const bt::BitSet & getBitSet() const; + + }; +} + +#endif diff --git a/plugins/infowidget/chunkbar.cpp b/plugins/infowidget/chunkbar.cpp new file mode 100644 index 0000000..a30571a --- /dev/null +++ b/plugins/infowidget/chunkbar.cpp @@ -0,0 +1,312 @@ +/*************************************************************************** + * Copyright (C) 2005 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * * + * 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 <qpainter.h> +#include <qpen.h> +#include <qbrush.h> +#include <qvaluelist.h> +#include <qpixmap.h> +#include <math.h> +#include <qtooltip.h> +#include <klocale.h> +#include <qmime.h> +#include <qimage.h> +#include <util/log.h> +#include <interfaces/torrentinterface.h> +#include <util/bitset.h> +#include <torrent/globals.h> +#include "chunkbar.h" + +using namespace bt; +using namespace kt; + +namespace kt +{ + + struct Range + { + int first,last; + int fac; + }; + + + static void FillAndFrameBlack(QImage* image, uint color, int size) + { + image->fill(color); + for (int i = 0; i < size; i++) + { + image->setPixel(0, i, 0); + image->setPixel(size - 1, i, 0); + image->setPixel(i, 0, 0); + image->setPixel(i, size - 1, 0); + } + } + + + + static void InitializeToolTipImages(ChunkBar* bar) + { + static bool images_initialized = false; + if (images_initialized) + return; + images_initialized = true; + + QMimeSourceFactory* factory = QMimeSourceFactory::defaultFactory(); + + QImage excluded(16, 16, 32); + FillAndFrameBlack(&excluded, bar->colorGroup().color(QColorGroup::Mid).pixel(), 16); + factory->setImage("excluded_color", excluded); + + QImage available(16, 16, 32); + FillAndFrameBlack(&available, bar->colorGroup().highlight().pixel(), 16); + factory->setImage("available_color", available); + + QImage unavailable(16, 16, 32); + FillAndFrameBlack(&unavailable, bar->colorGroup().base().pixel(), 16); + factory->setImage("unavailable_color", unavailable); + } + + ChunkBar::ChunkBar(QWidget *parent, const char *name) + : QFrame(parent, name),curr_tc(0) + { + setFrameShape(StyledPanel); + setFrameShadow(Sunken); + setLineWidth(3); + setMidLineWidth(3); + + show_excluded = false; + + InitializeToolTipImages(this); + + QToolTip::add(this, i18n("<img src=\"available_color\"> - Downloaded Chunks<br><img src=\"unavailable_color\"> - Chunks to Download<br><img src=\"excluded_color\"> - Excluded Chunks")); + + } + + + ChunkBar::~ChunkBar() + {} + + void ChunkBar::updateBar() + { + const BitSet & bs = getBitSet(); + QSize s = contentsRect().size(); + bool changed = !(curr == bs); + if (show_excluded && curr_tc) + { + BitSet ebs = curr_tc->excludedChunksBitSet(); + ebs.orBitSet(curr_tc->onlySeedChunksBitSet()), + changed = changed || !(curr_ebs == ebs); + curr_ebs = ebs; + } + + if (changed || pixmap.isNull() || pixmap.width() != s.width()) + { + // PROFILE("ChunkBar::updateBar"); + // Out() << "Pixmap : " << s.width() << " " << s.height() << endl; + pixmap.resize(s); + pixmap.fill(colorGroup().color(QColorGroup::Base)); + QPainter painter(&pixmap); + drawBarContents(&painter); + update(); + } + } + + void ChunkBar::drawContents(QPainter *p) + { + // first draw background + if (isEnabled()) + p->setBrush(colorGroup().base()); + else + p->setBrush(colorGroup().background()); + + p->setPen(Qt::NoPen); + p->drawRect(contentsRect()); + if (isEnabled()) + p->drawPixmap(contentsRect(),pixmap); + } + + void ChunkBar::setTC(kt::TorrentInterface* tc) + { + curr_tc = tc; + QSize s = contentsRect().size(); + //Out() << "Pixmap : " << s.width() << " " << s.height() << endl; + pixmap.resize(s); + pixmap.fill(colorGroup().color(QColorGroup::Base)); + QPainter painter(&pixmap); + drawBarContents(&painter); + update(); + } + + void ChunkBar::drawBarContents(QPainter *p) + { + p->saveWorldMatrix(); + if (curr_tc) + { + const TorrentStats & s = curr_tc->getStats(); + Uint32 w = contentsRect().width(); + const BitSet & bs = getBitSet(); + curr = bs; + if (bs.allOn()) + drawAllOn(p,colorGroup().highlight()); + else if (s.total_chunks > w) + drawMoreChunksThenPixels(p,bs,colorGroup().highlight()); + else + drawEqual(p,bs,colorGroup().highlight()); + + if (show_excluded && s.num_chunks_excluded > 0) + { + QColor c = colorGroup().color(QColorGroup::Mid); + if (curr_ebs.allOn()) + drawAllOn(p,c); + else if (s.total_chunks > w) + drawMoreChunksThenPixels(p,curr_ebs,c); + else + drawEqual(p,curr_ebs,c); + } + } + p->restoreWorldMatrix(); + } + + void ChunkBar::drawEqual(QPainter *p,const BitSet & bs,const QColor & color) + { + //p->setPen(QPen(colorGroup().highlight(),1,Qt::SolidLine)); + QColor c = color; + + Uint32 w = contentsRect().width(); + double scale = 1.0; + Uint32 total_chunks = curr_tc->getStats().total_chunks; + if (curr_tc->getStats().total_chunks != w) + scale = (double)w / total_chunks; + + p->setPen(QPen(c,1,Qt::SolidLine)); + p->setBrush(c); + + QValueList<Range> rs; + + for (Uint32 i = 0;i < bs.getNumBits();i++) + { + if (!bs.get(i)) + continue; + + if (rs.empty()) + { + Range r = {i,i,0}; + rs.append(r); + } + else + { + Range & l = rs.last(); + if (l.last == int(i - 1)) + { + l.last = i; + } + else + { + Range r = {i,i,0}; + rs.append(r); + } + } + } + + QRect r = contentsRect(); + + for (QValueList<Range>::iterator i = rs.begin();i != rs.end();++i) + { + Range & ra = *i; + int rw = ra.last - ra.first + 1; + p->drawRect((int)(scale * ra.first),0,(int)(rw * scale),r.height()); + } + } + + void ChunkBar::drawMoreChunksThenPixels(QPainter *p,const BitSet & bs,const QColor & color) + { + Uint32 w = contentsRect().width(); + double chunks_per_pixel = (double)bs.getNumBits() / w; + QValueList<Range> rs; + + for (Uint32 i = 0;i < w;i++) + { + Uint32 num_dl = 0; + Uint32 jStart = (Uint32) (i*chunks_per_pixel); + Uint32 jEnd = (Uint32) ((i+1)*chunks_per_pixel+0.5); + for (Uint32 j = jStart;j < jEnd;j++) + if (bs.get(j)) + num_dl++; + + if (num_dl == 0) + continue; + + int fac = int(100*((double)num_dl / (jEnd - jStart)) + 0.5); + if (rs.empty()) + { + Range r = {i,i,fac}; + rs.append(r); + } + else + { + Range & l = rs.last(); + if (l.last == int(i - 1) && l.fac == fac) + { + l.last = i; + } + else + { + Range r = {i,i,fac}; + rs.append(r); + } + } + } + + QRect r = contentsRect(); + + for (QValueList<Range>::iterator i = rs.begin();i != rs.end();++i) + { + Range & ra = *i; + int rw = ra.last - ra.first + 1; + int fac = ra.fac; + QColor c = color; + if (fac < 100) + { + // do some rounding off + if (fac <= 25) + fac = 25; + else if (fac <= 50) + fac = 45; + else + fac = 65; + c = color.light(200-fac); + } + p->setPen(QPen(c,1,Qt::SolidLine)); + p->setBrush(c); + p->drawRect(ra.first,0,rw,r.height()); + } + + } + + void ChunkBar::drawAllOn(QPainter *p,const QColor & color) + { + p->setPen(QPen(color,1,Qt::SolidLine)); + p->setBrush(color); + QSize s = contentsRect().size(); + p->drawRect(0,0,s.width(),s.height()); + } +} + +#include "chunkbar.moc" diff --git a/plugins/infowidget/chunkbar.h b/plugins/infowidget/chunkbar.h new file mode 100644 index 0000000..6cf0d6a --- /dev/null +++ b/plugins/infowidget/chunkbar.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2005 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * * + * 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 CHUNKBAR_H +#define CHUNKBAR_H + +#include <qlabel.h> +#include <util/bitset.h> +#include <qpixmap.h> + +class QPainter; + +namespace kt +{ + class TorrentInterface; +} + +namespace bt +{ + class BitSet; +} + +namespace kt +{ + + /** + * @author Joris Guisson, Vincent Wagelaar + * + * Bar which displays BitSets, subclasses need to fill the BitSet. + * BitSets can represent which chunks are downloaded, which chunks are available + * and which chunks are excluded. + */ + class ChunkBar : public QFrame + { + Q_OBJECT + public: + ChunkBar(QWidget *parent = 0, const char *name = 0); + virtual ~ChunkBar(); + + void setTC(kt::TorrentInterface* tc); + + virtual const bt::BitSet & getBitSet() const = 0; + virtual void drawContents(QPainter *p); + virtual void updateBar(); + + private: + void drawEqual(QPainter *p,const bt::BitSet & bs,const QColor & color); + void drawMoreChunksThenPixels(QPainter *p,const bt::BitSet & bs,const QColor & color); + void drawAllOn(QPainter *p,const QColor & color); + void drawBarContents(QPainter *p); + + protected: + kt::TorrentInterface* curr_tc; + bool show_excluded; + bt::BitSet curr,curr_ebs; + QPixmap pixmap; + }; +} + +#endif diff --git a/plugins/infowidget/chunkdownloadview.cpp b/plugins/infowidget/chunkdownloadview.cpp new file mode 100644 index 0000000..276a311 --- /dev/null +++ b/plugins/infowidget/chunkdownloadview.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** + * 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 <klocale.h> +#include <qlabel.h> +#include <interfaces/chunkdownloadinterface.h> +#include <interfaces/functions.h> +#include <interfaces/torrentinterface.h> +#include "chunkdownloadview.h" + + +using namespace bt; +using namespace kt; + +namespace kt +{ + + ChunkDownloadViewItem::ChunkDownloadViewItem(KListView* cdv,kt::ChunkDownloadInterface* cd) + : KListViewItem(cdv),cd(cd) + { + update(); + } + + void ChunkDownloadViewItem::update() + { + ChunkDownloadInterface::Stats s; + cd->getStats(s); + + setText(0,QString::number(s.chunk_index)); + setText(1,QString("%1 / %2").arg(s.pieces_downloaded).arg(s.total_pieces)); + setText(2,s.current_peer_id); + setText(3,KBytesPerSecToString(s.download_speed / 1024.0)); + setText(4,QString::number(s.num_downloaders)); + } + + int ChunkDownloadViewItem::compare(QListViewItem * i,int col,bool) const + { + ChunkDownloadViewItem* it = (ChunkDownloadViewItem*)i; + kt::ChunkDownloadInterface* ocd = it->cd; + ChunkDownloadInterface::Stats s; + cd->getStats(s); + ChunkDownloadInterface::Stats os; + ocd->getStats(os); + switch (col) + { + case 0: return CompareVal(s.chunk_index,os.chunk_index); + case 1: return CompareVal(s.pieces_downloaded,os.pieces_downloaded); + case 2: return QString::compare(s.current_peer_id,os.current_peer_id); + case 3: return CompareVal(s.download_speed,os.download_speed); + case 4: return CompareVal(s.num_downloaders,os.num_downloaders); + } + return 0; + } + + + ChunkDownloadView::ChunkDownloadView(QWidget *parent, const char *name) + : ChunkDownloadViewBase(parent, name) + { + m_list_view->setShowSortIndicator(true); + m_list_view->setAllColumnsShowFocus(true); + + m_list_view->setColumnAlignment(0,Qt::AlignLeft); + m_list_view->setColumnAlignment(1,Qt::AlignCenter); + m_list_view->setColumnAlignment(3,Qt::AlignRight); + m_list_view->setColumnAlignment(4,Qt::AlignRight); + curr_tc = 0; + } + + + ChunkDownloadView::~ChunkDownloadView() + {} + + + void ChunkDownloadView::addDownload(kt::ChunkDownloadInterface* cd) + { + ChunkDownloadViewItem* it = new ChunkDownloadViewItem(m_list_view,cd); + items.insert(cd,it); + } + + void ChunkDownloadView::removeDownload(kt::ChunkDownloadInterface* cd) + { + if (!items.contains(cd)) + return; + + ChunkDownloadViewItem* it = items[cd]; + delete it; + items.remove(cd); + } + + void ChunkDownloadView::removeAll() + { + m_list_view->clear(); + items.clear(); + } + + void ChunkDownloadView::changeTC(kt::TorrentInterface* tc) + { + curr_tc = tc; + setEnabled(curr_tc != 0); + update(); + } + + void ChunkDownloadView::update() + { + if (!curr_tc) + return; + + QMap<ChunkDownloadInterface*,ChunkDownloadViewItem*>::iterator i = items.begin(); + while (i != items.end()) + { + ChunkDownloadViewItem* it = i.data(); + it->update(); + i++; + } + m_list_view->sort(); + + const TorrentStats & s = curr_tc->getStats(); + m_chunks_downloading->setText(QString::number(s.num_chunks_downloading)); + m_chunks_downloaded->setText(QString::number(s.num_chunks_downloaded)); + m_total_chunks->setText(QString::number(s.total_chunks)); + m_excluded_chunks->setText(QString::number(s.num_chunks_excluded)); + m_chunks_left->setText(QString::number(s.num_chunks_left)); + + if( s.chunk_size / 1024 < 1024 ) + m_size_chunks->setText(QString::number(s.chunk_size / 1024) + "." + QString::number((s.chunk_size % 1024) / 100) + " KB"); + else + m_size_chunks->setText(QString::number(s.chunk_size / 1024 / 1024) + "." + QString::number(((s.chunk_size / 1024) % 1024) / 100) + " MB"); + } + + void ChunkDownloadView::saveLayout(KConfig* cfg,const QString & group_name) + { + m_list_view->saveLayout(cfg,group_name); + } + + void ChunkDownloadView::restoreLayout(KConfig* cfg,const QString & group_name) + { + m_list_view->restoreLayout(cfg,group_name); + } + + void ChunkDownloadView::clear() + { + m_chunks_downloading->clear(); + m_chunks_downloaded->clear(); + m_total_chunks->clear(); + m_excluded_chunks->clear(); + m_size_chunks->clear(); + } +} + +#include "chunkdownloadview.moc" diff --git a/plugins/infowidget/chunkdownloadview.h b/plugins/infowidget/chunkdownloadview.h new file mode 100644 index 0000000..a00a746 --- /dev/null +++ b/plugins/infowidget/chunkdownloadview.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * 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 BTCHUNKDOWNLOADVIEW_H +#define BTCHUNKDOWNLOADVIEW_H + +#include <klistview.h> +#include <qmap.h> +#include "chunkdownloadviewbase.h" + +namespace kt +{ + class ChunkDownloadInterface; + class ChunkDownloadView; + + class ChunkDownloadViewItem : public KListViewItem + { + kt::ChunkDownloadInterface* cd; + public: + ChunkDownloadViewItem(KListView* cdv,kt::ChunkDownloadInterface* cd); + + void update(); + int compare(QListViewItem * i,int col,bool) const; + }; + + + /** + @author Joris Guisson + */ + class ChunkDownloadView : public ChunkDownloadViewBase + { + Q_OBJECT + + QMap<kt::ChunkDownloadInterface*,ChunkDownloadViewItem*> items; + kt::TorrentInterface* curr_tc; + public: + ChunkDownloadView(QWidget *parent = 0, const char *name = 0); + virtual ~ChunkDownloadView(); + + void saveLayout(KConfig* cfg,const QString & group_name); + void restoreLayout(KConfig* cfg,const QString & group_name); + void clear(); + void update(); + void changeTC(kt::TorrentInterface* tc); + + public slots: + void addDownload(kt::ChunkDownloadInterface* cd); + void removeDownload(kt::ChunkDownloadInterface* cd); + void removeAll(); + }; +} + + +#endif diff --git a/plugins/infowidget/chunkdownloadviewbase.ui b/plugins/infowidget/chunkdownloadviewbase.ui new file mode 100644 index 0000000..24a6e18 --- /dev/null +++ b/plugins/infowidget/chunkdownloadviewbase.ui @@ -0,0 +1,345 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ChunkDownloadViewBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ChunkDownloadViewBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>830</width> + <height>534</height> + </rect> + </property> + <property name="caption"> + <string>Chunks</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Total:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_total_chunks</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Currently downloading:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_chunks_downloading</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout13</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Downloaded:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_chunks_downloaded</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout38</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>Excluded:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_excluded_chunks</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout38_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4_2</cstring> + </property> + <property name="text"> + <string>Left:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_chunks_left</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_8</cstring> + </property> + <property name="text"> + <string>Size:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>m_size_chunks</cstring> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </hbox> + </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>40</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="KListView"> + <column> + <property name="text"> + <string>Chunk</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Progress</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Peer</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Down Speed</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Assigned Peers</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>m_list_view</cstring> + </property> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/plugins/infowidget/downloadedchunkbar.cpp b/plugins/infowidget/downloadedchunkbar.cpp new file mode 100644 index 0000000..ab87ff7 --- /dev/null +++ b/plugins/infowidget/downloadedchunkbar.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * 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/bitset.h> +#include <interfaces/torrentinterface.h> +#include "downloadedchunkbar.h" + +namespace kt +{ + + DownloadedChunkBar::DownloadedChunkBar(QWidget* parent, const char* name) + : ChunkBar(parent,name) + { + show_excluded = true; + } + + + DownloadedChunkBar::~DownloadedChunkBar() + {} + + + const bt::BitSet & DownloadedChunkBar::getBitSet() const + { + if (curr_tc) + return curr_tc->downloadedChunksBitSet(); + else + return bt::BitSet::null; + } +} + +#include "downloadedchunkbar.moc" diff --git a/plugins/infowidget/downloadedchunkbar.h b/plugins/infowidget/downloadedchunkbar.h new file mode 100644 index 0000000..996634f --- /dev/null +++ b/plugins/infowidget/downloadedchunkbar.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * 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 DOWNLOADEDCHUNKBAR_H +#define DOWNLOADEDCHUNKBAR_H + +#include "chunkbar.h" + +namespace kt +{ + /** + @author Joris Guisson + */ + class DownloadedChunkBar : public ChunkBar + { + Q_OBJECT + public: + DownloadedChunkBar(QWidget* parent, const char* name); + virtual ~DownloadedChunkBar(); + + virtual const bt::BitSet & getBitSet() const; + + }; +} + +#endif diff --git a/plugins/infowidget/fileview.cpp b/plugins/infowidget/fileview.cpp new file mode 100644 index 0000000..7fb56a6 --- /dev/null +++ b/plugins/infowidget/fileview.cpp @@ -0,0 +1,447 @@ +/*************************************************************************** + * 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 <klocale.h> +#include <kiconloader.h> +#include <kglobal.h> +#include <kpopupmenu.h> +#include <krun.h> +#include <kmessagebox.h> +#include <kmimetype.h> +#include <util/bitset.h> +#include <util/functions.h> +#include <interfaces/functions.h> +#include <interfaces/torrentinterface.h> +#include <interfaces/torrentfileinterface.h> +#include <qfileinfo.h> +#include "functions.h" +#include "iwfiletreeitem.h" +#include "iwfiletreediritem.h" +#include "fileview.h" + +using namespace bt; + +namespace kt +{ + + FileView::FileView(QWidget *parent, const char *name) + : KListView(parent, name),curr_tc(0),multi_root(0),pending_fill(0),next_fill_item(0) + { + setFrameShape(QFrame::NoFrame); + addColumn( i18n( "File" ) ); + addColumn( i18n( "Size" ) ); + addColumn( i18n( "Download" ) ); + addColumn( i18n( "Preview" ) ); + addColumn( i18n( "% Complete" ) ); + setShowSortIndicator(true); + + context_menu = new KPopupMenu(this); + preview_id = context_menu->insertItem(SmallIcon("fileopen"),i18n("Open")); + context_menu->insertSeparator(); + first_id = context_menu->insertItem(i18n("Download First")); + normal_id = context_menu->insertItem(i18n("Download Normally")); + last_id = context_menu->insertItem(i18n("Download Last")); + context_menu->insertSeparator(); + dnd_keep_id = context_menu->insertItem(i18n("Do Not Download")); + dnd_throw_away_id = context_menu->insertItem(i18n("Delete File(s)")); + + + context_menu->setItemEnabled(preview_id, false); + context_menu->setItemEnabled(first_id, false); + context_menu->setItemEnabled(normal_id, false); + context_menu->setItemEnabled(last_id, false); + context_menu->setItemEnabled(dnd_keep_id, false); + context_menu->setItemEnabled(dnd_throw_away_id, false); + + connect(this,SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint& )), + this,SLOT(showContextMenu(KListView*, QListViewItem*, const QPoint& ))); + connect(context_menu, SIGNAL ( activated ( int ) ), this, SLOT ( contextItem ( int ) ) ); + connect(this,SIGNAL(doubleClicked( QListViewItem*, const QPoint&, int )), + this,SLOT(onDoubleClicked(QListViewItem*, const QPoint&, int))); + + connect(&fill_timer, SIGNAL(timeout()), this, SLOT( fillTreePartial() ) ); + + setEnabled(false); + + setSelectionMode(QListView::Extended); + } + + + FileView::~FileView() + {} + +#define ITEMS_PER_TICK 100 + + void FileView::fillTreePartial() + { + int cnt = 0; + while (next_fill_item < curr_tc->getNumFiles() && cnt < ITEMS_PER_TICK) + { + TorrentFileInterface & file = curr_tc->getTorrentFile(next_fill_item); + multi_root->insert(file.getPath(),file); + cnt++; + next_fill_item++; + } + + if (next_fill_item >= curr_tc->getNumFiles()) + { + multi_root->setOpen(true); + setRootIsDecorated(true); + setEnabled(true); + multi_root->updatePriorityInformation(curr_tc); + multi_root->updatePercentageInformation(); + multi_root->updatePreviewInformation(curr_tc); + fill_timer.stop(); + connect(curr_tc,SIGNAL(missingFilesMarkedDND( kt::TorrentInterface* )), + this,SLOT(refreshFileTree( kt::TorrentInterface* ))); + } + else + fill_timer.start(0,true); + } + + void FileView::fillFileTree() + { + multi_root = 0; + clear(); + + if (!curr_tc) + return; + + if (curr_tc->getStats().multi_file_torrent) + { + setEnabled(false); + multi_root = new IWFileTreeDirItem(this,curr_tc->getStats().torrent_name); + next_fill_item = 0; + fillTreePartial(); + } + else + { + const TorrentStats & s = curr_tc->getStats(); + this->setRootIsDecorated(false); + KListViewItem* item = new KListViewItem( + this, + s.torrent_name, + BytesToString(s.total_bytes)); + + item->setPixmap(0,KMimeType::findByPath(s.torrent_name)->pixmap(KIcon::Small)); + setEnabled(true); + connect(curr_tc,SIGNAL(missingFilesMarkedDND( kt::TorrentInterface* )), + this,SLOT(refreshFileTree( kt::TorrentInterface* ))); + } + } + + void FileView::changeTC(kt::TorrentInterface* tc) + { + if (tc == curr_tc) + return; + + curr_tc = tc; + pending_fill = true; + fill_timer.stop(); + fillFileTree(); + } + + void FileView::update() + { + if (!curr_tc) + return; + + if (isVisible() && !pending_fill) + { + readyPreview(); + readyPercentage(); + } + } + + void FileView::readyPercentage() + { + if (curr_tc && !curr_tc->getStats().multi_file_torrent) + { + QListViewItemIterator it(this); + if (!it.current()) + return; + + const BitSet & bs = curr_tc->downloadedChunksBitSet(); + Uint32 total = bs.getNumBits(); + Uint32 on = bs.numOnBits(); + double percent = 100.0 * ((double)on/(double)total); + if (percent < 0.0) + percent = 0.0; + else if (percent > 100.0) + percent = 100.0; + KLocale* loc = KGlobal::locale(); + it.current()->setText(4,i18n("%1 %").arg(loc->formatNumber(percent,2))); + } + } + + void FileView::readyPreview() + { + if (curr_tc && !curr_tc->getStats().multi_file_torrent) + { + QListViewItemIterator it(this); + if (!it.current()) + return; + + if (IsMultimediaFile(curr_tc->getStats().output_path)) + { + if ( curr_tc->readyForPreview() ) + it.current()->setText(3, i18n("Available")); + else + it.current()->setText(3, i18n("Pending")); + } + else + it.current()->setText(3, i18n("No")); + + } + } + + void FileView::showContextMenu(KListView* ,QListViewItem*,const QPoint & p) + { + const TorrentStats & s = curr_tc->getStats(); + // don't show a menu if item is 0 or if it is a directory + + + + QPtrList<QListViewItem> sel = selectedItems(); + switch(sel.count()) + { + case 0: + return; + break; + case 1: + break; + default: + context_menu->setItemEnabled(first_id, true); + context_menu->setItemEnabled(normal_id, true); + context_menu->setItemEnabled(last_id, true); + context_menu->setItemEnabled(preview_id, false); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_throw_away_id,true); + context_menu->popup(p); + return; + break; + } + QListViewItem* item = sel.getFirst(); + + context_menu->setItemEnabled(first_id, false); + context_menu->setItemEnabled(normal_id, false); + context_menu->setItemEnabled(last_id, false); + if (s.multi_file_torrent && item->childCount() == 0) + { + kt::TorrentFileInterface & file = ((FileTreeItem*)item)->getTorrentFile(); + if (!file.isNull()) + { + context_menu->setItemEnabled(preview_id, true); + this->preview_path = "cache" + bt::DirSeparator() + file.getPath(); + + switch(file.getPriority()) + { + case FIRST_PRIORITY: + context_menu->setItemEnabled(normal_id, true); + context_menu->setItemEnabled(last_id, true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_throw_away_id,true); + break; + case LAST_PRIORITY: + context_menu->setItemEnabled(first_id, true); + context_menu->setItemEnabled(normal_id, true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_throw_away_id,true); + break; + case EXCLUDED: + context_menu->setItemEnabled(first_id,true); + context_menu->setItemEnabled(normal_id,true); + context_menu->setItemEnabled(last_id, true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_throw_away_id,false); + break; + case ONLY_SEED_PRIORITY: + context_menu->setItemEnabled(first_id,true); + context_menu->setItemEnabled(normal_id,true); + context_menu->setItemEnabled(last_id, true); + context_menu->setItemEnabled(dnd_keep_id,false); + context_menu->setItemEnabled(dnd_throw_away_id,true); + break; + case PREVIEW_PRIORITY: + default: + context_menu->setItemEnabled(first_id, true); + context_menu->setItemEnabled(normal_id,false); + context_menu->setItemEnabled(last_id, true); + context_menu->setItemEnabled(dnd_keep_id,true); + context_menu->setItemEnabled(dnd_throw_away_id,true); + break; + } + } + else + { + context_menu->setItemEnabled(preview_id, false); + } + } + else + { + bool val = item->childCount() != 0; + context_menu->setItemEnabled(first_id, val); + context_menu->setItemEnabled(normal_id, val); + context_menu->setItemEnabled(last_id, val); + context_menu->setItemEnabled(dnd_keep_id,val); + context_menu->setItemEnabled(dnd_throw_away_id,val); + + context_menu->setItemEnabled(preview_id, true); + if (s.multi_file_torrent) + { + FileTreeDirItem* dir = ((FileTreeDirItem*)item); + preview_path = "cache" + dir->getPath(); + } + else + { + preview_path = "cache"; + } + } + + context_menu->popup(p); + } + + void FileView::contextItem(int id) + { + QPtrList<QListViewItem> sel = selectedItems(); + + Priority newpriority = NORMAL_PRIORITY; + if(id == this->preview_id) + { + new KRun(KURL::fromPathOrURL(this->curr_tc->getTorDir()+preview_path), 0, true, true); + return; + } + else if (id == dnd_throw_away_id) + { + Uint32 n = sel.count(); + if (n == 1) // single item can be a directory + { + // the number of the beast > 1 + n = (*sel.begin())->childCount() == 0 ? 1 : 666; + } + + QString msg = i18n( + "You will lose all data in this file, are you sure you want to do this ?", + "You will lose all data in these files, are you sure you want to do this ?",n); + + if (KMessageBox::warningYesNo(0,msg) == KMessageBox::No) + return; + newpriority = EXCLUDED; + } + else if(id == this->first_id) + { + newpriority = FIRST_PRIORITY; + } + else if(id == this->last_id) + { + newpriority = LAST_PRIORITY; + } + else if(id == this->normal_id) + { + newpriority = NORMAL_PRIORITY; + } + else if (id == dnd_keep_id) + { + newpriority = ONLY_SEED_PRIORITY; + } + + + + QPtrList<QListViewItem>::Iterator i = sel.begin(); + while(i != sel.end()) + { + QListViewItem* item = *i; + changePriority(item, newpriority); + multi_root->updatePriorityInformation(curr_tc); + i++; + } + } + + void FileView::changePriority(QListViewItem* item, Priority newpriority) + { + if(item->childCount() == 0) + { + FileTreeItem* fti = (FileTreeItem*)item; + if (newpriority == EXCLUDED) + { + fti->setChecked(false,false); + } + else if (newpriority == ONLY_SEED_PRIORITY) + { + fti->setChecked(false,true); + } + else + { + if (!fti->isOn()) + fti->setChecked(true,true); + fti->getTorrentFile().setPriority(newpriority); + } + return; + } + QListViewItem* myChild = item->firstChild(); + while( myChild ) + { + changePriority(myChild, newpriority); + myChild = myChild->nextSibling(); + } + } + + void FileView::refreshFileTree(kt::TorrentInterface* tc) + { + if (!tc || curr_tc != tc) + return; + + if (multi_root) + multi_root->updateDNDInformation(); + } + + void FileView::onDoubleClicked(QListViewItem* item,const QPoint & ,int ) + { + if (!curr_tc) + return; + + const TorrentStats & s = curr_tc->getStats(); + + if (s.multi_file_torrent) + { + if (item->childCount() == 0) + { + // file + FileTreeItem* file = (FileTreeItem*)item; + QString path = "cache" + bt::DirSeparator() + file->getTorrentFile().getPath(); + new KRun(KURL::fromPathOrURL(curr_tc->getTorDir() + path), 0, true, true); + } + else + { + // directory + FileTreeDirItem* dir = ((FileTreeDirItem*)item); + new KRun(KURL::fromPathOrURL(curr_tc->getTorDir() + "cache" + dir->getPath()), 0, true, true); + } + } + else + { + QFileInfo fi(curr_tc->getTorDir()+"cache"); + new KRun(KURL::fromPathOrURL(fi.readLink()), 0, true, true); + } + } +} + +#include "fileview.moc" diff --git a/plugins/infowidget/fileview.h b/plugins/infowidget/fileview.h new file mode 100644 index 0000000..6a827dc --- /dev/null +++ b/plugins/infowidget/fileview.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 KTFILEVIEW_H +#define KTFILEVIEW_H + +#include <klistview.h> +#include <util/constants.h> +#include <qtimer.h> + +namespace kt +{ + class TorrentInterface; + class IWFileTreeDirItem; + + /** + @author Joris Guisson <joris.guisson@gmail.com> + */ + class FileView : public KListView + { + Q_OBJECT + public: + FileView(QWidget *parent = 0, const char *name = 0); + virtual ~FileView(); + + void update(); + void changeTC(kt::TorrentInterface* tc); + private slots: + void contextItem(int id); + void showContextMenu(KListView* ,QListViewItem* item,const QPoint & p); + void refreshFileTree(kt::TorrentInterface* tc); + void onDoubleClicked(QListViewItem* item,const QPoint & ,int ); + void fillTreePartial(); + + private: + void fillFileTree(); + void readyPreview(); + void readyPercentage(); + void changePriority(QListViewItem* item, bt::Priority newpriority); + + private: + kt::TorrentInterface* curr_tc; + IWFileTreeDirItem* multi_root; + bool pending_fill; + KPopupMenu* context_menu; + QString preview_path; + QTimer fill_timer; + int preview_id; + int first_id; + int normal_id; + int last_id; + int dnd_keep_id; + int dnd_throw_away_id; + + int next_fill_item; + }; + +} + +#endif diff --git a/plugins/infowidget/flagdb.cpp b/plugins/infowidget/flagdb.cpp new file mode 100644 index 0000000..140a3b7 --- /dev/null +++ b/plugins/infowidget/flagdb.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2007 by Modestas Vainius <modestas@vainius.eu> * + * * + * 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 <qfile.h> +#include <qimage.h> +#include <kstandarddirs.h> +#include "flagdb.h" + +kt::FlagDBSource::FlagDBSource(const char* type, const QString& pathPattern) + : type(type), pathPattern(pathPattern) +{ +} + +kt::FlagDBSource::FlagDBSource(const QString& pathPattern) + : type(NULL), pathPattern(pathPattern) +{ +} + +kt::FlagDBSource::FlagDBSource() + : type(NULL), pathPattern() +{ +} + +QString kt::FlagDBSource::FlagDBSource::getPath(const QString& country) const +{ + if (type) { + return locate(type, pathPattern.arg(country)); + } else { + return pathPattern.arg(country); + } +} + +const QPixmap& kt::FlagDB::nullPixmap = QPixmap(); + +kt::FlagDB::FlagDB(int preferredWidth, int preferredHeight) + : preferredWidth(preferredWidth), + preferredHeight(preferredHeight), + sources(), + db() +{ +} + + +kt::FlagDB::FlagDB(const FlagDB& other) + : preferredWidth(other.preferredWidth), + preferredHeight(other.preferredHeight), + sources(other.sources), + db(other.db) +{ +} + +kt::FlagDB::~FlagDB() +{ +} + +void kt::FlagDB::addFlagSource(const FlagDBSource& source) +{ + sources.append(source); +} + +void kt::FlagDB::addFlagSource(const char* type, const QString& pathPattern) +{ + addFlagSource(FlagDBSource(type, pathPattern)); +} + +const QValueList<kt::FlagDBSource>& kt::FlagDB::listSources() const +{ + return sources; +} + +bool kt::FlagDB::isFlagAvailable(const QString& country) +{ + return getFlag(country).isNull(); +} + +const QPixmap& kt::FlagDB::getFlag(const QString& country) +{ + const QString& c = country.lower(); + if (!db.contains(c)) { + QImage img; + QPixmap pixmap; + for (QValueList<FlagDBSource>::const_iterator it = sources.constBegin(); it != sources.constEnd(); it++) { + const QString& path = (*it).getPath(c); + if (QFile::exists(path)) { + if (img.load(path)) { + if (img.width() != preferredWidth || img.height() != preferredHeight) { + const QImage& imgScaled = img.smoothScale(preferredWidth, preferredHeight, QImage::ScaleMin); + if (!imgScaled.isNull()) { + pixmap.convertFromImage(imgScaled); + break; + } else if (img.width() <= preferredWidth || img.height() <= preferredHeight) { + pixmap.convertFromImage(img); + break; + } + } + } + } + } + + db[c] = (!pixmap.isNull()) ? pixmap : nullPixmap; + } + return db[c]; +} diff --git a/plugins/infowidget/flagdb.h b/plugins/infowidget/flagdb.h new file mode 100644 index 0000000..f2524ab --- /dev/null +++ b/plugins/infowidget/flagdb.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2007 by Modestas Vainius <modestas@vainius.eu> * + * * + * 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 FLAGDB_H +#define FLAGDB_H + +#include <qpixmap.h> +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> + +namespace kt +{ + class FlagDBSource + { + public: + FlagDBSource(); + FlagDBSource(const char* type, const QString& pathPattern); + FlagDBSource(const QString& pathPattern); + QString getPath(const QString& country) const; + + const char* getType() { return type; }; + const QString& getPathPattern() { return pathPattern; }; + + private: + const char* type; + const QString pathPattern; + }; + + /** + @author Modestas Vainius + */ + class FlagDB + { + public : + FlagDB(int preferredWidth, int preferredHeight); + FlagDB(const FlagDB& m); + ~FlagDB(); + + void addFlagSource(const FlagDBSource& source); + void addFlagSource(const char* type, const QString& pathPattern); + const QValueList<FlagDBSource>& listSources() const; + bool isFlagAvailable(const QString& country); + const QPixmap& getFlag(const QString& country); + private: + static const QPixmap& nullPixmap; + int preferredWidth, preferredHeight; + QValueList<FlagDBSource> sources; + QMap<QString,QPixmap> db; + }; +} + + #endif diff --git a/plugins/infowidget/floatspinbox.cpp b/plugins/infowidget/floatspinbox.cpp new file mode 100644 index 0000000..8b78981 --- /dev/null +++ b/plugins/infowidget/floatspinbox.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + * Copyright (C) 2006 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * Jonas Widarsson <jonas@widarsson.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 <kglobal.h> +#include <klocale.h> +#include <qlineedit.h> +#include "floatspinbox.h" +#include "localefloatvalidator.h" + + +kt::FloatSpinBox::FloatSpinBox( + QWidget * parent, + const char * name + ) + :QSpinBox( -100, 100, 1, parent, name), + m_precision_digits( 2 ), + m_value(0.0f), + m_minValue(0.0f), + m_maxValue(0.0f), + m_useRange(false), + m_oldIntVal(0) +{ + QSpinBox::setValue(0); + setStep( 0.25f ); + connect(this, SIGNAL(valueChanged ( int )), this, SLOT(internalValueChanged( int ))); + setValidator( new LocaleFloatValidator( dynamic_cast<QSpinBox * > (this) )); + editor()->setAlignment(Qt::AlignRight); +} + +kt::FloatSpinBox::FloatSpinBox( + int precision, + QWidget * parent, + const char * name + ) + :QSpinBox( -100, 100, 1, parent, name), + m_precision_digits( precision ), + m_value(0.0f), + m_minValue(0.0f), + m_maxValue(0.0f), + m_useRange(false), + m_oldIntVal(0) +{ + QSpinBox::setValue(0); + setStep( 0.25 ); + connect(this, SIGNAL(valueChanged ( int )), this, SLOT(internalValueChanged( int ))); + setValidator( new LocaleFloatValidator( dynamic_cast<QSpinBox * > (this) )); +} + + +kt::FloatSpinBox::FloatSpinBox( + float minValue, + float maxValue, + float step, + int precision, + QWidget * parent, + const char * name + ) + :QSpinBox( -100, 100, 1, parent, name), + m_precision_digits( precision ), + m_value(0.0f), + m_minValue(minValue), + m_maxValue(maxValue), + m_useRange(true), + m_oldIntVal(0) +{ + QSpinBox::setValue(0); + setValue(0.0f); + setStep( step ); + connect(this, SIGNAL(valueChanged ( int )), this, SLOT(internalValueChanged( int ))); + setValidator( new LocaleFloatValidator( this )); + +} + +QString kt::FloatSpinBox::mapValueToText( int value ) +{ + /// This is called from QSpinBox, which passes an int. + /// As we don't use the QSpinBox's internal value, we ignore it. + QString t = KGlobal::locale()->formatNumber( m_value, m_precision_digits); + editor()->setText(t); + return t; +} + +int kt::FloatSpinBox::mapTextToValue( bool * ok ) +{ + /// This is called from QSpinBox, which needs an int for return. + /// As we don't use the QSpinBox's internal value, we only return 0. + + float value = KGlobal::locale()->readNumber(text(), ok); + if (*ok) + { + setValue(value); + *ok = true; + } + return 1; +} + +float kt::FloatSpinBox::minValue( ) const +{ + return m_minValue; +} + +float kt::FloatSpinBox::maxValue( ) const +{ + return m_maxValue; +} + +float kt::FloatSpinBox::value( ) const +{ + return m_value; +} + +int kt::FloatSpinBox::precision( ) const +{ + return m_precision_digits; +} + +void kt::FloatSpinBox::setMinValue( float minValue ) +{ + if (minValue <= m_maxValue) + { + m_minValue = minValue; + m_useRange = true; + } +} + +void kt::FloatSpinBox::setMaxValue( float maxValue ) +{ + if (maxValue >= m_minValue) + { + m_maxValue = maxValue; + m_useRange = true; + } +} + +void kt::FloatSpinBox::setValue( float value ) +{ + bool changed = false; + if (m_useRange) + { + float old = m_value; + m_value = max(m_minValue, min(m_maxValue, value)); + if ( old != m_value ) + changed = true; + } + else + { + m_value = value; + changed = true; + } + if (changed) + { + mapValueToText(0); + emit valueChanged( m_value ); + emit valueHasChanged(); + } +} + +void kt::FloatSpinBox::setStep( float step) +{ + if (step > 0) + m_step = step; +} + +void kt::FloatSpinBox::internalValueChanged( int value ) +{ + /// The step buttons won't work without tracking the + /// QSpinbox's value changes. + + if ( value > m_oldIntVal) + { + stepUp(); + } + else + { + stepDown(); + } + + if (value > 10) + value -= 20; + + if (value < -10) + value += 20; + + m_oldIntVal = value; +} + +void kt::FloatSpinBox::setPrecision( int value ) +{ + m_precision_digits = value; +} + +void kt::FloatSpinBox::stepUp( ) +{ + setValue( m_value + m_step ); +} + +void kt::FloatSpinBox::stepDown( ) +{ + setValue( m_value - m_step ); +} + +kt::FloatSpinBox::~ FloatSpinBox( ) +{ +} + + +#include "floatspinbox.moc" diff --git a/plugins/infowidget/floatspinbox.h b/plugins/infowidget/floatspinbox.h new file mode 100644 index 0000000..42545bc --- /dev/null +++ b/plugins/infowidget/floatspinbox.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2005 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * Jonas Widarsson <jonas@widarsson.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 FLOATSPINBOX_H +#define FLOATSPINBOX_H + +#include <qspinbox.h> + +namespace kt +{ + + /** + * @author Jonas Widarsson + * + * A Spinbox for float values which respects KGlobal::locale(). + * QSpinBox's internal integer value is only + * used for step detection. + */ + + class FloatSpinBox : public QSpinBox + { + Q_OBJECT + public: + FloatSpinBox( QWidget* parent=0, const char* name=0 ); + FloatSpinBox( int precision = 2, QWidget* parent=0, const char* name=0 ); + FloatSpinBox( float minValue, float maxValue, float step = 0.5, int precision = 2, + QWidget* parent=0, const char* name=0 ); + virtual ~FloatSpinBox(); + + QString mapValueToText( int value ); + + int mapTextToValue( bool *ok ); + + float minValue () const; + float maxValue () const; + float value () const; + int precision() const; + + public slots: + virtual void setMinValue ( float minValue ); + virtual void setMaxValue ( float maxValue ); + virtual void setValue ( float value ); + virtual void setStep ( float step ); + virtual void setPrecision( int value ); + virtual void stepUp(); + virtual void stepDown(); + + signals: + void valueChanged ( float value ); + void valueHasChanged (); + + private slots: + void internalValueChanged( int value ); + + private: + int m_precision_digits; + float m_value; + float m_minValue; + float m_maxValue; + bool m_useRange; + float m_step; + int m_oldIntVal; + float min( float a, float b) const + { + return (a < b) ? a : b; + } + + float max( float a, float b) const + { + return (a > b) ? a : b; + } + }; +} + +#endif diff --git a/plugins/infowidget/geoip/FLAGS_LICENCE b/plugins/infowidget/geoip/FLAGS_LICENCE new file mode 100644 index 0000000..368a8fe --- /dev/null +++ b/plugins/infowidget/geoip/FLAGS_LICENCE @@ -0,0 +1,2 @@ +Flag images found at http://www.hahn-hotel.com/flags/ +"All sets provided by us are free to use to anyone, for commercial or non-commercial websites."
\ No newline at end of file diff --git a/plugins/infowidget/geoip/GeoIP-LICENSE.txt b/plugins/infowidget/geoip/GeoIP-LICENSE.txt new file mode 100644 index 0000000..457710d --- /dev/null +++ b/plugins/infowidget/geoip/GeoIP-LICENSE.txt @@ -0,0 +1,74 @@ +There are two licenses, one for the C library software, and one for +the database. + +SOFTWARE LICENSE (C library) + +The GeoIP C Library is licensed under the GPL. For details see +the COPYING file. + +OPEN DATA LICENSE (GeoIP Standard Edition Database) + +Copyright (c) 2003 MaxMind LLC. All Rights Reserved. + +All advertising materials and documentation mentioning features or use of +this database must display the following acknowledgment: +"This product includes GeoIP data created by MaxMind, available from +http://maxmind.com/" + +Redistribution and use with or without modification, are permitted provided +that the following conditions are met: +1. Redistributions must retain the above copyright notice, this list of +conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. +2. All advertising materials and documentation mentioning features or use of +this database must display the following acknowledgement: +"This product includes GeoIP data created by MaxMind, available from +http://maxmind.com/" +3. "MaxMind" may not be used to endorse or promote products derived from this +database without specific prior written permission. + +THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Some parts of this software distribution are derived from the APNIC, ARIN and +RIPE databases (copyright details below). The author of this module makes no +claims of ownership on those parts. + +APNIC conditions of use: + +The files are freely available for download and use on the condition that APNIC +will not be held responsible for any loss or damage arising from the application +of the information contained in these reports. + +APNIC endeavours to the best of its ability to ensure the accuracy of these +reports; however, APNIC makes no guarantee in this regard. + +In particular, it should be noted that these reports seek to indicate the +country where resources were first allocated or assigned. It is not intended +that these reports be considered as an authoritative statement of the location +in which any specific resource may currently be in use. + +ARIN database copyright: + +Copyright (c) American Registry for Internet Numbers. All rights reserved. + +RIPE database copyright: + +The information in the RIPE Database is available to the public for agreed +Internet operation purposes, but is under copyright. The copyright statement is: + +"Except for agreed Internet operational purposes, no part of this publication +may be reproduced, stored in a retrieval system, or transmitted, in any form or +by any means, electronic, mechanical, recording, or otherwise, without prior +permission of the RIPE NCC on behalf of the copyright holders. Any use of this +material to target advertising or similar activities is explicitly forbidden and +may be prosecuted. The RIPE NCC requests to be notified of any such activities +or suspicions thereof." diff --git a/plugins/infowidget/geoip/Makefile.am b/plugins/infowidget/geoip/Makefile.am new file mode 100644 index 0000000..1a7d6c4 --- /dev/null +++ b/plugins/infowidget/geoip/Makefile.am @@ -0,0 +1,41 @@ +INCLUDES = -I$(srcdir)/../../libktorrent $(all_includes) +METASOURCES = AUTO + +ktdatadir = $(kde_datadir)/ktorrent/geoip + +if ENABLE_GEOIP +GEOIP_FILES = geoip.dat GeoIP-LICENSE.txt +else +GEOIP_FILES = +endif + +if ENABLE_BUILTIN_COUNTRY_FLAGS +FLAG_FILES = ad.png ae.png af.png ag.png ai.png al.png am.png an.png ao.png \ + aq.png ar.png as.png at.png au.png aw.png az.png ba.png bb.png bd.png be.png \ + bf.png bg.png bh.png bi.png bj.png bm.png bn.png bo.png br.png bs.png bt.png \ + bv.png bw.png by.png bz.png ca.png cc.png cd.png cf.png cg.png ch.png ci.png \ + ck.png cl.png cm.png cn.png co.png cr.png cs.png cu.png cv.png cx.png cy.png \ + cz.png de.png dj.png dk.png dm.png do.png dz.png ec.png ee.png eg.png eh.png \ + er.png es.png et.png eu.png fi.png fj.png fk.png fm.png fo.png fr.png ga.png \ + gb.png gd.png ge.png gf.png gh.png gi.png gl.png gm.png gn.png gp.png gq.png \ + gr.png gs.png gt.png gu.png gw.png gy.png hk.png hm.png hn.png hr.png ht.png \ + hu.png id.png ie.png il.png in.png io.png iq.png ir.png is.png it.png jm.png \ + jo.png jp.png ke.png kg.png kh.png ki.png km.png kn.png kp.png kr.png kw.png \ + ky.png kz.png la.png lb.png lc.png li.png lk.png lr.png ls.png lt.png lu.png \ + lv.png ly.png ma.png mc.png md.png mg.png mh.png mk.png ml.png mm.png mn.png \ + mo.png mp.png mq.png mr.png ms.png mt.png mu.png mv.png mw.png mx.png my.png \ + mz.png na.png nc.png ne.png nf.png ng.png ni.png nl.png no.png np.png nr.png \ + nu.png nz.png om.png pa.png pe.png pf.png pg.png ph.png pk.png pl.png pm.png \ + pn.png pr.png ps.png pt.png pw.png py.png qa.png re.png ro.png ru.png rw.png \ + sa.png sb.png sc.png sd.png se.png sg.png sh.png si.png sj.png sk.png sl.png \ + sm.png sn.png so.png sr.png st.png sv.png sy.png sz.png tc.png td.png tf.png \ + tg.png th.png tj.png tk.png tl.png tm.png tn.png to.png tp.png tr.png tt.png \ + tv.png tw.png tz.png ua.png ug.png um.png us.png uy.png uz.png va.png vc.png \ + ve.png vg.png vi.png vn.png vu.png wf.png ws.png ye.png yt.png yu.png za.png \ + zm.png zw.png FLAGS_LICENCE +else +FLAG_FILES = +endif + +ktdata_DATA = $(FLAG_FILES) $(GEOIP_FILES) + diff --git a/plugins/infowidget/geoip/ad.png b/plugins/infowidget/geoip/ad.png Binary files differnew file mode 100644 index 0000000..bcf1e35 --- /dev/null +++ b/plugins/infowidget/geoip/ad.png diff --git a/plugins/infowidget/geoip/ae.png b/plugins/infowidget/geoip/ae.png Binary files differnew file mode 100644 index 0000000..4ce8134 --- /dev/null +++ b/plugins/infowidget/geoip/ae.png diff --git a/plugins/infowidget/geoip/af.png b/plugins/infowidget/geoip/af.png Binary files differnew file mode 100644 index 0000000..14027c0 --- /dev/null +++ b/plugins/infowidget/geoip/af.png diff --git a/plugins/infowidget/geoip/ag.png b/plugins/infowidget/geoip/ag.png Binary files differnew file mode 100644 index 0000000..93b3eb8 --- /dev/null +++ b/plugins/infowidget/geoip/ag.png diff --git a/plugins/infowidget/geoip/ai.png b/plugins/infowidget/geoip/ai.png Binary files differnew file mode 100644 index 0000000..6aa3b55 --- /dev/null +++ b/plugins/infowidget/geoip/ai.png diff --git a/plugins/infowidget/geoip/al.png b/plugins/infowidget/geoip/al.png Binary files differnew file mode 100644 index 0000000..04f7c13 --- /dev/null +++ b/plugins/infowidget/geoip/al.png diff --git a/plugins/infowidget/geoip/am.png b/plugins/infowidget/geoip/am.png Binary files differnew file mode 100644 index 0000000..dbecf96 --- /dev/null +++ b/plugins/infowidget/geoip/am.png diff --git a/plugins/infowidget/geoip/an.png b/plugins/infowidget/geoip/an.png Binary files differnew file mode 100644 index 0000000..974daba --- /dev/null +++ b/plugins/infowidget/geoip/an.png diff --git a/plugins/infowidget/geoip/ao.png b/plugins/infowidget/geoip/ao.png Binary files differnew file mode 100644 index 0000000..5e08932 --- /dev/null +++ b/plugins/infowidget/geoip/ao.png diff --git a/plugins/infowidget/geoip/aq.png b/plugins/infowidget/geoip/aq.png Binary files differnew file mode 100644 index 0000000..b08a8b6 --- /dev/null +++ b/plugins/infowidget/geoip/aq.png diff --git a/plugins/infowidget/geoip/ar.png b/plugins/infowidget/geoip/ar.png Binary files differnew file mode 100644 index 0000000..68c99d9 --- /dev/null +++ b/plugins/infowidget/geoip/ar.png diff --git a/plugins/infowidget/geoip/as.png b/plugins/infowidget/geoip/as.png Binary files differnew file mode 100644 index 0000000..5903f6c --- /dev/null +++ b/plugins/infowidget/geoip/as.png diff --git a/plugins/infowidget/geoip/at.png b/plugins/infowidget/geoip/at.png Binary files differnew file mode 100644 index 0000000..1570d7a --- /dev/null +++ b/plugins/infowidget/geoip/at.png diff --git a/plugins/infowidget/geoip/au.png b/plugins/infowidget/geoip/au.png Binary files differnew file mode 100644 index 0000000..486646b --- /dev/null +++ b/plugins/infowidget/geoip/au.png diff --git a/plugins/infowidget/geoip/aw.png b/plugins/infowidget/geoip/aw.png Binary files differnew file mode 100644 index 0000000..5831bbe --- /dev/null +++ b/plugins/infowidget/geoip/aw.png diff --git a/plugins/infowidget/geoip/az.png b/plugins/infowidget/geoip/az.png Binary files differnew file mode 100644 index 0000000..420a871 --- /dev/null +++ b/plugins/infowidget/geoip/az.png diff --git a/plugins/infowidget/geoip/ba.png b/plugins/infowidget/geoip/ba.png Binary files differnew file mode 100644 index 0000000..dff9671 --- /dev/null +++ b/plugins/infowidget/geoip/ba.png diff --git a/plugins/infowidget/geoip/bb.png b/plugins/infowidget/geoip/bb.png Binary files differnew file mode 100644 index 0000000..1811232 --- /dev/null +++ b/plugins/infowidget/geoip/bb.png diff --git a/plugins/infowidget/geoip/bd.png b/plugins/infowidget/geoip/bd.png Binary files differnew file mode 100644 index 0000000..034f07a --- /dev/null +++ b/plugins/infowidget/geoip/bd.png diff --git a/plugins/infowidget/geoip/be.png b/plugins/infowidget/geoip/be.png Binary files differnew file mode 100644 index 0000000..4b50190 --- /dev/null +++ b/plugins/infowidget/geoip/be.png diff --git a/plugins/infowidget/geoip/bf.png b/plugins/infowidget/geoip/bf.png Binary files differnew file mode 100644 index 0000000..4b522d8 --- /dev/null +++ b/plugins/infowidget/geoip/bf.png diff --git a/plugins/infowidget/geoip/bg.png b/plugins/infowidget/geoip/bg.png Binary files differnew file mode 100644 index 0000000..60aae1d --- /dev/null +++ b/plugins/infowidget/geoip/bg.png diff --git a/plugins/infowidget/geoip/bh.png b/plugins/infowidget/geoip/bh.png Binary files differnew file mode 100644 index 0000000..b6524c2 --- /dev/null +++ b/plugins/infowidget/geoip/bh.png diff --git a/plugins/infowidget/geoip/bi.png b/plugins/infowidget/geoip/bi.png Binary files differnew file mode 100644 index 0000000..d4751e0 --- /dev/null +++ b/plugins/infowidget/geoip/bi.png diff --git a/plugins/infowidget/geoip/bj.png b/plugins/infowidget/geoip/bj.png Binary files differnew file mode 100644 index 0000000..4dbfd3f --- /dev/null +++ b/plugins/infowidget/geoip/bj.png diff --git a/plugins/infowidget/geoip/bm.png b/plugins/infowidget/geoip/bm.png Binary files differnew file mode 100644 index 0000000..c178fe7 --- /dev/null +++ b/plugins/infowidget/geoip/bm.png diff --git a/plugins/infowidget/geoip/bn.png b/plugins/infowidget/geoip/bn.png Binary files differnew file mode 100644 index 0000000..291fc80 --- /dev/null +++ b/plugins/infowidget/geoip/bn.png diff --git a/plugins/infowidget/geoip/bo.png b/plugins/infowidget/geoip/bo.png Binary files differnew file mode 100644 index 0000000..ad2120b --- /dev/null +++ b/plugins/infowidget/geoip/bo.png diff --git a/plugins/infowidget/geoip/br.png b/plugins/infowidget/geoip/br.png Binary files differnew file mode 100644 index 0000000..bd1b880 --- /dev/null +++ b/plugins/infowidget/geoip/br.png diff --git a/plugins/infowidget/geoip/bs.png b/plugins/infowidget/geoip/bs.png Binary files differnew file mode 100644 index 0000000..5395236 --- /dev/null +++ b/plugins/infowidget/geoip/bs.png diff --git a/plugins/infowidget/geoip/bt.png b/plugins/infowidget/geoip/bt.png Binary files differnew file mode 100644 index 0000000..ef1d430 --- /dev/null +++ b/plugins/infowidget/geoip/bt.png diff --git a/plugins/infowidget/geoip/bv.png b/plugins/infowidget/geoip/bv.png Binary files differnew file mode 100644 index 0000000..ed4c76b --- /dev/null +++ b/plugins/infowidget/geoip/bv.png diff --git a/plugins/infowidget/geoip/bw.png b/plugins/infowidget/geoip/bw.png Binary files differnew file mode 100644 index 0000000..c69641b --- /dev/null +++ b/plugins/infowidget/geoip/bw.png diff --git a/plugins/infowidget/geoip/by.png b/plugins/infowidget/geoip/by.png Binary files differnew file mode 100644 index 0000000..655f0ae --- /dev/null +++ b/plugins/infowidget/geoip/by.png diff --git a/plugins/infowidget/geoip/bz.png b/plugins/infowidget/geoip/bz.png Binary files differnew file mode 100644 index 0000000..92964f8 --- /dev/null +++ b/plugins/infowidget/geoip/bz.png diff --git a/plugins/infowidget/geoip/ca.png b/plugins/infowidget/geoip/ca.png Binary files differnew file mode 100644 index 0000000..757ea92 --- /dev/null +++ b/plugins/infowidget/geoip/ca.png diff --git a/plugins/infowidget/geoip/cc.png b/plugins/infowidget/geoip/cc.png Binary files differnew file mode 100644 index 0000000..ba02461 --- /dev/null +++ b/plugins/infowidget/geoip/cc.png diff --git a/plugins/infowidget/geoip/cd.png b/plugins/infowidget/geoip/cd.png Binary files differnew file mode 100644 index 0000000..6d6e96c --- /dev/null +++ b/plugins/infowidget/geoip/cd.png diff --git a/plugins/infowidget/geoip/cf.png b/plugins/infowidget/geoip/cf.png Binary files differnew file mode 100644 index 0000000..fa2b560 --- /dev/null +++ b/plugins/infowidget/geoip/cf.png diff --git a/plugins/infowidget/geoip/cg.png b/plugins/infowidget/geoip/cg.png Binary files differnew file mode 100644 index 0000000..aae69bb --- /dev/null +++ b/plugins/infowidget/geoip/cg.png diff --git a/plugins/infowidget/geoip/ch.png b/plugins/infowidget/geoip/ch.png Binary files differnew file mode 100644 index 0000000..aa2e8cd --- /dev/null +++ b/plugins/infowidget/geoip/ch.png diff --git a/plugins/infowidget/geoip/ci.png b/plugins/infowidget/geoip/ci.png Binary files differnew file mode 100644 index 0000000..b06b6e1 --- /dev/null +++ b/plugins/infowidget/geoip/ci.png diff --git a/plugins/infowidget/geoip/ck.png b/plugins/infowidget/geoip/ck.png Binary files differnew file mode 100644 index 0000000..b70d582 --- /dev/null +++ b/plugins/infowidget/geoip/ck.png diff --git a/plugins/infowidget/geoip/cl.png b/plugins/infowidget/geoip/cl.png Binary files differnew file mode 100644 index 0000000..148f2bc --- /dev/null +++ b/plugins/infowidget/geoip/cl.png diff --git a/plugins/infowidget/geoip/cm.png b/plugins/infowidget/geoip/cm.png Binary files differnew file mode 100644 index 0000000..f47d808 --- /dev/null +++ b/plugins/infowidget/geoip/cm.png diff --git a/plugins/infowidget/geoip/cn.png b/plugins/infowidget/geoip/cn.png Binary files differnew file mode 100644 index 0000000..f6c4a20 --- /dev/null +++ b/plugins/infowidget/geoip/cn.png diff --git a/plugins/infowidget/geoip/co.png b/plugins/infowidget/geoip/co.png Binary files differnew file mode 100644 index 0000000..b6636cd --- /dev/null +++ b/plugins/infowidget/geoip/co.png diff --git a/plugins/infowidget/geoip/cr.png b/plugins/infowidget/geoip/cr.png Binary files differnew file mode 100644 index 0000000..f4c0d03 --- /dev/null +++ b/plugins/infowidget/geoip/cr.png diff --git a/plugins/infowidget/geoip/cs.png b/plugins/infowidget/geoip/cs.png Binary files differnew file mode 100644 index 0000000..f923c01 --- /dev/null +++ b/plugins/infowidget/geoip/cs.png diff --git a/plugins/infowidget/geoip/cu.png b/plugins/infowidget/geoip/cu.png Binary files differnew file mode 100644 index 0000000..edc0752 --- /dev/null +++ b/plugins/infowidget/geoip/cu.png diff --git a/plugins/infowidget/geoip/cv.png b/plugins/infowidget/geoip/cv.png Binary files differnew file mode 100644 index 0000000..d6d1a76 --- /dev/null +++ b/plugins/infowidget/geoip/cv.png diff --git a/plugins/infowidget/geoip/cx.png b/plugins/infowidget/geoip/cx.png Binary files differnew file mode 100644 index 0000000..452b405 --- /dev/null +++ b/plugins/infowidget/geoip/cx.png diff --git a/plugins/infowidget/geoip/cy.png b/plugins/infowidget/geoip/cy.png Binary files differnew file mode 100644 index 0000000..6d6d36a --- /dev/null +++ b/plugins/infowidget/geoip/cy.png diff --git a/plugins/infowidget/geoip/cz.png b/plugins/infowidget/geoip/cz.png Binary files differnew file mode 100644 index 0000000..1aaca40 --- /dev/null +++ b/plugins/infowidget/geoip/cz.png diff --git a/plugins/infowidget/geoip/de.png b/plugins/infowidget/geoip/de.png Binary files differnew file mode 100644 index 0000000..fbbc44f --- /dev/null +++ b/plugins/infowidget/geoip/de.png diff --git a/plugins/infowidget/geoip/dj.png b/plugins/infowidget/geoip/dj.png Binary files differnew file mode 100644 index 0000000..95d4e30 --- /dev/null +++ b/plugins/infowidget/geoip/dj.png diff --git a/plugins/infowidget/geoip/dk.png b/plugins/infowidget/geoip/dk.png Binary files differnew file mode 100644 index 0000000..6f60a4a --- /dev/null +++ b/plugins/infowidget/geoip/dk.png diff --git a/plugins/infowidget/geoip/dm.png b/plugins/infowidget/geoip/dm.png Binary files differnew file mode 100644 index 0000000..7f240cf --- /dev/null +++ b/plugins/infowidget/geoip/dm.png diff --git a/plugins/infowidget/geoip/do.png b/plugins/infowidget/geoip/do.png Binary files differnew file mode 100644 index 0000000..78360ad --- /dev/null +++ b/plugins/infowidget/geoip/do.png diff --git a/plugins/infowidget/geoip/dz.png b/plugins/infowidget/geoip/dz.png Binary files differnew file mode 100644 index 0000000..8a53c6f --- /dev/null +++ b/plugins/infowidget/geoip/dz.png diff --git a/plugins/infowidget/geoip/ec.png b/plugins/infowidget/geoip/ec.png Binary files differnew file mode 100644 index 0000000..aaac909 --- /dev/null +++ b/plugins/infowidget/geoip/ec.png diff --git a/plugins/infowidget/geoip/ee.png b/plugins/infowidget/geoip/ee.png Binary files differnew file mode 100644 index 0000000..6258c3b --- /dev/null +++ b/plugins/infowidget/geoip/ee.png diff --git a/plugins/infowidget/geoip/eg.png b/plugins/infowidget/geoip/eg.png Binary files differnew file mode 100644 index 0000000..8725af0 --- /dev/null +++ b/plugins/infowidget/geoip/eg.png diff --git a/plugins/infowidget/geoip/eh.png b/plugins/infowidget/geoip/eh.png Binary files differnew file mode 100644 index 0000000..e142882 --- /dev/null +++ b/plugins/infowidget/geoip/eh.png diff --git a/plugins/infowidget/geoip/er.png b/plugins/infowidget/geoip/er.png Binary files differnew file mode 100644 index 0000000..dbd752c --- /dev/null +++ b/plugins/infowidget/geoip/er.png diff --git a/plugins/infowidget/geoip/es.png b/plugins/infowidget/geoip/es.png Binary files differnew file mode 100644 index 0000000..dd4d184 --- /dev/null +++ b/plugins/infowidget/geoip/es.png diff --git a/plugins/infowidget/geoip/et.png b/plugins/infowidget/geoip/et.png Binary files differnew file mode 100644 index 0000000..e28bd0b --- /dev/null +++ b/plugins/infowidget/geoip/et.png diff --git a/plugins/infowidget/geoip/eu.png b/plugins/infowidget/geoip/eu.png Binary files differnew file mode 100644 index 0000000..d25bdca --- /dev/null +++ b/plugins/infowidget/geoip/eu.png diff --git a/plugins/infowidget/geoip/fi.png b/plugins/infowidget/geoip/fi.png Binary files differnew file mode 100644 index 0000000..a198c11 --- /dev/null +++ b/plugins/infowidget/geoip/fi.png diff --git a/plugins/infowidget/geoip/fj.png b/plugins/infowidget/geoip/fj.png Binary files differnew file mode 100644 index 0000000..d3c3126 --- /dev/null +++ b/plugins/infowidget/geoip/fj.png diff --git a/plugins/infowidget/geoip/fk.png b/plugins/infowidget/geoip/fk.png Binary files differnew file mode 100644 index 0000000..7141415 --- /dev/null +++ b/plugins/infowidget/geoip/fk.png diff --git a/plugins/infowidget/geoip/fm.png b/plugins/infowidget/geoip/fm.png Binary files differnew file mode 100644 index 0000000..05b7f0c --- /dev/null +++ b/plugins/infowidget/geoip/fm.png diff --git a/plugins/infowidget/geoip/fo.png b/plugins/infowidget/geoip/fo.png Binary files differnew file mode 100644 index 0000000..79311ec --- /dev/null +++ b/plugins/infowidget/geoip/fo.png diff --git a/plugins/infowidget/geoip/fr.png b/plugins/infowidget/geoip/fr.png Binary files differnew file mode 100644 index 0000000..348ffa5 --- /dev/null +++ b/plugins/infowidget/geoip/fr.png diff --git a/plugins/infowidget/geoip/ga.png b/plugins/infowidget/geoip/ga.png Binary files differnew file mode 100644 index 0000000..643093f --- /dev/null +++ b/plugins/infowidget/geoip/ga.png diff --git a/plugins/infowidget/geoip/gb.png b/plugins/infowidget/geoip/gb.png Binary files differnew file mode 100644 index 0000000..45c8bc7 --- /dev/null +++ b/plugins/infowidget/geoip/gb.png diff --git a/plugins/infowidget/geoip/gd.png b/plugins/infowidget/geoip/gd.png Binary files differnew file mode 100644 index 0000000..ad838b9 --- /dev/null +++ b/plugins/infowidget/geoip/gd.png diff --git a/plugins/infowidget/geoip/ge.png b/plugins/infowidget/geoip/ge.png Binary files differnew file mode 100644 index 0000000..75d7c88 --- /dev/null +++ b/plugins/infowidget/geoip/ge.png diff --git a/plugins/infowidget/geoip/geoip.dat b/plugins/infowidget/geoip/geoip.dat Binary files differnew file mode 100644 index 0000000..11f1f6b --- /dev/null +++ b/plugins/infowidget/geoip/geoip.dat diff --git a/plugins/infowidget/geoip/gf.png b/plugins/infowidget/geoip/gf.png Binary files differnew file mode 100644 index 0000000..37f4b07 --- /dev/null +++ b/plugins/infowidget/geoip/gf.png diff --git a/plugins/infowidget/geoip/gh.png b/plugins/infowidget/geoip/gh.png Binary files differnew file mode 100644 index 0000000..798bc00 --- /dev/null +++ b/plugins/infowidget/geoip/gh.png diff --git a/plugins/infowidget/geoip/gi.png b/plugins/infowidget/geoip/gi.png Binary files differnew file mode 100644 index 0000000..2839ba1 --- /dev/null +++ b/plugins/infowidget/geoip/gi.png diff --git a/plugins/infowidget/geoip/gl.png b/plugins/infowidget/geoip/gl.png Binary files differnew file mode 100644 index 0000000..0690b6f --- /dev/null +++ b/plugins/infowidget/geoip/gl.png diff --git a/plugins/infowidget/geoip/gm.png b/plugins/infowidget/geoip/gm.png Binary files differnew file mode 100644 index 0000000..8bcb283 --- /dev/null +++ b/plugins/infowidget/geoip/gm.png diff --git a/plugins/infowidget/geoip/gn.png b/plugins/infowidget/geoip/gn.png Binary files differnew file mode 100644 index 0000000..48ee312 --- /dev/null +++ b/plugins/infowidget/geoip/gn.png diff --git a/plugins/infowidget/geoip/gp.png b/plugins/infowidget/geoip/gp.png Binary files differnew file mode 100644 index 0000000..e627bf2 --- /dev/null +++ b/plugins/infowidget/geoip/gp.png diff --git a/plugins/infowidget/geoip/gq.png b/plugins/infowidget/geoip/gq.png Binary files differnew file mode 100644 index 0000000..4b9a1be --- /dev/null +++ b/plugins/infowidget/geoip/gq.png diff --git a/plugins/infowidget/geoip/gr.png b/plugins/infowidget/geoip/gr.png Binary files differnew file mode 100644 index 0000000..ce31c8b --- /dev/null +++ b/plugins/infowidget/geoip/gr.png diff --git a/plugins/infowidget/geoip/gs.png b/plugins/infowidget/geoip/gs.png Binary files differnew file mode 100644 index 0000000..c0f3d5a --- /dev/null +++ b/plugins/infowidget/geoip/gs.png diff --git a/plugins/infowidget/geoip/gt.png b/plugins/infowidget/geoip/gt.png Binary files differnew file mode 100644 index 0000000..ed7113f --- /dev/null +++ b/plugins/infowidget/geoip/gt.png diff --git a/plugins/infowidget/geoip/gu.png b/plugins/infowidget/geoip/gu.png Binary files differnew file mode 100644 index 0000000..b59cb44 --- /dev/null +++ b/plugins/infowidget/geoip/gu.png diff --git a/plugins/infowidget/geoip/gw.png b/plugins/infowidget/geoip/gw.png Binary files differnew file mode 100644 index 0000000..075c5e2 --- /dev/null +++ b/plugins/infowidget/geoip/gw.png diff --git a/plugins/infowidget/geoip/gy.png b/plugins/infowidget/geoip/gy.png Binary files differnew file mode 100644 index 0000000..fc64031 --- /dev/null +++ b/plugins/infowidget/geoip/gy.png diff --git a/plugins/infowidget/geoip/hk.png b/plugins/infowidget/geoip/hk.png Binary files differnew file mode 100644 index 0000000..c2baf31 --- /dev/null +++ b/plugins/infowidget/geoip/hk.png diff --git a/plugins/infowidget/geoip/hm.png b/plugins/infowidget/geoip/hm.png Binary files differnew file mode 100644 index 0000000..ff84e0b --- /dev/null +++ b/plugins/infowidget/geoip/hm.png diff --git a/plugins/infowidget/geoip/hn.png b/plugins/infowidget/geoip/hn.png Binary files differnew file mode 100644 index 0000000..ff8d0ba --- /dev/null +++ b/plugins/infowidget/geoip/hn.png diff --git a/plugins/infowidget/geoip/hr.png b/plugins/infowidget/geoip/hr.png Binary files differnew file mode 100644 index 0000000..4965c41 --- /dev/null +++ b/plugins/infowidget/geoip/hr.png diff --git a/plugins/infowidget/geoip/ht.png b/plugins/infowidget/geoip/ht.png Binary files differnew file mode 100644 index 0000000..81541e3 --- /dev/null +++ b/plugins/infowidget/geoip/ht.png diff --git a/plugins/infowidget/geoip/hu.png b/plugins/infowidget/geoip/hu.png Binary files differnew file mode 100644 index 0000000..48afe0e --- /dev/null +++ b/plugins/infowidget/geoip/hu.png diff --git a/plugins/infowidget/geoip/id.png b/plugins/infowidget/geoip/id.png Binary files differnew file mode 100644 index 0000000..b824f31 --- /dev/null +++ b/plugins/infowidget/geoip/id.png diff --git a/plugins/infowidget/geoip/ie.png b/plugins/infowidget/geoip/ie.png Binary files differnew file mode 100644 index 0000000..8f881c8 --- /dev/null +++ b/plugins/infowidget/geoip/ie.png diff --git a/plugins/infowidget/geoip/il.png b/plugins/infowidget/geoip/il.png Binary files differnew file mode 100644 index 0000000..68e273c --- /dev/null +++ b/plugins/infowidget/geoip/il.png diff --git a/plugins/infowidget/geoip/in.png b/plugins/infowidget/geoip/in.png Binary files differnew file mode 100644 index 0000000..34abb74 --- /dev/null +++ b/plugins/infowidget/geoip/in.png diff --git a/plugins/infowidget/geoip/io.png b/plugins/infowidget/geoip/io.png Binary files differnew file mode 100644 index 0000000..f5dd57e --- /dev/null +++ b/plugins/infowidget/geoip/io.png diff --git a/plugins/infowidget/geoip/iq.png b/plugins/infowidget/geoip/iq.png Binary files differnew file mode 100644 index 0000000..a457f80 --- /dev/null +++ b/plugins/infowidget/geoip/iq.png diff --git a/plugins/infowidget/geoip/ir.png b/plugins/infowidget/geoip/ir.png Binary files differnew file mode 100644 index 0000000..eac13ef --- /dev/null +++ b/plugins/infowidget/geoip/ir.png diff --git a/plugins/infowidget/geoip/is.png b/plugins/infowidget/geoip/is.png Binary files differnew file mode 100644 index 0000000..2089318 --- /dev/null +++ b/plugins/infowidget/geoip/is.png diff --git a/plugins/infowidget/geoip/it.png b/plugins/infowidget/geoip/it.png Binary files differnew file mode 100644 index 0000000..09836d1 --- /dev/null +++ b/plugins/infowidget/geoip/it.png diff --git a/plugins/infowidget/geoip/jm.png b/plugins/infowidget/geoip/jm.png Binary files differnew file mode 100644 index 0000000..7fdfb37 --- /dev/null +++ b/plugins/infowidget/geoip/jm.png diff --git a/plugins/infowidget/geoip/jo.png b/plugins/infowidget/geoip/jo.png Binary files differnew file mode 100644 index 0000000..2b5077f --- /dev/null +++ b/plugins/infowidget/geoip/jo.png diff --git a/plugins/infowidget/geoip/jp.png b/plugins/infowidget/geoip/jp.png Binary files differnew file mode 100644 index 0000000..98cd271 --- /dev/null +++ b/plugins/infowidget/geoip/jp.png diff --git a/plugins/infowidget/geoip/ke.png b/plugins/infowidget/geoip/ke.png Binary files differnew file mode 100644 index 0000000..8192eb8 --- /dev/null +++ b/plugins/infowidget/geoip/ke.png diff --git a/plugins/infowidget/geoip/kg.png b/plugins/infowidget/geoip/kg.png Binary files differnew file mode 100644 index 0000000..846e83f --- /dev/null +++ b/plugins/infowidget/geoip/kg.png diff --git a/plugins/infowidget/geoip/kh.png b/plugins/infowidget/geoip/kh.png Binary files differnew file mode 100644 index 0000000..e8b4481 --- /dev/null +++ b/plugins/infowidget/geoip/kh.png diff --git a/plugins/infowidget/geoip/ki.png b/plugins/infowidget/geoip/ki.png Binary files differnew file mode 100644 index 0000000..b6e05c6 --- /dev/null +++ b/plugins/infowidget/geoip/ki.png diff --git a/plugins/infowidget/geoip/km.png b/plugins/infowidget/geoip/km.png Binary files differnew file mode 100644 index 0000000..cf3823a --- /dev/null +++ b/plugins/infowidget/geoip/km.png diff --git a/plugins/infowidget/geoip/kn.png b/plugins/infowidget/geoip/kn.png Binary files differnew file mode 100644 index 0000000..82320ae --- /dev/null +++ b/plugins/infowidget/geoip/kn.png diff --git a/plugins/infowidget/geoip/kp.png b/plugins/infowidget/geoip/kp.png Binary files differnew file mode 100644 index 0000000..7d86c9f --- /dev/null +++ b/plugins/infowidget/geoip/kp.png diff --git a/plugins/infowidget/geoip/kr.png b/plugins/infowidget/geoip/kr.png Binary files differnew file mode 100644 index 0000000..93231a8 --- /dev/null +++ b/plugins/infowidget/geoip/kr.png diff --git a/plugins/infowidget/geoip/kw.png b/plugins/infowidget/geoip/kw.png Binary files differnew file mode 100644 index 0000000..11a64ba --- /dev/null +++ b/plugins/infowidget/geoip/kw.png diff --git a/plugins/infowidget/geoip/ky.png b/plugins/infowidget/geoip/ky.png Binary files differnew file mode 100644 index 0000000..94ec427 --- /dev/null +++ b/plugins/infowidget/geoip/ky.png diff --git a/plugins/infowidget/geoip/kz.png b/plugins/infowidget/geoip/kz.png Binary files differnew file mode 100644 index 0000000..d2061c3 --- /dev/null +++ b/plugins/infowidget/geoip/kz.png diff --git a/plugins/infowidget/geoip/la.png b/plugins/infowidget/geoip/la.png Binary files differnew file mode 100644 index 0000000..d15f089 --- /dev/null +++ b/plugins/infowidget/geoip/la.png diff --git a/plugins/infowidget/geoip/lb.png b/plugins/infowidget/geoip/lb.png Binary files differnew file mode 100644 index 0000000..c560362 --- /dev/null +++ b/plugins/infowidget/geoip/lb.png diff --git a/plugins/infowidget/geoip/lc.png b/plugins/infowidget/geoip/lc.png Binary files differnew file mode 100644 index 0000000..bdbe4ea --- /dev/null +++ b/plugins/infowidget/geoip/lc.png diff --git a/plugins/infowidget/geoip/li.png b/plugins/infowidget/geoip/li.png Binary files differnew file mode 100644 index 0000000..82ed982 --- /dev/null +++ b/plugins/infowidget/geoip/li.png diff --git a/plugins/infowidget/geoip/lk.png b/plugins/infowidget/geoip/lk.png Binary files differnew file mode 100644 index 0000000..ea3ec46 --- /dev/null +++ b/plugins/infowidget/geoip/lk.png diff --git a/plugins/infowidget/geoip/lr.png b/plugins/infowidget/geoip/lr.png Binary files differnew file mode 100644 index 0000000..bc55adf --- /dev/null +++ b/plugins/infowidget/geoip/lr.png diff --git a/plugins/infowidget/geoip/ls.png b/plugins/infowidget/geoip/ls.png Binary files differnew file mode 100644 index 0000000..79cd5ad --- /dev/null +++ b/plugins/infowidget/geoip/ls.png diff --git a/plugins/infowidget/geoip/lt.png b/plugins/infowidget/geoip/lt.png Binary files differnew file mode 100644 index 0000000..d865e39 --- /dev/null +++ b/plugins/infowidget/geoip/lt.png diff --git a/plugins/infowidget/geoip/lu.png b/plugins/infowidget/geoip/lu.png Binary files differnew file mode 100644 index 0000000..740a8f7 --- /dev/null +++ b/plugins/infowidget/geoip/lu.png diff --git a/plugins/infowidget/geoip/lv.png b/plugins/infowidget/geoip/lv.png Binary files differnew file mode 100644 index 0000000..d59a1fc --- /dev/null +++ b/plugins/infowidget/geoip/lv.png diff --git a/plugins/infowidget/geoip/ly.png b/plugins/infowidget/geoip/ly.png Binary files differnew file mode 100644 index 0000000..5cb02fb --- /dev/null +++ b/plugins/infowidget/geoip/ly.png diff --git a/plugins/infowidget/geoip/ma.png b/plugins/infowidget/geoip/ma.png Binary files differnew file mode 100644 index 0000000..2737e19 --- /dev/null +++ b/plugins/infowidget/geoip/ma.png diff --git a/plugins/infowidget/geoip/mc.png b/plugins/infowidget/geoip/mc.png Binary files differnew file mode 100644 index 0000000..cfa1b92 --- /dev/null +++ b/plugins/infowidget/geoip/mc.png diff --git a/plugins/infowidget/geoip/md.png b/plugins/infowidget/geoip/md.png Binary files differnew file mode 100644 index 0000000..b88c574 --- /dev/null +++ b/plugins/infowidget/geoip/md.png diff --git a/plugins/infowidget/geoip/mg.png b/plugins/infowidget/geoip/mg.png Binary files differnew file mode 100644 index 0000000..33d38af --- /dev/null +++ b/plugins/infowidget/geoip/mg.png diff --git a/plugins/infowidget/geoip/mh.png b/plugins/infowidget/geoip/mh.png Binary files differnew file mode 100644 index 0000000..344d3ae --- /dev/null +++ b/plugins/infowidget/geoip/mh.png diff --git a/plugins/infowidget/geoip/mk.png b/plugins/infowidget/geoip/mk.png Binary files differnew file mode 100644 index 0000000..af3cd2c --- /dev/null +++ b/plugins/infowidget/geoip/mk.png diff --git a/plugins/infowidget/geoip/ml.png b/plugins/infowidget/geoip/ml.png Binary files differnew file mode 100644 index 0000000..bbc8c61 --- /dev/null +++ b/plugins/infowidget/geoip/ml.png diff --git a/plugins/infowidget/geoip/mm.png b/plugins/infowidget/geoip/mm.png Binary files differnew file mode 100644 index 0000000..f1c021a --- /dev/null +++ b/plugins/infowidget/geoip/mm.png diff --git a/plugins/infowidget/geoip/mn.png b/plugins/infowidget/geoip/mn.png Binary files differnew file mode 100644 index 0000000..5662c2e --- /dev/null +++ b/plugins/infowidget/geoip/mn.png diff --git a/plugins/infowidget/geoip/mo.png b/plugins/infowidget/geoip/mo.png Binary files differnew file mode 100644 index 0000000..68bdd10 --- /dev/null +++ b/plugins/infowidget/geoip/mo.png diff --git a/plugins/infowidget/geoip/mp.png b/plugins/infowidget/geoip/mp.png Binary files differnew file mode 100644 index 0000000..cec5b93 --- /dev/null +++ b/plugins/infowidget/geoip/mp.png diff --git a/plugins/infowidget/geoip/mq.png b/plugins/infowidget/geoip/mq.png Binary files differnew file mode 100644 index 0000000..6704e60 --- /dev/null +++ b/plugins/infowidget/geoip/mq.png diff --git a/plugins/infowidget/geoip/mr.png b/plugins/infowidget/geoip/mr.png Binary files differnew file mode 100644 index 0000000..7b37d98 --- /dev/null +++ b/plugins/infowidget/geoip/mr.png diff --git a/plugins/infowidget/geoip/ms.png b/plugins/infowidget/geoip/ms.png Binary files differnew file mode 100644 index 0000000..487b59b --- /dev/null +++ b/plugins/infowidget/geoip/ms.png diff --git a/plugins/infowidget/geoip/mt.png b/plugins/infowidget/geoip/mt.png Binary files differnew file mode 100644 index 0000000..2cd7bb9 --- /dev/null +++ b/plugins/infowidget/geoip/mt.png diff --git a/plugins/infowidget/geoip/mu.png b/plugins/infowidget/geoip/mu.png Binary files differnew file mode 100644 index 0000000..d57f15e --- /dev/null +++ b/plugins/infowidget/geoip/mu.png diff --git a/plugins/infowidget/geoip/mv.png b/plugins/infowidget/geoip/mv.png Binary files differnew file mode 100644 index 0000000..4972a4c --- /dev/null +++ b/plugins/infowidget/geoip/mv.png diff --git a/plugins/infowidget/geoip/mw.png b/plugins/infowidget/geoip/mw.png Binary files differnew file mode 100644 index 0000000..9086528 --- /dev/null +++ b/plugins/infowidget/geoip/mw.png diff --git a/plugins/infowidget/geoip/mx.png b/plugins/infowidget/geoip/mx.png Binary files differnew file mode 100644 index 0000000..c68a926 --- /dev/null +++ b/plugins/infowidget/geoip/mx.png diff --git a/plugins/infowidget/geoip/my.png b/plugins/infowidget/geoip/my.png Binary files differnew file mode 100644 index 0000000..2989d2e --- /dev/null +++ b/plugins/infowidget/geoip/my.png diff --git a/plugins/infowidget/geoip/mz.png b/plugins/infowidget/geoip/mz.png Binary files differnew file mode 100644 index 0000000..7281b03 --- /dev/null +++ b/plugins/infowidget/geoip/mz.png diff --git a/plugins/infowidget/geoip/na.png b/plugins/infowidget/geoip/na.png Binary files differnew file mode 100644 index 0000000..258c942 --- /dev/null +++ b/plugins/infowidget/geoip/na.png diff --git a/plugins/infowidget/geoip/nc.png b/plugins/infowidget/geoip/nc.png Binary files differnew file mode 100644 index 0000000..2abf002 --- /dev/null +++ b/plugins/infowidget/geoip/nc.png diff --git a/plugins/infowidget/geoip/ne.png b/plugins/infowidget/geoip/ne.png Binary files differnew file mode 100644 index 0000000..d0c59a1 --- /dev/null +++ b/plugins/infowidget/geoip/ne.png diff --git a/plugins/infowidget/geoip/nf.png b/plugins/infowidget/geoip/nf.png Binary files differnew file mode 100644 index 0000000..a119153 --- /dev/null +++ b/plugins/infowidget/geoip/nf.png diff --git a/plugins/infowidget/geoip/ng.png b/plugins/infowidget/geoip/ng.png Binary files differnew file mode 100644 index 0000000..44492e1 --- /dev/null +++ b/plugins/infowidget/geoip/ng.png diff --git a/plugins/infowidget/geoip/ni.png b/plugins/infowidget/geoip/ni.png Binary files differnew file mode 100644 index 0000000..805b800 --- /dev/null +++ b/plugins/infowidget/geoip/ni.png diff --git a/plugins/infowidget/geoip/nl.png b/plugins/infowidget/geoip/nl.png Binary files differnew file mode 100644 index 0000000..24b3e42 --- /dev/null +++ b/plugins/infowidget/geoip/nl.png diff --git a/plugins/infowidget/geoip/no.png b/plugins/infowidget/geoip/no.png Binary files differnew file mode 100644 index 0000000..c5d3441 --- /dev/null +++ b/plugins/infowidget/geoip/no.png diff --git a/plugins/infowidget/geoip/np.png b/plugins/infowidget/geoip/np.png Binary files differnew file mode 100644 index 0000000..35856b5 --- /dev/null +++ b/plugins/infowidget/geoip/np.png diff --git a/plugins/infowidget/geoip/nr.png b/plugins/infowidget/geoip/nr.png Binary files differnew file mode 100644 index 0000000..e0a801e --- /dev/null +++ b/plugins/infowidget/geoip/nr.png diff --git a/plugins/infowidget/geoip/nu.png b/plugins/infowidget/geoip/nu.png Binary files differnew file mode 100644 index 0000000..561ca9e --- /dev/null +++ b/plugins/infowidget/geoip/nu.png diff --git a/plugins/infowidget/geoip/nz.png b/plugins/infowidget/geoip/nz.png Binary files differnew file mode 100644 index 0000000..2e2cb1b --- /dev/null +++ b/plugins/infowidget/geoip/nz.png diff --git a/plugins/infowidget/geoip/om.png b/plugins/infowidget/geoip/om.png Binary files differnew file mode 100644 index 0000000..f6a8b4f --- /dev/null +++ b/plugins/infowidget/geoip/om.png diff --git a/plugins/infowidget/geoip/pa.png b/plugins/infowidget/geoip/pa.png Binary files differnew file mode 100644 index 0000000..97c3335 --- /dev/null +++ b/plugins/infowidget/geoip/pa.png diff --git a/plugins/infowidget/geoip/pe.png b/plugins/infowidget/geoip/pe.png Binary files differnew file mode 100644 index 0000000..3b8bdf8 --- /dev/null +++ b/plugins/infowidget/geoip/pe.png diff --git a/plugins/infowidget/geoip/pf.png b/plugins/infowidget/geoip/pf.png Binary files differnew file mode 100644 index 0000000..8b25d20 --- /dev/null +++ b/plugins/infowidget/geoip/pf.png diff --git a/plugins/infowidget/geoip/pg.png b/plugins/infowidget/geoip/pg.png Binary files differnew file mode 100644 index 0000000..1e2ba72 --- /dev/null +++ b/plugins/infowidget/geoip/pg.png diff --git a/plugins/infowidget/geoip/ph.png b/plugins/infowidget/geoip/ph.png Binary files differnew file mode 100644 index 0000000..6758586 --- /dev/null +++ b/plugins/infowidget/geoip/ph.png diff --git a/plugins/infowidget/geoip/pk.png b/plugins/infowidget/geoip/pk.png Binary files differnew file mode 100644 index 0000000..fb7d7a4 --- /dev/null +++ b/plugins/infowidget/geoip/pk.png diff --git a/plugins/infowidget/geoip/pl.png b/plugins/infowidget/geoip/pl.png Binary files differnew file mode 100644 index 0000000..d0d71b7 --- /dev/null +++ b/plugins/infowidget/geoip/pl.png diff --git a/plugins/infowidget/geoip/pm.png b/plugins/infowidget/geoip/pm.png Binary files differnew file mode 100644 index 0000000..bb7b62e --- /dev/null +++ b/plugins/infowidget/geoip/pm.png diff --git a/plugins/infowidget/geoip/pn.png b/plugins/infowidget/geoip/pn.png Binary files differnew file mode 100644 index 0000000..727b47e --- /dev/null +++ b/plugins/infowidget/geoip/pn.png diff --git a/plugins/infowidget/geoip/pr.png b/plugins/infowidget/geoip/pr.png Binary files differnew file mode 100644 index 0000000..4487e33 --- /dev/null +++ b/plugins/infowidget/geoip/pr.png diff --git a/plugins/infowidget/geoip/ps.png b/plugins/infowidget/geoip/ps.png Binary files differnew file mode 100644 index 0000000..0a26426 --- /dev/null +++ b/plugins/infowidget/geoip/ps.png diff --git a/plugins/infowidget/geoip/pt.png b/plugins/infowidget/geoip/pt.png Binary files differnew file mode 100644 index 0000000..8dbc9c9 --- /dev/null +++ b/plugins/infowidget/geoip/pt.png diff --git a/plugins/infowidget/geoip/pw.png b/plugins/infowidget/geoip/pw.png Binary files differnew file mode 100644 index 0000000..6a79ad8 --- /dev/null +++ b/plugins/infowidget/geoip/pw.png diff --git a/plugins/infowidget/geoip/py.png b/plugins/infowidget/geoip/py.png Binary files differnew file mode 100644 index 0000000..79fb185 --- /dev/null +++ b/plugins/infowidget/geoip/py.png diff --git a/plugins/infowidget/geoip/qa.png b/plugins/infowidget/geoip/qa.png Binary files differnew file mode 100644 index 0000000..c74d326 --- /dev/null +++ b/plugins/infowidget/geoip/qa.png diff --git a/plugins/infowidget/geoip/re.png b/plugins/infowidget/geoip/re.png Binary files differnew file mode 100644 index 0000000..07ba0c7 --- /dev/null +++ b/plugins/infowidget/geoip/re.png diff --git a/plugins/infowidget/geoip/ro.png b/plugins/infowidget/geoip/ro.png Binary files differnew file mode 100644 index 0000000..09eee0e --- /dev/null +++ b/plugins/infowidget/geoip/ro.png diff --git a/plugins/infowidget/geoip/ru.png b/plugins/infowidget/geoip/ru.png Binary files differnew file mode 100644 index 0000000..7944b95 --- /dev/null +++ b/plugins/infowidget/geoip/ru.png diff --git a/plugins/infowidget/geoip/rw.png b/plugins/infowidget/geoip/rw.png Binary files differnew file mode 100644 index 0000000..1526936 --- /dev/null +++ b/plugins/infowidget/geoip/rw.png diff --git a/plugins/infowidget/geoip/sa.png b/plugins/infowidget/geoip/sa.png Binary files differnew file mode 100644 index 0000000..5d9420d --- /dev/null +++ b/plugins/infowidget/geoip/sa.png diff --git a/plugins/infowidget/geoip/sb.png b/plugins/infowidget/geoip/sb.png Binary files differnew file mode 100644 index 0000000..50a584e --- /dev/null +++ b/plugins/infowidget/geoip/sb.png diff --git a/plugins/infowidget/geoip/sc.png b/plugins/infowidget/geoip/sc.png Binary files differnew file mode 100644 index 0000000..0f1ea8c --- /dev/null +++ b/plugins/infowidget/geoip/sc.png diff --git a/plugins/infowidget/geoip/sd.png b/plugins/infowidget/geoip/sd.png Binary files differnew file mode 100644 index 0000000..cfd32d9 --- /dev/null +++ b/plugins/infowidget/geoip/sd.png diff --git a/plugins/infowidget/geoip/se.png b/plugins/infowidget/geoip/se.png Binary files differnew file mode 100644 index 0000000..ba49b92 --- /dev/null +++ b/plugins/infowidget/geoip/se.png diff --git a/plugins/infowidget/geoip/sg.png b/plugins/infowidget/geoip/sg.png Binary files differnew file mode 100644 index 0000000..db17483 --- /dev/null +++ b/plugins/infowidget/geoip/sg.png diff --git a/plugins/infowidget/geoip/sh.png b/plugins/infowidget/geoip/sh.png Binary files differnew file mode 100644 index 0000000..fa95fc4 --- /dev/null +++ b/plugins/infowidget/geoip/sh.png diff --git a/plugins/infowidget/geoip/si.png b/plugins/infowidget/geoip/si.png Binary files differnew file mode 100644 index 0000000..420c623 --- /dev/null +++ b/plugins/infowidget/geoip/si.png diff --git a/plugins/infowidget/geoip/sj.png b/plugins/infowidget/geoip/sj.png Binary files differnew file mode 100644 index 0000000..316e9e8 --- /dev/null +++ b/plugins/infowidget/geoip/sj.png diff --git a/plugins/infowidget/geoip/sk.png b/plugins/infowidget/geoip/sk.png Binary files differnew file mode 100644 index 0000000..1abf082 --- /dev/null +++ b/plugins/infowidget/geoip/sk.png diff --git a/plugins/infowidget/geoip/sl.png b/plugins/infowidget/geoip/sl.png Binary files differnew file mode 100644 index 0000000..824f979 --- /dev/null +++ b/plugins/infowidget/geoip/sl.png diff --git a/plugins/infowidget/geoip/sm.png b/plugins/infowidget/geoip/sm.png Binary files differnew file mode 100644 index 0000000..e9d4f2b --- /dev/null +++ b/plugins/infowidget/geoip/sm.png diff --git a/plugins/infowidget/geoip/sn.png b/plugins/infowidget/geoip/sn.png Binary files differnew file mode 100644 index 0000000..c9b026a --- /dev/null +++ b/plugins/infowidget/geoip/sn.png diff --git a/plugins/infowidget/geoip/so.png b/plugins/infowidget/geoip/so.png Binary files differnew file mode 100644 index 0000000..c7c155d --- /dev/null +++ b/plugins/infowidget/geoip/so.png diff --git a/plugins/infowidget/geoip/sr.png b/plugins/infowidget/geoip/sr.png Binary files differnew file mode 100644 index 0000000..b838461 --- /dev/null +++ b/plugins/infowidget/geoip/sr.png diff --git a/plugins/infowidget/geoip/st.png b/plugins/infowidget/geoip/st.png Binary files differnew file mode 100644 index 0000000..1be3857 --- /dev/null +++ b/plugins/infowidget/geoip/st.png diff --git a/plugins/infowidget/geoip/sv.png b/plugins/infowidget/geoip/sv.png Binary files differnew file mode 100644 index 0000000..fc5c5b5 --- /dev/null +++ b/plugins/infowidget/geoip/sv.png diff --git a/plugins/infowidget/geoip/sy.png b/plugins/infowidget/geoip/sy.png Binary files differnew file mode 100644 index 0000000..87a102d --- /dev/null +++ b/plugins/infowidget/geoip/sy.png diff --git a/plugins/infowidget/geoip/sz.png b/plugins/infowidget/geoip/sz.png Binary files differnew file mode 100644 index 0000000..847704f --- /dev/null +++ b/plugins/infowidget/geoip/sz.png diff --git a/plugins/infowidget/geoip/tc.png b/plugins/infowidget/geoip/tc.png Binary files differnew file mode 100644 index 0000000..a2dd1e3 --- /dev/null +++ b/plugins/infowidget/geoip/tc.png diff --git a/plugins/infowidget/geoip/td.png b/plugins/infowidget/geoip/td.png Binary files differnew file mode 100644 index 0000000..8d76050 --- /dev/null +++ b/plugins/infowidget/geoip/td.png diff --git a/plugins/infowidget/geoip/tf.png b/plugins/infowidget/geoip/tf.png Binary files differnew file mode 100644 index 0000000..8b14629 --- /dev/null +++ b/plugins/infowidget/geoip/tf.png diff --git a/plugins/infowidget/geoip/tg.png b/plugins/infowidget/geoip/tg.png Binary files differnew file mode 100644 index 0000000..1ab1584 --- /dev/null +++ b/plugins/infowidget/geoip/tg.png diff --git a/plugins/infowidget/geoip/th.png b/plugins/infowidget/geoip/th.png Binary files differnew file mode 100644 index 0000000..b4af833 --- /dev/null +++ b/plugins/infowidget/geoip/th.png diff --git a/plugins/infowidget/geoip/tj.png b/plugins/infowidget/geoip/tj.png Binary files differnew file mode 100644 index 0000000..bc08004 --- /dev/null +++ b/plugins/infowidget/geoip/tj.png diff --git a/plugins/infowidget/geoip/tk.png b/plugins/infowidget/geoip/tk.png Binary files differnew file mode 100644 index 0000000..d18f222 --- /dev/null +++ b/plugins/infowidget/geoip/tk.png diff --git a/plugins/infowidget/geoip/tl.png b/plugins/infowidget/geoip/tl.png Binary files differnew file mode 100644 index 0000000..3a5a3df --- /dev/null +++ b/plugins/infowidget/geoip/tl.png diff --git a/plugins/infowidget/geoip/tm.png b/plugins/infowidget/geoip/tm.png Binary files differnew file mode 100644 index 0000000..bdde4d2 --- /dev/null +++ b/plugins/infowidget/geoip/tm.png diff --git a/plugins/infowidget/geoip/tn.png b/plugins/infowidget/geoip/tn.png Binary files differnew file mode 100644 index 0000000..b1d8786 --- /dev/null +++ b/plugins/infowidget/geoip/tn.png diff --git a/plugins/infowidget/geoip/to.png b/plugins/infowidget/geoip/to.png Binary files differnew file mode 100644 index 0000000..9ffad3f --- /dev/null +++ b/plugins/infowidget/geoip/to.png diff --git a/plugins/infowidget/geoip/tp.png b/plugins/infowidget/geoip/tp.png Binary files differnew file mode 100644 index 0000000..2f9e1c5 --- /dev/null +++ b/plugins/infowidget/geoip/tp.png diff --git a/plugins/infowidget/geoip/tr.png b/plugins/infowidget/geoip/tr.png Binary files differnew file mode 100644 index 0000000..834ff3b --- /dev/null +++ b/plugins/infowidget/geoip/tr.png diff --git a/plugins/infowidget/geoip/tt.png b/plugins/infowidget/geoip/tt.png Binary files differnew file mode 100644 index 0000000..8a4697e --- /dev/null +++ b/plugins/infowidget/geoip/tt.png diff --git a/plugins/infowidget/geoip/tv.png b/plugins/infowidget/geoip/tv.png Binary files differnew file mode 100644 index 0000000..3cf5a6a --- /dev/null +++ b/plugins/infowidget/geoip/tv.png diff --git a/plugins/infowidget/geoip/tw.png b/plugins/infowidget/geoip/tw.png Binary files differnew file mode 100644 index 0000000..612811e --- /dev/null +++ b/plugins/infowidget/geoip/tw.png diff --git a/plugins/infowidget/geoip/tz.png b/plugins/infowidget/geoip/tz.png Binary files differnew file mode 100644 index 0000000..38cf2ae --- /dev/null +++ b/plugins/infowidget/geoip/tz.png diff --git a/plugins/infowidget/geoip/ua.png b/plugins/infowidget/geoip/ua.png Binary files differnew file mode 100644 index 0000000..b1f05dd --- /dev/null +++ b/plugins/infowidget/geoip/ua.png diff --git a/plugins/infowidget/geoip/ug.png b/plugins/infowidget/geoip/ug.png Binary files differnew file mode 100644 index 0000000..9e18382 --- /dev/null +++ b/plugins/infowidget/geoip/ug.png diff --git a/plugins/infowidget/geoip/um.png b/plugins/infowidget/geoip/um.png Binary files differnew file mode 100644 index 0000000..02abc0f --- /dev/null +++ b/plugins/infowidget/geoip/um.png diff --git a/plugins/infowidget/geoip/us.png b/plugins/infowidget/geoip/us.png Binary files differnew file mode 100644 index 0000000..21aedb8 --- /dev/null +++ b/plugins/infowidget/geoip/us.png diff --git a/plugins/infowidget/geoip/uy.png b/plugins/infowidget/geoip/uy.png Binary files differnew file mode 100644 index 0000000..94b3e69 --- /dev/null +++ b/plugins/infowidget/geoip/uy.png diff --git a/plugins/infowidget/geoip/uz.png b/plugins/infowidget/geoip/uz.png Binary files differnew file mode 100644 index 0000000..f336c66 --- /dev/null +++ b/plugins/infowidget/geoip/uz.png diff --git a/plugins/infowidget/geoip/va.png b/plugins/infowidget/geoip/va.png Binary files differnew file mode 100644 index 0000000..bd6488a --- /dev/null +++ b/plugins/infowidget/geoip/va.png diff --git a/plugins/infowidget/geoip/vc.png b/plugins/infowidget/geoip/vc.png Binary files differnew file mode 100644 index 0000000..6b697e6 --- /dev/null +++ b/plugins/infowidget/geoip/vc.png diff --git a/plugins/infowidget/geoip/ve.png b/plugins/infowidget/geoip/ve.png Binary files differnew file mode 100644 index 0000000..3fbf630 --- /dev/null +++ b/plugins/infowidget/geoip/ve.png diff --git a/plugins/infowidget/geoip/vg.png b/plugins/infowidget/geoip/vg.png Binary files differnew file mode 100644 index 0000000..6ebc938 --- /dev/null +++ b/plugins/infowidget/geoip/vg.png diff --git a/plugins/infowidget/geoip/vi.png b/plugins/infowidget/geoip/vi.png Binary files differnew file mode 100644 index 0000000..d98b021 --- /dev/null +++ b/plugins/infowidget/geoip/vi.png diff --git a/plugins/infowidget/geoip/vn.png b/plugins/infowidget/geoip/vn.png Binary files differnew file mode 100644 index 0000000..23add83 --- /dev/null +++ b/plugins/infowidget/geoip/vn.png diff --git a/plugins/infowidget/geoip/vu.png b/plugins/infowidget/geoip/vu.png Binary files differnew file mode 100644 index 0000000..131d19a --- /dev/null +++ b/plugins/infowidget/geoip/vu.png diff --git a/plugins/infowidget/geoip/wf.png b/plugins/infowidget/geoip/wf.png Binary files differnew file mode 100644 index 0000000..9576dc7 --- /dev/null +++ b/plugins/infowidget/geoip/wf.png diff --git a/plugins/infowidget/geoip/ws.png b/plugins/infowidget/geoip/ws.png Binary files differnew file mode 100644 index 0000000..dc44158 --- /dev/null +++ b/plugins/infowidget/geoip/ws.png diff --git a/plugins/infowidget/geoip/ye.png b/plugins/infowidget/geoip/ye.png Binary files differnew file mode 100644 index 0000000..245f46f --- /dev/null +++ b/plugins/infowidget/geoip/ye.png diff --git a/plugins/infowidget/geoip/yt.png b/plugins/infowidget/geoip/yt.png Binary files differnew file mode 100644 index 0000000..3e6ef07 --- /dev/null +++ b/plugins/infowidget/geoip/yt.png diff --git a/plugins/infowidget/geoip/yu.png b/plugins/infowidget/geoip/yu.png Binary files differnew file mode 100644 index 0000000..b00030c --- /dev/null +++ b/plugins/infowidget/geoip/yu.png diff --git a/plugins/infowidget/geoip/za.png b/plugins/infowidget/geoip/za.png Binary files differnew file mode 100644 index 0000000..c601244 --- /dev/null +++ b/plugins/infowidget/geoip/za.png diff --git a/plugins/infowidget/geoip/zm.png b/plugins/infowidget/geoip/zm.png Binary files differnew file mode 100644 index 0000000..201f4cf --- /dev/null +++ b/plugins/infowidget/geoip/zm.png diff --git a/plugins/infowidget/geoip/zw.png b/plugins/infowidget/geoip/zw.png Binary files differnew file mode 100644 index 0000000..66754d4 --- /dev/null +++ b/plugins/infowidget/geoip/zw.png diff --git a/plugins/infowidget/infowidgetplugin.cpp b/plugins/infowidget/infowidgetplugin.cpp new file mode 100644 index 0000000..4957c48 --- /dev/null +++ b/plugins/infowidget/infowidgetplugin.cpp @@ -0,0 +1,244 @@ +/*************************************************************************** + * 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 <qscrollview.h> +#include <kgenericfactory.h> +#include <kglobal.h> +#include <klocale.h> +#include <interfaces/coreinterface.h> +#include <interfaces/guiinterface.h> +#include <interfaces/torrentinterface.h> + +#include "infowidgetplugin.h" +#include "infowidgetprefpage.h" +#include "statustab.h" +#include "fileview.h" +#include "chunkdownloadview.h" +#include "peerview.h" +#include "trackerview.h" +#include "infowidgetpluginsettings.h" +#include "ktorrentmonitor.h" + + +#define NAME "Info Widget" +#define AUTHOR "Joris Guisson" +#define EMAIL "joris.guisson@gmail.com" + + +K_EXPORT_COMPONENT_FACTORY(ktinfowidgetplugin,KGenericFactory<kt::InfoWidgetPlugin>("ktinfowidgetplugin")) + +namespace kt +{ + + + InfoWidgetPlugin::InfoWidgetPlugin(QObject* parent, const char* name, const QStringList& args) + : Plugin(parent, name, args,NAME,i18n("Info Widget"),AUTHOR,EMAIL, + i18n("Shows additional information about a download. Like which chunks have been downloaded, how many seeders and leechers ..."), + "ktinfowidget") + { + pref = 0; + peer_view = 0; + cd_view = 0; + tracker_view = 0; + file_view = 0; + status_tab = 0; + monitor = 0; + } + + + InfoWidgetPlugin::~InfoWidgetPlugin() + {} + + + void InfoWidgetPlugin::load() + { + status_tab = new StatusTab(0); + file_view = new FileView(0); + + pref = new InfoWidgetPrefPage(this); + getGUI()->addViewListener(this); + getGUI()->addToolWidget(status_tab,"info",i18n("Status"),GUIInterface::DOCK_BOTTOM); + getGUI()->addToolWidget(file_view,"folder",i18n("Files"),GUIInterface::DOCK_BOTTOM); + + showPeerView( InfoWidgetPluginSettings::showPeerView() ); + showChunkView( InfoWidgetPluginSettings::showChunkView() ); + showTrackerView( InfoWidgetPluginSettings::showTrackersView() ); + + getGUI()->addPrefPage(pref); + currentTorrentChanged(const_cast<kt::TorrentInterface*>(getGUI()->getCurrentTorrent())); + + file_view->restoreLayout(KGlobal::config(),"FileView"); + } + + void InfoWidgetPlugin::unload() + { + if (cd_view) + cd_view->saveLayout(KGlobal::config(),"ChunkDownloadView"); + if (peer_view) + peer_view->saveLayout(KGlobal::config(),"PeerView"); + if (file_view) + file_view->saveLayout(KGlobal::config(),"FileView"); + + getGUI()->removeViewListener(this); + getGUI()->removePrefPage(pref); + getGUI()->removeToolWidget(status_tab); + getGUI()->removeToolWidget(file_view); + if (cd_view) + getGUI()->removeToolWidget(cd_view); + if (tracker_view) + getGUI()->removeToolWidget(tracker_view); + if (peer_view) + getGUI()->removeToolWidget(peer_view); + + delete monitor; + monitor = 0; + delete status_tab; + status_tab = 0; + delete file_view; + file_view = 0; + delete cd_view; + cd_view = 0; + delete peer_view; + peer_view = 0; + delete tracker_view; + tracker_view = 0; + delete pref; + pref = 0; + } + + void InfoWidgetPlugin::guiUpdate() + { + if (status_tab && status_tab->isVisible()) + status_tab->update(); + + if (file_view && file_view->isVisible()) + file_view->update(); + + if (peer_view && peer_view->isVisible()) + peer_view->update(); + + if (cd_view && cd_view->isVisible()) + cd_view->update(); + + if (tracker_view && tracker_view->isVisible()) + tracker_view->update(); + } + + void InfoWidgetPlugin::currentTorrentChanged(TorrentInterface* tc) + { + if (status_tab) + status_tab->changeTC(tc); + if (file_view) + file_view->changeTC(tc); + if (cd_view) + cd_view->changeTC(tc); + if (tracker_view) + tracker_view->changeTC(tc); + + if (peer_view) + peer_view->setEnabled(tc != 0); + + createMonitor(tc); + } + + bool InfoWidgetPlugin::versionCheck(const QString & version) const + { + return version == KT_VERSION_MACRO; + } + + + void InfoWidgetPlugin::showPeerView(bool show) + { + kt::TorrentInterface* tc = const_cast<kt::TorrentInterface*>(getGUI()->getCurrentTorrent()); + + if (show && !peer_view) + { + peer_view = new PeerView(0); + getGUI()->addToolWidget(peer_view,"kdmconfig",i18n("Peers"),GUIInterface::DOCK_BOTTOM); + + peer_view->restoreLayout(KGlobal::config(),"PeerView"); + createMonitor(tc); + } + else if (!show && peer_view) + { + peer_view->saveLayout(KGlobal::config(),"PeerView"); + getGUI()->removeToolWidget(peer_view); + delete peer_view; peer_view = 0; + createMonitor(tc); + } + } + + void InfoWidgetPlugin::showChunkView(bool show) + { + kt::TorrentInterface* tc = const_cast<kt::TorrentInterface*>(getGUI()->getCurrentTorrent()); + + if (show && !cd_view) + { + cd_view = new ChunkDownloadView(0); + getGUI()->addToolWidget(cd_view,"fifteenpieces",i18n("Chunks"),GUIInterface::DOCK_BOTTOM); + + cd_view->restoreLayout(KGlobal::config(),"ChunkDownloadView"); + cd_view->changeTC(tc); + createMonitor(tc); + } + else if (!show && cd_view) + { + cd_view->saveLayout(KGlobal::config(),"ChunkDownloadView"); + getGUI()->removeToolWidget(cd_view); + delete cd_view; cd_view = 0; + createMonitor(tc); + } + } + + void InfoWidgetPlugin::showTrackerView(bool show) + { + if (show && !tracker_view) + { + tracker_view = new TrackerView(0); + getGUI()->addToolWidget(tracker_view,"network",i18n("Trackers"), + GUIInterface::DOCK_BOTTOM); + tracker_view->changeTC(const_cast<kt::TorrentInterface*>(getGUI()->getCurrentTorrent())); + // seeing that a merge of the trackers might happen after a torrent has been loaded + // we need to update the tracker_view + connect(getCore(),SIGNAL(loadingFinished(const KURL&, bool, bool)), + tracker_view,SLOT(onLoadingFinished(const KURL&, bool, bool))); + } + else if (!show && tracker_view) + { + getGUI()->removeToolWidget(tracker_view); + delete tracker_view; tracker_view = 0; + } + } + + void InfoWidgetPlugin::createMonitor(TorrentInterface* tc) + { + if (monitor) + delete monitor; monitor = 0; + + if (peer_view) + peer_view->removeAll(); + if (cd_view) + cd_view->removeAll(); + + if (tc && (peer_view || cd_view)) + monitor = new KTorrentMonitor(tc,peer_view,cd_view); + } +} + +#include "infowidgetplugin.moc" diff --git a/plugins/infowidget/infowidgetplugin.h b/plugins/infowidget/infowidgetplugin.h new file mode 100644 index 0000000..9e08e75 --- /dev/null +++ b/plugins/infowidget/infowidgetplugin.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 KTINFOWIDGETPLUGIN_H +#define KTINFOWIDGETPLUGIN_H + +#include <interfaces/plugin.h> +#include <interfaces/guiinterface.h> + + + +namespace kt +{ + class PeerView; + class TrackerView; + class StatusTab; + class FileView; + class ChunkDownloadView; + class InfoWidgetPrefPage; + class KTorrentMonitor; + + + /** + @author Joris Guisson + */ + class InfoWidgetPlugin : public Plugin,public ViewListener + { + Q_OBJECT + public: + InfoWidgetPlugin(QObject* parent, const char* name, const QStringList& args); + virtual ~InfoWidgetPlugin(); + + virtual void load(); + virtual void unload(); + virtual void guiUpdate(); + virtual void currentTorrentChanged(TorrentInterface* tc); + virtual bool versionCheck(const QString & version) const; + + ///Show PeerView in main window + void showPeerView(bool show); + ///Show ChunkDownloadView in main window + void showChunkView(bool show); + ///Show TrackerView in main window + void showTrackerView(bool show); + private: + void createMonitor(TorrentInterface* tc); + + private: + PeerView* peer_view; + ChunkDownloadView* cd_view; + TrackerView* tracker_view; + FileView* file_view; + StatusTab* status_tab; + KTorrentMonitor* monitor; + + InfoWidgetPrefPage* pref; + }; + +} + +#endif diff --git a/plugins/infowidget/infowidgetpluginsettings.kcfgc b/plugins/infowidget/infowidgetpluginsettings.kcfgc new file mode 100644 index 0000000..39b3109 --- /dev/null +++ b/plugins/infowidget/infowidgetpluginsettings.kcfgc @@ -0,0 +1,7 @@ +# Code generation options for kconfig_compiler +File=ktinfowidgetplugin.kcfg +ClassName=InfoWidgetPluginSettings +Namespace=kt +Singleton=true +Mutators=true +# will create the necessary code for setting those variables diff --git a/plugins/infowidget/infowidgetprefpage.cpp b/plugins/infowidget/infowidgetprefpage.cpp new file mode 100644 index 0000000..16e1384 --- /dev/null +++ b/plugins/infowidget/infowidgetprefpage.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 <klocale.h> +#include <qcheckbox.h> +#include <kglobal.h> +#include <kiconloader.h> +#include "infowidgetplugin.h" +#include "infowidgetprefpage.h" +#include "infowidgetpluginsettings.h" +#include "iwpref.h" + + +namespace kt +{ + + InfoWidgetPrefPage::InfoWidgetPrefPage(InfoWidgetPlugin* iw) + : PrefPageInterface(i18n("Info Widget"),i18n("Information Widget Options"),KGlobal::iconLoader()->loadIcon("ktinfowidget",KIcon::NoGroup)),iw(iw) + { + pref = 0; + } + + + InfoWidgetPrefPage::~InfoWidgetPrefPage() + {} + + + bool InfoWidgetPrefPage::apply() + { + InfoWidgetPluginSettings::setShowPeerView(pref->m_show_pv->isChecked()); + InfoWidgetPluginSettings::setShowChunkView(pref->m_show_cdv->isChecked()); + InfoWidgetPluginSettings::setShowTrackersView(pref->m_show_tv->isChecked()); + InfoWidgetPluginSettings::writeConfig(); + iw->showPeerView( InfoWidgetPluginSettings::showPeerView() ); + iw->showChunkView( InfoWidgetPluginSettings::showChunkView() ); + iw->showTrackerView( InfoWidgetPluginSettings::showTrackersView() ); + return true; + } + + void InfoWidgetPrefPage::createWidget(QWidget* parent) + { + pref = new IWPref(parent); + updateData(); + } + + void InfoWidgetPrefPage::deleteWidget() + { + delete pref; + } + + void InfoWidgetPrefPage::updateData() + { + pref->m_show_pv->setChecked(InfoWidgetPluginSettings::showPeerView()); + pref->m_show_cdv->setChecked(InfoWidgetPluginSettings::showChunkView()); + pref->m_show_tv->setChecked(InfoWidgetPluginSettings::showTrackersView()); + } + +} diff --git a/plugins/infowidget/infowidgetprefpage.h b/plugins/infowidget/infowidgetprefpage.h new file mode 100644 index 0000000..a1fa40f --- /dev/null +++ b/plugins/infowidget/infowidgetprefpage.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * 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 KTINFOWIDGETPREFPAGE_H +#define KTINFOWIDGETPREFPAGE_H + +#include <interfaces/prefpageinterface.h> + +class IWPref; + +namespace kt +{ + class InfoWidgetPlugin; + + + /** + @author Joris Guisson + */ + class InfoWidgetPrefPage : public PrefPageInterface + { + InfoWidgetPlugin* iw; + IWPref* pref; + public: + InfoWidgetPrefPage(InfoWidgetPlugin* iw); + virtual ~InfoWidgetPrefPage(); + + virtual bool apply(); + virtual void createWidget(QWidget* parent); + virtual void deleteWidget(); + virtual void updateData(); + + }; + +} + +#endif diff --git a/plugins/infowidget/iwfiletreediritem.cpp b/plugins/infowidget/iwfiletreediritem.cpp new file mode 100644 index 0000000..1ddf899 --- /dev/null +++ b/plugins/infowidget/iwfiletreediritem.cpp @@ -0,0 +1,224 @@ +/*************************************************************************** + * 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 <kglobal.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <util/functions.h> +#include <interfaces/torrentfileinterface.h> +#include <interfaces/torrentinterface.h> +#include "iwfiletreediritem.h" +#include "iwfiletreeitem.h" +#include "functions.h" + +using namespace kt; + +namespace kt +{ + + IWFileTreeDirItem::IWFileTreeDirItem(KListView* klv,const QString & name) + : kt::FileTreeDirItem(klv,name) + { + } + + IWFileTreeDirItem::IWFileTreeDirItem(IWFileTreeDirItem* parent,const QString & name) + : kt::FileTreeDirItem(parent,name) + { + } + + IWFileTreeDirItem::~IWFileTreeDirItem() + { + } + + + void IWFileTreeDirItem::updatePercentageInformation() + { + // first set all the child items + bt::PtrMap<QString,FileTreeItem>::iterator i = children.begin(); + while (i != children.end()) + { + IWFileTreeItem* item = (IWFileTreeItem*)i->second; + item->updatePercentageInformation(); + i++; + } + + // then recursivly move on to subdirs + bt::PtrMap<QString,FileTreeDirItem>::iterator j = subdirs.begin(); + while (j != subdirs.end()) + { + ((IWFileTreeDirItem*)j->second)->updatePercentageInformation(); + j++; + } + } + + void IWFileTreeDirItem::updatePreviewInformation(kt::TorrentInterface* tc) + { + // first set all the child items + bt::PtrMap<QString,FileTreeItem>::iterator i = children.begin(); + while (i != children.end()) + { + IWFileTreeItem* item = (IWFileTreeItem*)i->second; + item->updatePreviewInformation(tc); + i++; + } + + // then recursivly move on to subdirs + bt::PtrMap<QString,FileTreeDirItem>::iterator j = subdirs.begin(); + while (j != subdirs.end()) + { + ((IWFileTreeDirItem*)j->second)->updatePreviewInformation(tc); + j++; + } + } + + Priority IWFileTreeDirItem::updatePriorityInformation(kt::TorrentInterface* tc) + { + // first set all the child items + bt::PtrMap<QString,FileTreeItem>::iterator i = children.begin(); + bool setpriority = false; + bool oneexcluded = false; + Priority priority = PREVIEW_PRIORITY; + if(i != children.end()) + { + IWFileTreeItem* item = (IWFileTreeItem*)i->second; + item->updatePriorityInformation(tc); + i++; + priority = item->getTorrentFile().getPriority(); + if(priority == EXCLUDED) + oneexcluded = true; + setpriority = true; + } + while (i != children.end()) + { + IWFileTreeItem* item = (IWFileTreeItem*)i->second; + item->updatePriorityInformation(tc); + i++; + if(item->getTorrentFile().getPriority() != priority) + setpriority = false; + if(item->getTorrentFile().getPriority() == EXCLUDED) + oneexcluded = true; + } + + // then recursivly move on to subdirs + bt::PtrMap<QString,FileTreeDirItem>::iterator j = subdirs.begin(); + if(j != subdirs.end() && children.begin() == children.end()) + { + Priority priority = + ((IWFileTreeDirItem*)j->second)->updatePriorityInformation(tc); + if(priority != PREVIEW_PRIORITY) + setpriority = true; + if(priority == EXCLUDED) + oneexcluded = true; + j++; + } + + while (j != subdirs.end()) + { + if(((IWFileTreeDirItem*)j->second)->updatePriorityInformation(tc) + != priority) + setpriority = false; + if(((IWFileTreeDirItem*)j->second)->updatePriorityInformation(tc) + == EXCLUDED) + oneexcluded = true; + j++; + } + + if(setpriority) + { + switch(priority) + { + case FIRST_PRIORITY: + setText(2, i18n("Yes, First")); + childStateChange(); + break; + case LAST_PRIORITY: + setText(2, i18n("Yes, Last")); + childStateChange(); + break; + case EXCLUDED: + setText(2, i18n("No")); + childStateChange(); + break; + default: + setText(2, i18n("Yes")); + childStateChange(); + break; + } + return priority; + } + if(oneexcluded) + { + setText(2, i18n("No")); + childStateChange(); + } + else + { + setText(2, i18n("Yes")); + childStateChange(); + } + return PREVIEW_PRIORITY; + } + + FileTreeItem* IWFileTreeDirItem::newFileTreeItem(const QString & name,TorrentFileInterface & file) + { + return new IWFileTreeItem(this,name,file); + } + + FileTreeDirItem* IWFileTreeDirItem::newFileTreeDirItem(const QString & subdir) + { + return new IWFileTreeDirItem(this,subdir); + } + + void IWFileTreeDirItem::updateDNDInformation() + { + // first set all the child items + bt::PtrMap<QString,FileTreeItem>::iterator i = children.begin(); + while (i != children.end()) + { + IWFileTreeItem* item = (IWFileTreeItem*)i->second; + item->updateDNDInformation(); + i++; + } + + // then recursivly move on to subdirs + bt::PtrMap<QString,FileTreeDirItem>::iterator j = subdirs.begin(); + while (j != subdirs.end()) + { + ((IWFileTreeDirItem*)j->second)->updateDNDInformation(); + j++; + } + } + + bt::ConfirmationResult IWFileTreeDirItem::confirmationDialog() + { + return bt::KEEP_DATA; +/* QString msg = i18n("Do you want to keep the existing data for seeding ?"); + int ret = KMessageBox::warningYesNoCancel(0,msg,QString::null, + KGuiItem(i18n("Keep the data")), + KGuiItem(i18n("Delete the data"))); + if (ret == KMessageBox::Yes) + return bt::KEEP_DATA; + else if (ret == KMessageBox::No) + return bt::THROW_AWAY_DATA; + else + return bt::CANCELED; + */ + } +} diff --git a/plugins/infowidget/iwfiletreediritem.h b/plugins/infowidget/iwfiletreediritem.h new file mode 100644 index 0000000..90aa7ea --- /dev/null +++ b/plugins/infowidget/iwfiletreediritem.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * 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 IWFILETREEDIRITEM_H +#define IWFILETREEDIRITEM_H + +#include <interfaces/filetreediritem.h> + +class IWFileTreeItem; + +using bt::Uint32; +using bt::Priority; +using bt::FIRST_PRIORITY; +using bt::NORMAL_PRIORITY; +using bt::LAST_PRIORITY; +using bt::PREVIEW_PRIORITY; +using bt::EXCLUDED; + +namespace bt +{ + class TorrentFile; + class TorrentInterface; +} + +namespace kt +{ + using namespace bt; + /** + * @author Joris Guisson + * + * Directory item in the InfoWidget's file view. + */ + class IWFileTreeDirItem : public kt::FileTreeDirItem + { + public: + IWFileTreeDirItem(KListView* klv,const QString & name); + IWFileTreeDirItem(IWFileTreeDirItem* parent,const QString & name); + virtual ~IWFileTreeDirItem(); + + /** + * Update the preview information. + * @param tc The TorrentInterface object + */ + void updatePreviewInformation(kt::TorrentInterface* tc); + + /** + * Update the downloaded percentage information. + */ + void updatePercentageInformation(); + + Priority updatePriorityInformation(kt::TorrentInterface* tc); + + /** + * Update the DND information of each file item. + */ + void updateDNDInformation(); + + virtual kt::FileTreeItem* newFileTreeItem(const QString & name, kt::TorrentFileInterface & file); + virtual kt::FileTreeDirItem* newFileTreeDirItem(const QString & subdir); + virtual bt::ConfirmationResult confirmationDialog(); + }; +} + +#endif diff --git a/plugins/infowidget/iwfiletreeitem.cpp b/plugins/infowidget/iwfiletreeitem.cpp new file mode 100644 index 0000000..e6281df --- /dev/null +++ b/plugins/infowidget/iwfiletreeitem.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** + * 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 <klocale.h> +#include <kglobal.h> +#include <kmessagebox.h> +#include <interfaces/functions.h> +#include <interfaces/torrentinterface.h> +#include <interfaces/torrentfileinterface.h> +#include <util/bitset.h> +#include "iwfiletreeitem.h" +#include "iwfiletreediritem.h" +#include "functions.h" + +using namespace kt; + +namespace kt +{ + + IWFileTreeItem::IWFileTreeItem(IWFileTreeDirItem* item,const QString & name,kt::TorrentFileInterface & file) + : FileTreeItem(item,name,file) + { + perc_complete = 0.0; + connect(&file,SIGNAL(downloadPercentageChanged( float )),this,SLOT(onPercentageUpdated( float ))); + connect(&file,SIGNAL(previewAvailable( bool )),this,SLOT(onPreviewAvailable( bool ))); + } + + IWFileTreeItem::~IWFileTreeItem() + { + } + + int IWFileTreeItem::compare(QListViewItem* i, int col, bool ascending) const + { + if (col == 4) + { + IWFileTreeItem* other = dynamic_cast<IWFileTreeItem*>(i); + if (!other) + return 0; + else + return CompareVal(perc_complete,other->perc_complete); + } + else + { + return FileTreeItem::compare(i, col, ascending); + } + } + + + void IWFileTreeItem::updatePreviewInformation(kt::TorrentInterface* tc) + { + if (file.isMultimedia()) + { + if (tc->readyForPreview(file.getFirstChunk(), file.getFirstChunk()+1) ) + { + setText(3, i18n("Available")); + } + else + { + setText(3, i18n("Pending")); + } + } + else + setText(3, i18n("No")); + } + + void IWFileTreeItem::updatePercentageInformation() + { + onPercentageUpdated(file.getDownloadPercentage()); + } + + void IWFileTreeItem::onPercentageUpdated(float p) + { + double percent = p; + if (percent < 0.0) + percent = 0.0; + else if (percent > 100.0) + percent = 100.0; + KLocale* loc = KGlobal::locale(); + setText(4,i18n("%1 %").arg(loc->formatNumber(percent,2))); + perc_complete = percent; + } + + void IWFileTreeItem::onPreviewAvailable(bool av) + { + if (av) + { + setText(3, i18n("Available")); + } + else if (file.isMultimedia()) + { + setText(3, i18n("Pending")); + } + else + { + setText(3, i18n("No")); + } + } + + void IWFileTreeItem::updatePriorityInformation(kt::TorrentInterface* tc) + { + switch(file.getPriority()) + { + case FIRST_PRIORITY: + setText(2, i18n("Yes, First")); + break; + case LAST_PRIORITY: + setText(2, i18n("Yes, Last")); + break; + case ONLY_SEED_PRIORITY: + case EXCLUDED: + setText(2, i18n("No")); + break; + case PREVIEW_PRIORITY: + break; + default: + setText(2, i18n("Yes")); + break; + } + } + + void IWFileTreeItem::updateDNDInformation() + { + if (file.doNotDownload() && isOn()) + { + setChecked(false); + setText(2, i18n("No")); + } + } + + bt::ConfirmationResult IWFileTreeItem::confirmationDialog() + { + return bt::KEEP_DATA; + /* + QString msg = i18n("Do you want to keep the existing data for seeding ?"); + int ret = KMessageBox::warningYesNoCancel(0,msg,QString::null, + KGuiItem(i18n("Keep the data")), + KGuiItem(i18n("Delete the data"))); + if (ret == KMessageBox::Yes) + return bt::KEEP_DATA; + else if (ret == KMessageBox::No) + return bt::THROW_AWAY_DATA; + else + return bt::CANCELED; + */ + } + +} + +#include "iwfiletreeitem.moc" + diff --git a/plugins/infowidget/iwfiletreeitem.h b/plugins/infowidget/iwfiletreeitem.h new file mode 100644 index 0000000..7877ff1 --- /dev/null +++ b/plugins/infowidget/iwfiletreeitem.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * 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 IWFILETREEITEM_H +#define IWFILETREEITEM_H + +#include <qobject.h> +#include <interfaces/filetreeitem.h> + +using namespace bt; + +namespace kt +{ + class TorrentFileInterface; + class TorrentInterface; + class IWFileTreeDirItem; + + /** + * @author Joris Guisson + * + * File item in the InfoWidget's file view. + */ + class IWFileTreeItem : public QObject, public kt::FileTreeItem + { + Q_OBJECT + + double perc_complete; + public: + IWFileTreeItem(IWFileTreeDirItem* item,const QString & name,kt::TorrentFileInterface & file); + virtual ~IWFileTreeItem(); + + void updatePreviewInformation(kt::TorrentInterface* tc); + void updatePercentageInformation(); + void updatePriorityInformation(kt::TorrentInterface* tc); + void updateDNDInformation(); + protected: + virtual int compare(QListViewItem* i, int col, bool ascending) const; + virtual bt::ConfirmationResult confirmationDialog(); + + protected slots: + void onPercentageUpdated(float p); + void onPreviewAvailable(bool av); + }; +} + + + +#endif diff --git a/plugins/infowidget/iwpref.ui b/plugins/infowidget/iwpref.ui new file mode 100644 index 0000000..1007259 --- /dev/null +++ b/plugins/infowidget/iwpref.ui @@ -0,0 +1,69 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>IWPref</class> +<widget class="QWidget"> + <property name="name"> + <cstring>IWPref</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>138</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>m_show_pv</cstring> + </property> + <property name="text"> + <string>Show list of peers</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>m_show_cdv</cstring> + </property> + <property name="text"> + <string>Show list of chunks currentl&y downloading</string> + </property> + </widget> + <spacer row="3" 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>21</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>m_show_tv</cstring> + </property> + <property name="text"> + <string>Show list of trackers</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/plugins/infowidget/ktinfowidgetplugin.desktop b/plugins/infowidget/ktinfowidgetplugin.desktop new file mode 100644 index 0000000..535f90c --- /dev/null +++ b/plugins/infowidget/ktinfowidgetplugin.desktop @@ -0,0 +1,29 @@ +[Desktop Entry] +Name=SearchPlugin +Name[bg]=Приставка за търсене +Name[br]=Lugent klask +Name[da]=SøgePlugin +Name[de]=Suche-Modul +Name[el]=Πρόσθετο αναζήτησης +Name[es]=Complemento de búsqueda +Name[et]=Otsimisplugin +Name[fa]=وصلۀ جستجو +Name[it]=Plugin di ricerca +Name[nb]=Søkemodul +Name[nds]=Söök-Moduul +Name[nl]=Zoekplugin +Name[pl]=Wtyczka wyszukiwania +Name[pt]='Plugin' de Procura +Name[pt_BR]=Plugin de Busca +Name[sk]=Vyhľadávací Plugin +Name[sr]=Прикључак претраге +Name[sr@Latn]=Priključak pretrage +Name[sv]=Sökinsticksprogram +Name[tr]=Arama Eklentisi +Name[uk]=Втулок пошуку +Name[xx]=xxSearchPluginxx +Name[zh_CN]=搜索插件 +Name[zh_TW]=搜尋外掛程式 +ServiceTypes=KTorrent/Plugin +Type=Service +X-KDE-Library=ktinfowidgetplugin diff --git a/plugins/infowidget/ktinfowidgetplugin.kcfg b/plugins/infowidget/ktinfowidgetplugin.kcfg new file mode 100644 index 0000000..51048fa --- /dev/null +++ b/plugins/infowidget/ktinfowidgetplugin.kcfg @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 + http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" > + + <kcfgfile name="ktinfowidgetpluginrc"/> + <group name="general"> + <entry name="showPeerView" type="Bool"> + <label>Show peer view tab in main window</label> + <default>true</default> + </entry> + <entry name="showChunkView" type="Bool"> + <label>Show chunk download view tab in main window</label> + <default>true</default> + </entry> + <entry name="showTrackersView" type="Bool"> + <label>Show trackers view tab in main window</label> + <default>true</default> + </entry> + </group> +</kcfg> diff --git a/plugins/infowidget/ktorrentmonitor.cpp b/plugins/infowidget/ktorrentmonitor.cpp new file mode 100644 index 0000000..7494a5c --- /dev/null +++ b/plugins/infowidget/ktorrentmonitor.cpp @@ -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. * + ***************************************************************************/ +#include <interfaces/peerinterface.h> +#include <interfaces/torrentinterface.h> +#include <interfaces/chunkdownloadinterface.h> +#include "ktorrentmonitor.h" +#include "peerview.h" +#include "chunkdownloadview.h" + +using namespace bt; + +namespace kt +{ + + KTorrentMonitor::KTorrentMonitor(kt::TorrentInterface* tc, + PeerView* pv, + ChunkDownloadView* cdv) : tc(tc),pv(pv),cdv(cdv) + { + if (tc) + tc->setMonitor(this); + } + + + KTorrentMonitor::~KTorrentMonitor() + { + if (tc) + tc->setMonitor(0); + } + + + void KTorrentMonitor::downloadRemoved(kt::ChunkDownloadInterface* cd) + { + if (cdv) + cdv->removeDownload(cd); + } + + void KTorrentMonitor::downloadStarted(kt::ChunkDownloadInterface* cd) + { + if (cdv) + cdv->addDownload(cd); + } + + void KTorrentMonitor::peerAdded(kt::PeerInterface* peer) + { + if (pv) + pv->addPeer(peer); + } + + void KTorrentMonitor::peerRemoved(kt::PeerInterface* peer) + { + if (pv) + pv->removePeer(peer); + } + + void KTorrentMonitor::stopped() + { + if (pv) + pv->removeAll(); + if (cdv) + cdv->removeAll(); + } + + void KTorrentMonitor::destroyed() + { + if (pv) + pv->removeAll(); + if (cdv) + cdv->removeAll(); + tc = 0; + } +} diff --git a/plugins/infowidget/ktorrentmonitor.h b/plugins/infowidget/ktorrentmonitor.h new file mode 100644 index 0000000..6a312a2 --- /dev/null +++ b/plugins/infowidget/ktorrentmonitor.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 KTORRENTMONITOR_H +#define KTORRENTMONITOR_H + +#include <interfaces/monitorinterface.h> + + + +namespace kt +{ + class TorrentInterface; + class PeerView; + class ChunkDownloadView; + + /** + @author Joris Guisson + */ + class KTorrentMonitor : public kt::MonitorInterface + { + kt::TorrentInterface* tc; + PeerView* pv; + ChunkDownloadView* cdv; + public: + KTorrentMonitor( + kt::TorrentInterface* tc, + PeerView* pv, + ChunkDownloadView* cdv); + virtual ~KTorrentMonitor(); + + virtual void downloadRemoved(kt::ChunkDownloadInterface* cd); + virtual void downloadStarted(kt::ChunkDownloadInterface* cd); + virtual void peerAdded(kt::PeerInterface* peer); + virtual void peerRemoved(kt::PeerInterface* peer); + virtual void stopped(); + virtual void destroyed(); + + }; +} + +#endif diff --git a/plugins/infowidget/localefloatvalidator.cpp b/plugins/infowidget/localefloatvalidator.cpp new file mode 100644 index 0000000..7faafed --- /dev/null +++ b/plugins/infowidget/localefloatvalidator.cpp @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2006 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * Jonas Widarsson <jonas@widarsson.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 <kglobal.h> +#include <klocale.h> +#include "localefloatvalidator.h" + +kt::LocaleFloatValidator::LocaleFloatValidator( QObject * parent, const char * name ) +:QValidator(parent, name) +{ + QString decimalPoint = QRegExp::escape(KGlobal::locale()->decimalSymbol()); + regexp.setPattern("^-?\\d*(" + decimalPoint + "\\d*)?$"); +} + +QValidator::State kt::LocaleFloatValidator::validate( QString & str, int & pos) const +{ + return regexp.exactMatch(str) ? QValidator::Acceptable : QValidator::Invalid; +} + + +#include "localefloatvalidator.moc" diff --git a/plugins/infowidget/localefloatvalidator.h b/plugins/infowidget/localefloatvalidator.h new file mode 100644 index 0000000..d4d12ee --- /dev/null +++ b/plugins/infowidget/localefloatvalidator.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 by * + * Joris Guisson <joris.guisson@gmail.com> * + * Vincent Wagelaar <vincent@ricardis.tudelft.nl> * + * Jonas Widarsson <jonas@widarsson.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 LOCALEFLOATVALIDATOR_H +#define LOCALEFLOATVALIDATOR_H + +#include <qvalidator.h> +class QRegExp; +namespace kt{ + /** + * @author Jonas Widarsson + * + * A float validator that respects KLocale::decimalSymbol() + */ + class LocaleFloatValidator : public QValidator + { + Q_OBJECT + public: + LocaleFloatValidator( QObject * parent, const char *name = 0 ); + + virtual QValidator::State validate( QString & str, int & pos) const; + private: + QRegExp regexp; + }; +} + +#endif diff --git a/plugins/infowidget/peerview.cpp b/plugins/infowidget/peerview.cpp new file mode 100644 index 0000000..0e05791 --- /dev/null +++ b/plugins/infowidget/peerview.cpp @@ -0,0 +1,357 @@ +/*************************************************************************** + * Copyright (C) 2005 by Joris Guisson <joris.guisson@gmail.com> * + * Copyright (C) 2007 by Modestas Vainius <modestas@vainius.eu> * + * * + * 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 <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <ksocketaddress.h> +#include <qpoint.h> +#include <qlistview.h> +#include <kpopupmenu.h> +#include <interfaces/peerinterface.h> +#include <interfaces/functions.h> +#include <torrent/ipblocklist.h> +#include <util/log.h> +#include "config.h" + +#ifdef USE_SYSTEM_GEOIP +#include <GeoIP.h> +#else +#include "GeoIP.h" +#endif +#include "peerview.h" +#include "flagdb.h" + +using namespace bt; +using namespace kt; + +namespace kt +{ + + Uint32 PeerViewItem::pvi_count = 0; + // Global GeoIP pointer, gets destroyed when no PeerViewItem's exist + static GeoIP* geo_ip = 0; + static QPixmap yes_pix; + static QPixmap no_pix; + static QPixmap lock_pix; + static FlagDB flagDB(22, 18); + static bool yes_no_pix_loaded = false; + static bool geoip_db_exists = true; + static QString geoip_data_file; + + PeerViewItem::PeerViewItem(PeerView* pv,kt::PeerInterface* peer) : KListViewItem(pv),peer(peer) + { + if (!yes_no_pix_loaded) + { + KIconLoader* iload = KGlobal::iconLoader(); + /* Prefer builtin flag images to the ones provided by KDE */ + flagDB.addFlagSource("data", QString("ktorrent/geoip/%1.png")); + flagDB.addFlagSource("locale", QString("l10n/%1/flag.png")); + yes_pix = iload->loadIcon("button_ok",KIcon::Small); + no_pix = iload->loadIcon("button_cancel",KIcon::Small); + lock_pix = iload->loadIcon("ktencrypted",KIcon::Small); +#ifdef USE_SYSTEM_GEOIP + geo_ip = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); + geoip_db_exists = (geo_ip != NULL); +#else + geoip_db_exists = !locate("data", "ktorrent/geoip/geoip.dat").isNull(); + if(geoip_db_exists) { + geoip_data_file = "ktorrent/geoip/geoip.dat"; + } else { + geoip_db_exists = !locate("data", "ktorrent/geoip/GeoIP.dat").isNull(); + if (geoip_db_exists) + geoip_data_file = "ktorrent/geoip/GeoIP.dat"; + } +#endif + yes_no_pix_loaded = true; + } + + pvi_count++; + const char * hostname = 0; + const char * country_code = 0; + const char * country_name = 0; + int country_id = 0; + + const PeerInterface::Stats & s = peer->getStats(); + hostname = s.ip_address.ascii(); + + // open GeoIP if necessary + if (!geo_ip && geoip_db_exists) { +#ifdef USE_SYSTEM_GEOIP + geo_ip = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); +#else + geo_ip = GeoIP_open(locate("data", geoip_data_file).ascii(),0); +#endif + } + if (geo_ip) + { + country_id = GeoIP_id_by_name(geo_ip, hostname); + country_code = GeoIP_country_code[country_id]; + country_name = GeoIP_country_name[country_id]; + setText(1, country_name); + m_country = QString(country_name); + } + else + { + setText(1,"N/A"); + } + + /* if (s.fast_extensions) + setText(0,s.ip_address + " (F)"); + else*/ + setText(0,s.ip_address); + + struct in_addr addr = {0}; + inet_aton(s.ip_address.ascii(),&addr); + ip = ntohl(addr.s_addr); + + setText(2,s.client); + + if (country_code) + { + setPixmap(1, flagDB.getFlag(country_code)); + } + + if (s.encrypted) + setPixmap(0,lock_pix); + update(); + } + + PeerViewItem::~PeerViewItem() + { + if (pvi_count > 0) // just to be sure, let this not wrap around + pvi_count--; + + // destroy when not needed anymore + if (pvi_count == 0 && geo_ip) + { + GeoIP_delete(geo_ip); + geo_ip = 0; + } + } + + + void PeerViewItem::update() + { + KLocale* loc = KGlobal::locale(); + const PeerInterface::Stats & s = peer->getStats(); + + if (s.download_rate >= 103) // lowest "visible" speed, all below will be 0,0 Kb/s + setText(3,KBytesPerSecToString(s.download_rate / 1024.0)); + else + setText(3, ""); + if (s.upload_rate >= 103) // lowest "visible" speed, all below will be 0,0 Kb/s + setText(4,KBytesPerSecToString(s.upload_rate / 1024.0)); + else + setText(4, ""); + //setPixmap(5,!s.choked ? yes_pix : no_pix); + setText(5,s.choked ? i18n("Yes") : i18n("No")); + //setPixmap(6,!s.snubbed ? yes_pix : no_pix); + setText(6,s.snubbed ? i18n("Yes") : i18n("No")); + setText(7,QString("%1 %").arg(loc->formatNumber(s.perc_of_file,2))); + setPixmap(8,s.dht_support ? yes_pix : no_pix); + setText(9,loc->formatNumber(s.aca_score,2)); + setPixmap(10,s.has_upload_slot ? yes_pix : QPixmap()); + setText(11,QString("%1 / %2").arg(s.num_down_requests).arg(s.num_up_requests)); + setText(12, BytesToString(s.bytes_downloaded)); + setText(13, BytesToString(s.bytes_uploaded)); + } + + int PeerViewItem::compare(QListViewItem * i,int col,bool) const + { + PeerViewItem* pvi = (PeerViewItem*) i; + PeerInterface* op = pvi->peer; + const PeerInterface::Stats & s = peer->getStats(); + const PeerInterface::Stats & os = op->getStats(); + switch (col) + { + case 0: return CompareVal(ip,pvi->ip); // use numeric representation to sort + //return QString::compare(s.ip_address,os.ip_address); + case 1: return QString::compare(m_country, pvi->m_country); + case 2: return QString::compare(s.client,os.client); + case 3: return CompareVal(s.download_rate,os.download_rate); + case 4: return CompareVal(s.upload_rate,os.upload_rate); + case 5: return CompareVal(s.choked,os.choked); + case 6: return CompareVal(s.snubbed,os.snubbed); + case 7: return CompareVal(s.perc_of_file,os.perc_of_file); + case 8: return CompareVal(s.dht_support,os.dht_support); + case 9: return CompareVal(s.aca_score,os.aca_score); + case 10: return CompareVal(s.has_upload_slot,os.has_upload_slot); + case 11: return CompareVal(s.num_down_requests+s.num_up_requests, os.num_down_requests+os.num_up_requests); + case 12: return CompareVal(s.bytes_downloaded, os.bytes_downloaded); + case 13: return CompareVal(s.bytes_uploaded, os.bytes_uploaded); + + } + return 0; + } + + PeerView::PeerView(QWidget *parent, const char *name) + : KListView(parent, name) + { + addColumn(i18n("IP")); + addColumn(i18n("Country")); + addColumn(i18n("Client")); + addColumn(i18n("Down Speed")); + addColumn(i18n("Up Speed")); + addColumn(i18n("Choked")); + addColumn(i18n("Snubbed")); + addColumn(i18n("Availability")); + addColumn(i18n("DHT")); + addColumn(i18n("Score")); + addColumn(i18n("Upload Slot")); + addColumn(i18n("Requests")); + addColumn(i18n("Downloaded")); + addColumn(i18n("Uploaded")); + + setAllColumnsShowFocus(true); + setShowSortIndicator(true); + + setColumnAlignment(3,Qt::AlignRight); + setColumnAlignment(4,Qt::AlignRight); + setColumnAlignment(5,Qt::AlignCenter); + setColumnAlignment(6,Qt::AlignCenter); + setColumnAlignment(7,Qt::AlignRight); + setColumnAlignment(8,Qt::AlignCenter); + setColumnAlignment(9,Qt::AlignRight); + setColumnAlignment(10,Qt::AlignCenter); + setColumnAlignment(11,Qt::AlignCenter); + setColumnAlignment(12,Qt::AlignRight); + setColumnAlignment(13,Qt::AlignRight); + + for (Uint32 i = 0;i < (Uint32)columns();i++) + setColumnWidthMode(i,QListView::Manual); + + setShowSortIndicator(true); + + menu = new KPopupMenu(this); + kick_id = menu->insertItem(KGlobal::iconLoader()->loadIcon("delete_user", KIcon::NoGroup), i18n("to kick", "Kick peer")); + ban_id = menu->insertItem(KGlobal::iconLoader()->loadIcon("filter",KIcon::NoGroup), i18n("to ban", "Ban peer")); + + connect(this,SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint& )), + this,SLOT(showContextMenu(KListView*, QListViewItem*, const QPoint& ))); + connect(menu, SIGNAL ( activated ( int ) ), this, SLOT ( contextItem ( int ) ) ); + setFrameShape(QFrame::NoFrame); + } + + + PeerView::~PeerView() + {} + + void PeerView::addPeer(kt::PeerInterface* peer) + { + PeerViewItem* i = new PeerViewItem(this,peer); + items.insert(peer,i); + } + + void PeerView::removePeer(kt::PeerInterface* peer) + { + QMap<kt::PeerInterface*,PeerViewItem*>::iterator it = items.find(peer); + if (it == items.end()) + { + return; + } + + PeerViewItem* pvi = it.data(); + if (pvi == curr) + curr = 0; + + delete pvi; + items.erase(peer); + + } + + void PeerView::banPeer(kt::PeerInterface* peer) + { + if(!peer) + return; + + IPBlocklist& filter = IPBlocklist::instance(); + const PeerInterface::Stats & s = peer->getStats(); + KNetwork::KIpAddress ip(s.ip_address); + QString ips = ip.toString(); + /** + * @TODO Clean this up. + * this whole mess was because of KNetwork classes + * since we no longer use them, may I clean it up? + * I'll wait some time just in case... + **/ + if(ips.startsWith(":")) + filter.insert(ips.section(":",-1),3); + else + filter.insert(ips,3); + peer->kill(); + } + + void PeerView::kickPeer(kt::PeerInterface* peer) + { + if(!peer) + return; + + peer->kill(); + } + + void PeerView::update() + { + QMap<kt::PeerInterface*,PeerViewItem*>::iterator i = items.begin(); + while (i != items.end()) + { + PeerViewItem* it = i.data(); + it->update(); + i++; + } + sort(); + } + + void PeerView::removeAll() + { + items.clear(); + clear(); + } + + void PeerView::showContextMenu( KListView*, QListViewItem* item, const QPoint& p) + { + if(!item) + return; + + curr = dynamic_cast<PeerViewItem*>(item); + if (curr) + { + menu->setItemEnabled(ban_id, true); + menu->setItemEnabled(kick_id, true); + menu->popup(p); + } + } + + void PeerView::contextItem(int id) + { + if (id == ban_id && curr) + banPeer(curr->getPeer()); + + if (id == kick_id && curr) + kickPeer(curr->getPeer()); + } +} + +#include "peerview.moc" diff --git a/plugins/infowidget/peerview.h b/plugins/infowidget/peerview.h new file mode 100644 index 0000000..a4a8b94 --- /dev/null +++ b/plugins/infowidget/peerview.h @@ -0,0 +1,81 @@ +/*************************************************************************** + * 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 PEERVIEW_H +#define PEERVIEW_H + +#include <qmap.h> +#include <klistview.h> +#include <qlistview.h> +#include <kpopupmenu.h> +#include <qpoint.h> +#include <util/constants.h> + +namespace kt +{ + class PeerInterface; + class PeerView; + + class PeerViewItem : public KListViewItem + { + kt::PeerInterface* peer; + QString m_country; + bt::Uint32 ip; + // counter to keep track of how many PeerViewItem objects are in existence + static bt::Uint32 pvi_count; + public: + PeerViewItem(PeerView* pv,kt::PeerInterface* peer); + virtual ~PeerViewItem(); + + void update(); + int compare(QListViewItem * i,int col,bool) const; + kt::PeerInterface* getPeer() { return peer; } + + }; + + /** + @author Joris Guisson + */ + class PeerView : public KListView + { + Q_OBJECT + + QMap<kt::PeerInterface*,PeerViewItem*> items; + public: + PeerView(QWidget *parent = 0, const char *name = 0); + virtual ~PeerView(); + + public slots: + void addPeer(kt::PeerInterface* peer); + void removePeer(kt::PeerInterface* peer); + void banPeer(kt::PeerInterface* peer); + void kickPeer(kt::PeerInterface* peer); + void update(); + void removeAll(); + void showContextMenu(KListView* ,QListViewItem* item,const QPoint & p); + void contextItem(int id); + private: + KPopupMenu* menu; + int ban_id; + int kick_id; + PeerViewItem* curr; + }; +} + +#endif diff --git a/plugins/infowidget/statustab.cpp b/plugins/infowidget/statustab.cpp new file mode 100644 index 0000000..b0974ed --- /dev/null +++ b/plugins/infowidget/statustab.cpp @@ -0,0 +1,267 @@ +/*************************************************************************** + * 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 <math.h> +#include <float.h> +#include <qdatetime.h> +#include <qcheckbox.h> +#include <kglobal.h> +#include <klocale.h> +#include <interfaces/functions.h> +#include <interfaces/torrentinterface.h> + +#include "downloadedchunkbar.h" +#include "availabilitychunkbar.h" +#include "floatspinbox.h" +#include "statustab.h" + +namespace kt +{ + + StatusTab::StatusTab(QWidget* parent, const char* name, WFlags fl) + : StatusTabBase(parent,name,fl),curr_tc(0) + { + QColorGroup cg = colorGroup(); + // do not use hardcoded colors + m_info_caption->setPaletteBackgroundColor(cg.mid()); + m_chunks_caption->setPaletteBackgroundColor(cg.mid()); + m_sharing_caption->setPaletteBackgroundColor(cg.mid()); + + maxRatio->setMinValue(0.0f); + maxRatio->setMaxValue(100.0f); + maxRatio->setStep(0.1f); + connect(maxRatio, SIGNAL(valueHasChanged()), this, SLOT(maxRatioReturnPressed())); + connect(useLimit, SIGNAL( toggled(bool) ), this, SLOT( useLimitToggled(bool) ) ); + + maxTime->setMinValue(0.0f); + maxTime->setMaxValue(10000000.0f); + maxTime->setStep(0.05f); + maxTime->setSpecialValueText(i18n("No limit")); + connect(useTimeLimit,SIGNAL(toggled(bool)), this,SLOT(useTimeLimitToggled(bool))); + connect(maxTime,SIGNAL(valueHasChanged()), this, SLOT(timeValueChanged())); + + int h = (int)ceil(fontMetrics().height()*1.25); + m_chunk_bar->setFixedHeight(h); + m_av_chunk_bar->setFixedHeight(h); + } + + StatusTab::~StatusTab() + {} + + void StatusTab::changeTC(kt::TorrentInterface* tc) + { + if (tc == curr_tc) + return; + + curr_tc = tc; + + m_chunk_bar->setTC(tc); + m_av_chunk_bar->setTC(tc); + setEnabled(tc != 0); + + if (curr_tc) + { + float ratio = curr_tc->getMaxShareRatio(); + if(ratio > 0) + { + useLimit->setChecked(true); + maxRatio->setValue(ratio); + } + else + { + maxRatio->setValue(0.0); + useLimit->setChecked(false); + maxRatio->setEnabled(false); + } + + float hours = curr_tc->getMaxSeedTime(); + if (hours > 0) + { + maxTime->setEnabled(true); + useTimeLimit->setChecked(true); + maxTime->setValue(hours); + } + else + { + maxTime->setEnabled(false); + useTimeLimit->setChecked(false); + } + } + else + { + maxRatio->setValue(0.00f); + m_share_ratio->clear(); + m_tracker_status->clear(); + m_seeders->clear(); + m_leechers->clear(); + m_tracker_update_time->clear(); + m_avg_up->clear(); + m_avg_down->clear(); + } + + update(); + } + + void StatusTab::update() + { + if (!curr_tc) + return; + + const TorrentStats & s = curr_tc->getStats(); + + m_chunk_bar->updateBar(); + m_av_chunk_bar->updateBar(); + + if (s.running) + { + QTime t; + t = t.addSecs(curr_tc->getTimeToNextTrackerUpdate()); + m_tracker_update_time->setText(t.toString("mm:ss")); + } + else + { + m_tracker_update_time->setText(""); + } + + m_tracker_status->setText(s.trackerstatus); + + m_seeders->setText(QString("%1 (%2)") + .arg(s.seeders_connected_to).arg(s.seeders_total)); + + m_leechers->setText(QString("%1 (%2)") + .arg(s.leechers_connected_to).arg(s.leechers_total)); + + float ratio = kt::ShareRatio(s); + if(!maxRatio->hasFocus() && useLimit->isChecked()) + maxRatioUpdate(); + + m_share_ratio->setText(QString("<font color=\"%1\">%2</font>").arg(ratio <= 0.8 ? "#ff0000" : "#1c9a1c").arg(KGlobal::locale()->formatNumber(ratio,2))); + + Uint32 secs = curr_tc->getRunningTimeUL(); + if (secs == 0) + { + m_avg_up->setText(KBytesPerSecToString(0)); + + } + else + { + double r = (double)s.bytes_uploaded / 1024.0; + m_avg_up->setText(KBytesPerSecToString(r / secs)); + } + + secs = curr_tc->getRunningTimeDL(); + if (secs == 0) + { + m_avg_down->setText(KBytesPerSecToString(0)); + } + else + { + double r = (double)(s.bytes_downloaded - s.imported_bytes)/ 1024.0; + m_avg_down->setText(KBytesPerSecToString(r / secs)); + } + } + + void StatusTab::maxRatioReturnPressed() + { + if(!curr_tc) + return; + + curr_tc->setMaxShareRatio(maxRatio->value()); + } + + void StatusTab::useLimitToggled(bool state) + { + if(!curr_tc) + return; + + maxRatio->setEnabled(state); + if (!state) + { + curr_tc->setMaxShareRatio(0.00f); + maxRatio->setValue(0.00f); + } + else + { + float msr = curr_tc->getMaxShareRatio(); + if(msr == 0.00f) + { + curr_tc->setMaxShareRatio(1.00f); + maxRatio->setValue(1.00f); + } + + float sr = kt::ShareRatio(curr_tc->getStats()); + if(sr >= 1.00f) + { + //always add 1 to max share ratio to prevent stopping if torrent is running. + curr_tc->setMaxShareRatio(sr + 1.00f); + maxRatio->setValue(sr + 1.00f); + } + } + } + + void StatusTab::maxRatioUpdate() + { + if(!curr_tc) + return; + + float ratio = curr_tc->getMaxShareRatio(); + if(ratio > 0.00f) + { + maxRatio->setEnabled(true); + useLimit->setChecked(true); + maxRatio->setValue(ratio); + } + else + { + maxRatio->setEnabled(false); + useLimit->setChecked(false); + maxRatio->setValue(0.00f); + } + } + + void StatusTab::useTimeLimitToggled(bool on) + { + if(!curr_tc) + return; + + maxTime->setEnabled(on); + if (on) + { + Uint32 dl = curr_tc->getRunningTimeDL(); + Uint32 ul = curr_tc->getRunningTimeUL(); + float hours = (ul - dl) / 3600.0f + 1.0; // add one hour to current seed time to not stop immediatly + maxTime->setValue(hours); + curr_tc->setMaxSeedTime(hours); + } + else + { + curr_tc->setMaxSeedTime(0.0f); + } + } + + void StatusTab::timeValueChanged() + { + if (curr_tc) + curr_tc->setMaxSeedTime(maxTime->value()); + } + +} + +#include "statustab.moc" + diff --git a/plugins/infowidget/statustab.h b/plugins/infowidget/statustab.h new file mode 100644 index 0000000..14e987d --- /dev/null +++ b/plugins/infowidget/statustab.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * 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 STATUSTAB_H +#define STATUSTAB_H + +#include "statustabbase.h" + +namespace kt +{ + class TorrentInterface; + + class StatusTab : public StatusTabBase + { + Q_OBJECT + + public: + StatusTab(QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + virtual ~StatusTab(); + + + public slots: + void changeTC(kt::TorrentInterface* tc); + void update(); + void maxRatioReturnPressed(); + void useLimitToggled(bool on); + void useTimeLimitToggled(bool on); + void timeValueChanged(); + private: + void maxRatioUpdate(); + + private: + kt::TorrentInterface* curr_tc; + }; +} + +#endif + diff --git a/plugins/infowidget/statustabbase.ui b/plugins/infowidget/statustabbase.ui new file mode 100644 index 0000000..179f68a --- /dev/null +++ b/plugins/infowidget/statustabbase.ui @@ -0,0 +1,667 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>StatusTabBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>StatusTabBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>839</width> + <height>250</height> + </rect> + </property> + <property name="caption"> + <string>Status</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_info_caption</cstring> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>200</red> + <green>200</green> + <blue>200</blue> + </color> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>Info</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Seeders:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_6</cstring> + </property> + <property name="text"> + <string>Leechers:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>m_seeders</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>m_leechers</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>Average Down Speed:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>m_avg_down</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>m_avg_up</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_7</cstring> + </property> + <property name="text"> + <string>Average Up Speed:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel3_2</cstring> + </property> + <property name="text"> + <string>Next update in:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_5</cstring> + </property> + <property name="text"> + <string>Tracker Status:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>m_tracker_status</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>m_tracker_update_time</cstring> + </property> + <property name="minimumSize"> + <size> + <width>100</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</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> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout17</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout25</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_chunks_caption</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>200</red> + <green>200</green> + <blue>200</blue> + </color> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>Chunks</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Parts of the torrent which have been downloaded:</string> + </property> + </widget> + <widget class="kt::DownloadedChunkBar"> + <property name="name"> + <cstring>m_chunk_bar</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Parts of the torrent which are available:</string> + </property> + </widget> + <widget class="kt::AvailabilityChunkBar"> + <property name="name"> + <cstring>m_av_chunk_bar</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>20</height> + </size> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer11</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> + </vbox> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>VLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>m_sharing_caption</cstring> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>200</red> + <green>200</green> + <blue>200</blue> + </color> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>Sharing</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="kt::FloatSpinBox" row="1" column="1"> + <property name="name"> + <cstring>maxRatio</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Your upload will stop when share ratio gets to this value. Zero means no limit.</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel3_3</cstring> + </property> + <property name="text"> + <string>Share ratio:</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="kt::FloatSpinBox"> + <property name="name"> + <cstring>maxTime</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>20</width> + <height>0</height> + </size> + </property> + <property name="toolTip" stdset="0"> + <string>Your upload will stop when you have uploaded for this many hours.</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_9</cstring> + </property> + <property name="text"> + <string>Hours</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>useLimit</cstring> + </property> + <property name="text"> + <string>Ratio limit:</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Limit works only in seed mode</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>useTimeLimit</cstring> + </property> + <property name="text"> + <string>Time &limit:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>m_share_ratio</cstring> + </property> + <property name="minimumSize"> + <size> + <width>50</width> + <height>0</height> + </size> + </property> + <property name="frameShape"> + <enum>Panel</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>kt::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> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>kt::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> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>kt::FloatSpinBox</class> + <header location="local">floatspinbox.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>downloadedchunkbar.h</includehint> + <includehint>availabilitychunkbar.h</includehint> + <includehint>floatspinbox.h</includehint> + <includehint>floatspinbox.h</includehint> +</includehints> +</UI> diff --git a/plugins/infowidget/trackerview.cpp b/plugins/infowidget/trackerview.cpp new file mode 100644 index 0000000..2339189 --- /dev/null +++ b/plugins/infowidget/trackerview.cpp @@ -0,0 +1,243 @@ +/*************************************************************************** + * 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 "trackerview.h" +#include <interfaces/torrentinterface.h> +#include <interfaces/trackerslist.h> + +#include <qdatetime.h> +#include <qstring.h> +#include <qlabel.h> +#include <qlistview.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qtooltip.h> + +#include <klocale.h> +#include <kurl.h> +#include <kmessagebox.h> +#include <kpushbutton.h> +#include <ksqueezedtextlabel.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <klistview.h> + +#include <torrent/globals.h> +#include <util/log.h> + +namespace kt +{ + TrackerView::TrackerView(QWidget *parent, const char *name) + :TrackerViewBase(parent, name), tc(0) + { + KIconLoader* iload = KGlobal::iconLoader(); + btnUpdate->setIconSet(iload->loadIconSet("apply", KIcon::Small)); + btnAdd->setIconSet(iload->loadIconSet("add", KIcon::Small)); + btnRemove->setIconSet(iload->loadIconSet("remove", KIcon::Small)); + btnRestore->setIconSet(iload->loadIconSet("undo", KIcon::Small)); + + QPalette p = lblCurrent->palette(); + p.setColor(QPalette::Active,QColorGroup::Base,p.color(QPalette::Active,QColorGroup::Background)); + lblCurrent->setPalette(p); + } + + TrackerView::~TrackerView() + { + } + + void TrackerView::btnAdd_clicked() + { + if(!tc || txtTracker->text().isEmpty()) + return; + + if(tc->getStats().priv_torrent) + { + KMessageBox::sorry(0, i18n("Cannot add a tracker to a private torrent.")); + return; + } + + KURL url(txtTracker->text()); + if(!url.isValid()) + { + KMessageBox::error(0, i18n("Malformed URL.")); + return; + } + + new QListViewItem(listTrackers, txtTracker->text()); + tc->getTrackersList()->addTracker(url,true); + } + + void TrackerView::btnRemove_clicked() + { + QListViewItem* current = listTrackers->currentItem(); + if(!current) + return; + + KURL url(current->text(0)); + if(tc->getTrackersList()->removeTracker(url)) + delete current; + else + KMessageBox::sorry(0, i18n("Cannot remove torrent default tracker.")); + } + + void TrackerView::btnChange_clicked() + { + QListViewItem* current = listTrackers->currentItem(); + if(!current) + return; + + KURL url(current->text(0)); + tc->getTrackersList()->setTracker(url); + tc->updateTracker(); + } + + void TrackerView::btnRestore_clicked() + { + tc->getTrackersList()->restoreDefault(); + tc->updateTracker(); + + // update the list of trackers + listTrackers->clear(); + + const KURL::List trackers = tc->getTrackersList()->getTrackerURLs(); + if(trackers.empty()) + return; + + for (KURL::List::const_iterator i = trackers.begin();i != trackers.end();i++) + new QListViewItem(listTrackers, (*i).prettyURL()); + } + + void TrackerView::btnUpdate_clicked() + { + if(!tc) + return; + + tc->updateTracker(); + } + + void TrackerView::listTrackers_currentChanged(QListViewItem* item) + { + if(!item) + txtTracker->clear(); + else + txtTracker->setText(item->text(0)); + } + + void TrackerView::changeTC(TorrentInterface* ti) + { + if (tc == ti) + return; + + setEnabled(ti != 0); + torrentChanged(ti); + update(); + } + + void TrackerView::update() + { + if(!tc) + return; + + const TorrentStats & s = tc->getStats(); + if (s.running) + { + QTime t; + t = t.addSecs(tc->getTimeToNextTrackerUpdate()); + lblUpdate->setText(t.toString("mm:ss")); + } + + //Update manual annunce button + btnUpdate->setEnabled(s.running && tc->announceAllowed()); + // only enable change when we can actually change and the torrent is running + btnChange->setEnabled(s.running && listTrackers->childCount() > 1); + + lblStatus->setText("<b>" + s.trackerstatus + "</b>"); + if (tc->getTrackersList()) + { + QString t = tc->getTrackersList()->getTrackerURL().prettyURL(); + if (lblCurrent->text() != t ) + lblCurrent->setText(t); + } + else + lblCurrent->clear(); + + btnAdd->setEnabled(txtTracker->text() != QString::null && !tc->getStats().priv_torrent); + } + + void TrackerView::onLoadingFinished(const KURL & ,bool,bool) + { + torrentChanged(tc); + } + + void TrackerView::torrentChanged(TorrentInterface* ti) + { + tc = ti; + listTrackers->clear(); + if(!tc) + { + lblStatus->clear(); + lblCurrent->clear(); + lblUpdate->clear(); + txtTracker->clear(); + + btnAdd->setEnabled(false); + btnRemove->setEnabled(false); + btnRestore->setEnabled(false); + btnChange->setEnabled(false); + btnRestore->setEnabled(false); + return; + } + + const TorrentStats & s = tc->getStats(); + + if (s.priv_torrent) + { + btnAdd->setEnabled(false); + btnRemove->setEnabled(false); + btnRestore->setEnabled(false); + txtTracker->setText(i18n("You cannot add trackers to a private torrent")); + txtTracker->setEnabled(false); + } + else + { + btnAdd->setEnabled(true); + btnRemove->setEnabled(true); + btnRestore->setEnabled(true); + txtTracker->clear(); + txtTracker->setEnabled(true); + } + + const KURL::List trackers = tc->getTrackersList()->getTrackerURLs(); + if(trackers.empty()) + { + new QListViewItem(listTrackers, tc->getTrackersList()->getTrackerURL().prettyURL()); + } + else + { + for (KURL::List::const_iterator i = trackers.begin();i != trackers.end();i++) + new QListViewItem(listTrackers, (*i).prettyURL()); + } + + btnUpdate->setEnabled(s.running && tc->announceAllowed()); + btnChange->setEnabled(s.running && listTrackers->childCount() > 1); + } +} + + +#include "trackerview.moc" diff --git a/plugins/infowidget/trackerview.h b/plugins/infowidget/trackerview.h new file mode 100644 index 0000000..fd23fb8 --- /dev/null +++ b/plugins/infowidget/trackerview.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2006 by Joris Guisson, Ivan Vasic * + * 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 TRACKERVIEW_H +#define TRACKERVIEW_H + +#include <kurl.h> +#include "trackerviewbase.h" + +namespace kt +{ + class TorrentInterface; + class TorrentFileInterface; + + /** + * @author Ivan Vasic <ivan@ktorrent.org> + */ + class TrackerView: public TrackerViewBase + { + Q_OBJECT + public: + TrackerView(QWidget *parent = 0, const char *name = 0); + virtual ~TrackerView(); + + void update(); + void changeTC(TorrentInterface* ti); + + public slots: + virtual void btnUpdate_clicked(); + virtual void btnRestore_clicked(); + virtual void btnChange_clicked(); + virtual void btnRemove_clicked(); + virtual void btnAdd_clicked(); + virtual void listTrackers_currentChanged(QListViewItem*); + void onLoadingFinished(const KURL & ,bool,bool); + + private: + void torrentChanged(TorrentInterface* ti); + + private: + TorrentInterface* tc; + + }; +} +#endif diff --git a/plugins/infowidget/trackerviewbase.ui b/plugins/infowidget/trackerviewbase.ui new file mode 100644 index 0000000..758ddc7 --- /dev/null +++ b/plugins/infowidget/trackerviewbase.ui @@ -0,0 +1,317 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>TrackerViewBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>TrackerViewBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>750</width> + <height>254</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="1" column="0"> + <property name="name"> + <cstring>txtTracker</cstring> + </property> + </widget> + <widget class="KPushButton" row="0" column="1"> + <property name="name"> + <cstring>btnUpdate</cstring> + </property> + <property name="text"> + <string>&Update Tracker</string> + </property> + <property name="toolTip" stdset="0"> + <string>Minimum update interval - 60 seconds</string> + </property> + </widget> + <widget class="KPushButton" row="1" column="1"> + <property name="name"> + <cstring>btnAdd</cstring> + </property> + <property name="text"> + <string>Add Trac&ker</string> + </property> + </widget> + <widget class="QLayoutWidget" row="2" column="1"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnRemove</cstring> + </property> + <property name="text"> + <string>Remove Tracker</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnChange</cstring> + </property> + <property name="text"> + <string>Ch&ange Tracker</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4_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>68</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>btnRestore</cstring> + </property> + <property name="text"> + <string>Restore Defaults</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + </vbox> + </widget> + <widget class="KListView" row="2" column="0"> + <column> + <property name="text"> + <string>Trackers</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>listTrackers</cstring> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <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>URL:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>lblCurrent</cstring> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <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="QLabel"> + <property name="name"> + <cstring>lblStatus</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Next update in:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>lblUpdate</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>btnChange</sender> + <signal>clicked()</signal> + <receiver>TrackerViewBase</receiver> + <slot>btnChange_clicked()</slot> + </connection> + <connection> + <sender>btnUpdate</sender> + <signal>clicked()</signal> + <receiver>TrackerViewBase</receiver> + <slot>btnUpdate_clicked()</slot> + </connection> + <connection> + <sender>btnAdd</sender> + <signal>clicked()</signal> + <receiver>TrackerViewBase</receiver> + <slot>btnAdd_clicked()</slot> + </connection> + <connection> + <sender>btnRemove</sender> + <signal>clicked()</signal> + <receiver>TrackerViewBase</receiver> + <slot>btnRemove_clicked()</slot> + </connection> + <connection> + <sender>btnRestore</sender> + <signal>clicked()</signal> + <receiver>TrackerViewBase</receiver> + <slot>btnRestore_clicked()</slot> + </connection> +</connections> +<slots> + <slot>btnChange_clicked()</slot> + <slot>listTrackers_currentChanged(QListViewItem*)</slot> + <slot>btnUpdate_clicked()</slot> + <slot>btnAdd_clicked()</slot> + <slot>btnRemove_clicked()</slot> + <slot>btnRestore_clicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> |