Implement #28 Create Torrent Dialog

This commit is contained in:
Andrew Resch 2008-09-21 00:33:37 +00:00
parent aec7f35a71
commit 68974ff459
7 changed files with 732 additions and 75 deletions

View File

@ -10,3 +10,4 @@ Deluge 1.1.0 - "" (In Development)
* Sorting # column will place downloaders above seeds * Sorting # column will place downloaders above seeds
* Remove dependency on libtorrent for add torrent dialog * Remove dependency on libtorrent for add torrent dialog
* Allow adding multiple trackers at once in the edit tracker dialog * Allow adding multiple trackers at once in the edit tracker dialog
* Implement #28 Create Torrent Dialog

View File

@ -646,6 +646,40 @@ class Core(
unaccessible (non-existent or insufficient privs)""" unaccessible (non-existent or insufficient privs)"""
return deluge.common.get_path_size(path) return deluge.common.get_path_size(path)
def export_create_torrent(self, path, tracker, piece_length, comment, target,
url_list, private, created_by, httpseeds, add_to_session):
log.debug("creating torrent..")
threading.Thread(target=_create_torrent_thread,
args=(
path,
tracker,
piece_length,
comment,
target,
url_list,
private,
created_by,
httpseeds,
add_to_session)).start()
def _create_torrent_thread(self, path, tracker, piece_length, comment, target,
url_list, private, created_by, httpseeds, add_to_session):
import deluge.metafile
deluge.metafile.make_meta_file(
path,
tracker,
piece_length,
comment=comment,
target=target,
url_list=url_list,
private=private,
created_by=created_by,
httpseeds=httpseeds)
log.debug("torrent created!")
if add_to_session:
self.export_add_torrent_file(os.path.split(target)[1], open(target, "rb").read(), None)
## Queueing functions ## ## Queueing functions ##
def export_queue_top(self, torrent_ids): def export_queue_top(self, torrent_ids):
log.debug("Attempting to queue %s to top", torrent_ids) log.debug("Attempting to queue %s to top", torrent_ids)

View File

@ -72,11 +72,11 @@ def decode_from_filesystem(path):
def dummy(v): def dummy(v):
pass pass
def make_meta_file(path, url, piece_len_exp, progress=dummy, def make_meta_file(path, url, piece_length, progress=dummy,
title=None, comment=None, safe=None, content_type=None, title=None, comment=None, safe=None, content_type=None,
target=None, url_list=None, name=None): target=None, url_list=None, name=None, private=False,
created_by=None, httpseeds=None):
data = {'announce': url.strip(), 'creation date': int(gmtime())} data = {'announce': url.strip(), 'creation date': int(gmtime())}
piece_length = 2 ** piece_len_exp
a, b = os.path.split(path) a, b = os.path.split(path)
if not target: if not target:
if b == '': if b == '':
@ -85,7 +85,7 @@ def make_meta_file(path, url, piece_len_exp, progress=dummy,
f = os.path.join(a, b + '.torrent') f = os.path.join(a, b + '.torrent')
else: else:
f = target f = target
info = makeinfo(path, piece_length, progress, name, content_type) info = makeinfo(path, piece_length, progress, name, content_type, private)
#check_info(info) #check_info(info)
h = file(f, 'wb') h = file(f, 'wb')
@ -99,6 +99,11 @@ def make_meta_file(path, url, piece_len_exp, progress=dummy,
data['safe'] = safe data['safe'] = safe
if url_list: if url_list:
data['url-list'] = url_list data['url-list'] = url_list
if created_by:
data['created by'] = created_by
if httpseeds:
data['httpseeds'] = httpseeds
h.write(bencode(data)) h.write(bencode(data))
h.close() h.close()
@ -109,7 +114,7 @@ def calcsize(path):
return total return total
def makeinfo(path, piece_length, progress, name = None, def makeinfo(path, piece_length, progress, name = None,
content_type = None): # HEREDAVE. If path is directory, content_type = None, private=False): # HEREDAVE. If path is directory,
# how do we assign content type? # how do we assign content type?
def to_utf8(name): def to_utf8(name):
if isinstance(name, unicode): if isinstance(name, unicode):
@ -130,6 +135,7 @@ def makeinfo(path, piece_length, progress, name = None,
'characters.' % name) 'characters.' % name)
return u.encode('utf-8') return u.encode('utf-8')
path = os.path.abspath(path) path = os.path.abspath(path)
piece_count = 0
if os.path.isdir(path): if os.path.isdir(path):
subs = subfiles(path) subs = subfiles(path)
subs.sort() subs.sort()
@ -141,6 +147,7 @@ def makeinfo(path, piece_length, progress, name = None,
totalhashed = 0 totalhashed = 0
for p, f in subs: for p, f in subs:
totalsize += os.path.getsize(f) totalsize += os.path.getsize(f)
num_pieces = totalsize / piece_length
for p, f in subs: for p, f in subs:
pos = 0 pos = 0
@ -155,6 +162,7 @@ def makeinfo(path, piece_length, progress, name = None,
while pos < size: while pos < size:
a = min(size - pos, piece_length - done) a = min(size - pos, piece_length - done)
sh.update(h.read(a)) sh.update(h.read(a))
piece_count += 1
done += a done += a
pos += a pos += a
totalhashed += a totalhashed += a
@ -163,7 +171,7 @@ def makeinfo(path, piece_length, progress, name = None,
pieces.append(sh.digest()) pieces.append(sh.digest())
done = 0 done = 0
sh = sha() sh = sha()
progress(a) progress(piece_count, num_pieces)
h.close() h.close()
if done > 0: if done > 0:
pieces.append(sh.digest()) pieces.append(sh.digest())
@ -176,30 +184,33 @@ def makeinfo(path, piece_length, progress, name = None,
return {'pieces': ''.join(pieces), return {'pieces': ''.join(pieces),
'piece length': piece_length, 'files': fs, 'piece length': piece_length, 'files': fs,
'name': name} 'name': name,
'private': private}
else: else:
size = os.path.getsize(path) size = os.path.getsize(path)
num_pieces = size / piece_length
pieces = [] pieces = []
p = 0 p = 0
h = file(path, 'rb') h = file(path, 'rb')
while p < size: while p < size:
x = h.read(min(piece_length, size - p)) x = h.read(min(piece_length, size - p))
if flag.isSet():
return
pieces.append(sha(x).digest()) pieces.append(sha(x).digest())
piece_count += 1
p += piece_length p += piece_length
if p > size: if p > size:
p = size p = size
progress(min(piece_length, size - p)) progress(piece_count, num_pieces)
h.close() h.close()
if content_type is not None: if content_type is not None:
return {'pieces': ''.join(pieces), return {'pieces': ''.join(pieces),
'piece length': piece_length, 'length': size, 'piece length': piece_length, 'length': size,
'name': to_utf8(os.path.split(path)[1]), 'name': to_utf8(os.path.split(path)[1]),
'content_type' : content_type } 'content_type' : content_type,
'private': private }
return {'pieces': ''.join(pieces), return {'pieces': ''.join(pieces),
'piece length': piece_length, 'length': size, 'piece length': piece_length, 'length': size,
'name': to_utf8(os.path.split(path)[1])} 'name': to_utf8(os.path.split(path)[1]),
'private': private}
def subfiles(d): def subfiles(d):
r = [] r = []

View File

@ -169,7 +169,7 @@ class BaseClient(object):
"set_torrent_prioritize_first_last", "set_torrent_auto_managed", "set_torrent_prioritize_first_last", "set_torrent_auto_managed",
"set_torrent_stop_ratio", "set_torrent_stop_at_ratio", "set_torrent_stop_ratio", "set_torrent_stop_at_ratio",
"set_torrent_remove_at_ratio", "set_torrent_move_on_completed", "set_torrent_remove_at_ratio", "set_torrent_move_on_completed",
"set_torrent_move_on_completed_path", "add_torrent_magnets"] "set_torrent_move_on_completed_path", "add_torrent_magnets", "create_torrent"]
def __init__(self): def __init__(self):
self.core = _core self.core = _core

View File

@ -33,67 +33,356 @@
import gtk import gtk
import pkg_resources import pkg_resources
import os.path
import gobject
from deluge.ui.client import aclient as client
import deluge.ui.gtkui.listview as listview
import deluge.component as component import deluge.component as component
import deluge.common import deluge.common
from deluge.configmanager import ConfigManager from deluge.configmanager import ConfigManager
from deluge.log import LOG as log from deluge.log import LOG as log
class CreateTorrentDialog: class CreateTorrentDialog:
def __init__(self):
pass
def show(self): def show(self):
self.config = ConfigManager("gtkui.conf") self.glade = gtk.glade.XML(
glade = gtk.glade.XML(
pkg_resources.resource_filename( pkg_resources.resource_filename(
"deluge.ui.gtkui", "deluge.ui.gtkui",
"glade/create_torrent_dialog.glade")) "glade/create_torrent_dialog.glade"))
self.dialog = glade.get_widget("create_torrent_dialog") self.config = ConfigManager("gtkui.conf")
self.dialog = self.glade.get_widget("create_torrent_dialog")
self.dialog.set_transient_for(component.get("MainWindow").window) self.dialog.set_transient_for(component.get("MainWindow").window)
glade.signal_autoconnect({ self.glade.signal_autoconnect({
"on_button_file_clicked": self._on_button_file_clicked, "on_button_file_clicked": self._on_button_file_clicked,
"on_button_folder_clicked": self._on_button_folder_clicked, "on_button_folder_clicked": self._on_button_folder_clicked,
"on_button_remote_path_clicked": self._on_button_remote_path_clicked, "on_button_remote_path_clicked": self._on_button_remote_path_clicked,
"on_button_cancel_clicked": self._on_button_cancel_clicked, "on_button_cancel_clicked": self._on_button_cancel_clicked,
"on_button_create_clicked": self._on_button_create_clicked, "on_button_save_clicked": self._on_button_save_clicked,
"on_button_up_clicked": self._on_button_up_clicked, "on_button_up_clicked": self._on_button_up_clicked,
"on_button_add_clicked": self._on_button_add_clicked, "on_button_add_clicked": self._on_button_add_clicked,
"on_button_remove_clicked": self._on_button_remove_clicked, "on_button_remove_clicked": self._on_button_remove_clicked,
"on_button_down_clicked": self._on_button_down_clicked "on_button_down_clicked": self._on_button_down_clicked
}) })
# path, icon, size
self.files_treestore = gtk.TreeStore(str, str, gobject.TYPE_UINT64)
self.dialog.show_all() column = gtk.TreeViewColumn(_("Filename"))
render = gtk.CellRendererPixbuf()
column.pack_start(render, False)
column.add_attribute(render, "stock-id", 1)
render = gtk.CellRendererText()
column.pack_start(render, True)
column.add_attribute(render, "text", 0)
column.set_expand(True)
self.glade.get_widget("treeview_files").append_column(column)
column = gtk.TreeViewColumn(_("Size"))
render = gtk.CellRendererText()
column.pack_start(render)
column.set_cell_data_func(render, listview.cell_data_size, 2)
self.glade.get_widget("treeview_files").append_column(column)
self.glade.get_widget("treeview_files").set_model(self.files_treestore)
self.glade.get_widget("treeview_files").set_show_expanders(False)
# tier, url
self.trackers_liststore = gtk.ListStore(int, str)
self.glade.get_widget("tracker_treeview").append_column(
gtk.TreeViewColumn(_("Tier"), gtk.CellRendererText(), text=0))
self.glade.get_widget("tracker_treeview").append_column(
gtk.TreeViewColumn(_("Tracker"), gtk.CellRendererText(), text=1))
self.glade.get_widget("tracker_treeview").set_model(self.trackers_liststore)
self.trackers_liststore.set_sort_column_id(0, gtk.SORT_ASCENDING)
if not client.is_localhost() and client.connected():
self.glade.get_widget("button_remote_path").show()
else:
self.glade.get_widget("button_remote_path").hide()
self.dialog.show()
def adjust_piece_size(self):
"""Adjusts the recommended piece based on the file/folder/path selected."""
size = self.files_treestore[0][2]
model = self.glade.get_widget("combo_piece_size").get_model()
psize = 0
for index,value in enumerate(model):
psize = int(value[0].split()[0]) * 1024
pieces = size / psize
if pieces < 2048 or (index + 1) == len(model):
self.glade.get_widget("combo_piece_size").set_active(index)
break
def _on_button_file_clicked(self, widget): def _on_button_file_clicked(self, widget):
log.debug("_on_button_file_clicked") log.debug("_on_button_file_clicked")
# Setup the filechooserdialog
chooser = gtk.FileChooserDialog(_("Choose a file"),
self.dialog,
gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
chooser.set_transient_for(self.dialog)
chooser.set_select_multiple(False)
chooser.set_property("skip-taskbar-hint", True)
# Run the dialog
response = chooser.run()
if response == gtk.RESPONSE_OK:
result = chooser.get_filename()
else:
chooser.destroy()
return
self.files_treestore.clear()
self.files_treestore.append(None, [result, gtk.STOCK_FILE, deluge.common.get_path_size(result)])
self.adjust_piece_size()
chooser.destroy()
def _on_button_folder_clicked(self, widget): def _on_button_folder_clicked(self, widget):
log.debug("_on_button_folder_clicked") log.debug("_on_button_folder_clicked")
# Setup the filechooserdialog
chooser = gtk.FileChooserDialog(_("Choose a folder"),
self.dialog,
gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
gtk.RESPONSE_OK))
chooser.set_transient_for(self.dialog)
chooser.set_select_multiple(False)
chooser.set_property("skip-taskbar-hint", True)
# Run the dialog
response = chooser.run()
if response == gtk.RESPONSE_OK:
result = chooser.get_filename()
else:
chooser.destroy()
return
self.files_treestore.clear()
self.files_treestore.append(None, [result, gtk.STOCK_OPEN, deluge.common.get_path_size(result)])
self.adjust_piece_size()
chooser.destroy()
def _on_button_remote_path_clicked(self, widget): def _on_button_remote_path_clicked(self, widget):
log.debug("_on_button_remote_path_clicked") log.debug("_on_button_remote_path_clicked")
dialog = self.glade.get_widget("remote_path_dialog")
entry = self.glade.get_widget("entry_path")
dialog.set_transient_for(self.dialog)
entry.set_text("/")
entry.grab_focus()
response = dialog.run()
if response == gtk.RESPONSE_OK:
result = entry.get_text()
def _on_get_path_size(size):
log.debug("size: %s", size)
if size > 0:
self.files_treestore.clear()
self.files_treestore.append(None, [result, gtk.STOCK_NETWORK, size])
self.adjust_piece_size()
client.get_path_size(_on_get_path_size, result)
client.force_call(True)
dialog.destroy()
def _on_button_cancel_clicked(self, widget): def _on_button_cancel_clicked(self, widget):
log.debug("_on_button_cancel_clicked") log.debug("_on_button_cancel_clicked")
self.dialog.destroy() self.dialog.destroy()
def _on_button_create_clicked(self, widget): def _on_button_save_clicked(self, widget):
log.debug("_on_button_create_clicked") log.debug("_on_button_save_clicked")
if len(self.files_treestore) == 0:
return
is_remote = self.files_treestore[0][1] == gtk.STOCK_NETWORK
if is_remote:
# This is a remote path
response = self.glade.get_widget("remote_save_dialog").run()
if response == gtk.RESPONSE_OK:
result = self.glade.get_widget("entry_save_path").get_text()
else:
return
else:
# Setup the filechooserdialog
chooser = gtk.FileChooserDialog(_("Save .torrent file"),
self.dialog,
gtk.FILE_CHOOSER_ACTION_SAVE,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE,
gtk.RESPONSE_OK))
chooser.set_transient_for(self.dialog)
chooser.set_select_multiple(False)
chooser.set_property("skip-taskbar-hint", True)
# Add .torrent and * file filters
file_filter = gtk.FileFilter()
file_filter.set_name(_("Torrent files"))
file_filter.add_pattern("*." + "torrent")
chooser.add_filter(file_filter)
file_filter = gtk.FileFilter()
file_filter.set_name(_("All files"))
file_filter.add_pattern("*")
chooser.add_filter(file_filter)
# Run the dialog
response = chooser.run()
if response == gtk.RESPONSE_OK:
result = chooser.get_filename()
else:
chooser.destroy()
return
# Fix up torrent filename
if len(result) < 9:
result += ".torrent"
elif result[-8:] != ".torrent":
result += ".torrent"
# Get the path
path = self.files_treestore[0][0]
# Get a list of trackers
trackers = [t[1] for t in self.trackers_liststore]
if len(trackers) == 0:
return
# Get a list of webseeds
webseeds = []
b = self.glade.get_widget("textview_webseeds").get_buffer()
lines = b.get_text(b.get_start_iter(), b.get_end_iter()).strip().split("\n")
import deluge.common
for l in lines:
if deluge.common.is_url(l):
webseeds.append(l)
# Get the piece length in bytes
combo = self.glade.get_widget("combo_piece_size")
piece_length = int(combo.get_model()[combo.get_active()][0].split()[0]) * 1024
num_pieces = self.files_treestore[0][2] / piece_length
author = self.glade.get_widget("entry_author").get_text()
comment = self.glade.get_widget("entry_comments").get_text()
private = self.glade.get_widget("chk_private_flag").get_active()
add_to_session = self.glade.get_widget("chk_add_to_session").get_active()
if is_remote:
client.create_torrent(
path,
trackers[0],
piece_length,
comment,
result,
trackers,
private,
author,
webseeds,
add_to_session)
else:
# Setup progress dialog
self.glade.get_widget("progress_dialog").set_transient_for(component.get("MainWindow").window)
self.glade.get_widget("progress_dialog").show_all()
import threading
threading.Thread(target=self.create_torrent,
args=(
path,
trackers[0],
piece_length,
self._on_create_torrent_progress,
comment,
result,
trackers,
private,
author,
webseeds,
add_to_session)).start()
chooser.destroy()
self.dialog.destroy() self.dialog.destroy()
def create_torrent(self, path, tracker, piece_length, progress, comment, target,
url_list, private, created_by, httpseeds, add_to_session):
import deluge.metafile
deluge.metafile.make_meta_file(
path,
tracker,
piece_length,
progress=progress,
comment=comment,
target=target,
url_list=url_list,
private=private,
created_by=created_by,
httpseeds=httpseeds)
self.glade.get_widget("progress_dialog").hide_all()
if add_to_session:
client.add_torrent_files([target])
def _on_create_torrent_progress(self, value, num_pieces):
percent = float(value)/float(num_pieces)
pbar = self.glade.get_widget("progressbar")
pbar.set_text(_("%.2f%%") % (percent*100))
if percent >= 0 and percent <= 1.0:
pbar.set_fraction(percent)
def _on_button_up_clicked(self, widget): def _on_button_up_clicked(self, widget):
log.debug("_on_button_up_clicked") log.debug("_on_button_up_clicked")
row = self.glade.get_widget("tracker_treeview").get_selection().get_selected()[1]
def _on_button_add_clicked(self, widget): if self.trackers_liststore[row][0] == 0:
log.debug("_on_button_add_clicked") return
else:
def _on_button_remove_clicked(self, widget): self.trackers_liststore[row][0] -= 1
log.debug("_on_button_remove_clicked")
def _on_button_down_clicked(self, widget): def _on_button_down_clicked(self, widget):
log.debug("_on_button_down_clicked") log.debug("_on_button_down_clicked")
row = self.glade.get_widget("tracker_treeview").get_selection().get_selected()[1]
self.trackers_liststore[row][0] += 1
def _on_button_add_clicked(self, widget):
log.debug("_on_button_add_clicked")
glade = gtk.glade.XML(
pkg_resources.resource_filename(
"deluge.ui.gtkui",
"glade/edit_trackers.glade"))
dialog = glade.get_widget("add_tracker_dialog")
dialog.set_transient_for(self.dialog)
textview = glade.get_widget("textview_trackers")
textview.get_buffer().set_text("")
textview.grab_focus()
response = dialog.run()
if response == gtk.RESPONSE_OK:
# Create a list of trackers from the textview buffer
trackers = []
b = textview.get_buffer()
lines = b.get_text(b.get_start_iter(), b.get_end_iter()).strip().split("\n")
for l in lines:
if deluge.common.is_url(l):
trackers.append(l)
# We are going to add these trackers to the heighest tier + 1
tier = 0
for row in self.trackers_liststore:
if row[0] > tier:
tier = row[0]
for tracker in trackers:
self.trackers_liststore.append([tier, tracker])
dialog.destroy()
def _on_button_remove_clicked(self, widget):
log.debug("_on_button_remove_clicked")
row = self.glade.get_widget("tracker_treeview").get_selection().get_selected()[1]
self.trackers_liststore.remove(row)

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Fri Aug 29 22:38:52 2008 --> <!--Generated with glade3 3.4.5 on Sat Sep 20 16:56:06 2008 -->
<glade-interface> <glade-interface>
<widget class="GtkWindow" id="create_torrent_dialog"> <widget class="GtkWindow" id="create_torrent_dialog">
<property name="height_request">560</property>
<property name="border_width">5</property> <property name="border_width">5</property>
<property name="title" translatable="yes">Create Torrent</property> <property name="title" translatable="yes">Create Torrent</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
@ -82,10 +81,15 @@
<widget class="GtkTreeView" id="treeview_files"> <widget class="GtkTreeView" id="treeview_files">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">True</property> <property name="headers_clickable">True</property>
</widget> </widget>
</child> </child>
</widget> </widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child> </child>
<child> <child>
<widget class="GtkHButtonBox" id="hbuttonbox2"> <widget class="GtkHButtonBox" id="hbuttonbox2">
@ -279,48 +283,31 @@
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkTable" id="table1"> <widget class="GtkHBox" id="hbox4">
<property name="visible">True</property> <property name="visible">True</property>
<property name="n_rows">2</property> <property name="spacing">5</property>
<property name="n_columns">2</property>
<property name="column_spacing">5</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkTextView" id="textview2">
<property name="visible">True</property>
<property name="can_focus">True</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label6"> <widget class="GtkLabel" id="label6">
<property name="visible">True</property> <property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">Comments:</property> <property name="label" translatable="yes">Comments:</property>
</widget> </widget>
<packing> <packing>
<property name="x_options">GTK_FILL</property> <property name="expand">False</property>
<property name="y_options"></property> </packing>
</child>
<child>
<widget class="GtkEntry" id="entry_comments">
<property name="visible">True</property>
<property name="can_focus">True</property>
</widget>
<packing>
<property name="position">1</property>
</packing> </packing>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
@ -394,7 +381,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="no">gtk-go-up</property> <property name="label">gtk-go-up</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">0</property>
<signal name="clicked" handler="on_button_up_clicked"/> <signal name="clicked" handler="on_button_up_clicked"/>
@ -421,7 +408,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="no">gtk-remove</property> <property name="label">gtk-remove</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">0</property>
<signal name="clicked" handler="on_button_remove_clicked"/> <signal name="clicked" handler="on_button_remove_clicked"/>
@ -436,7 +423,7 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="no">gtk-go-down</property> <property name="label">gtk-go-down</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">0</property>
<signal name="clicked" handler="on_button_down_clicked"/> <signal name="clicked" handler="on_button_down_clicked"/>
@ -497,7 +484,7 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="resize_mode">GTK_RESIZE_QUEUE</property> <property name="resize_mode">GTK_RESIZE_QUEUE</property>
<child> <child>
<widget class="GtkTextView" id="textview1"> <widget class="GtkTextView" id="textview_webseeds">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
</widget> </widget>
@ -562,6 +549,11 @@
<child> <child>
<widget class="GtkComboBox" id="combo_piece_size"> <widget class="GtkComboBox" id="combo_piece_size">
<property name="visible">True</property> <property name="visible">True</property>
<property name="items" translatable="yes">32 KiB
64 KiB
128 KiB
256 KiB
512 KiB</property>
</widget> </widget>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -655,20 +647,21 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="label" translatable="no">gtk-cancel</property> <property name="label">gtk-cancel</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">0</property>
<signal name="clicked" handler="on_button_cancel_clicked"/> <signal name="clicked" handler="on_button_cancel_clicked"/>
</widget> </widget>
</child> </child>
<child> <child>
<widget class="GtkButton" id="button1"> <widget class="GtkButton" id="button_save">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="label" translatable="yes">gtk-save</property> <property name="label" translatable="yes">gtk-save</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">0</property>
<signal name="clicked" handler="on_button_save_clicked"/>
</widget> </widget>
<packing> <packing>
<property name="position">1</property> <property name="position">1</property>
@ -686,4 +679,333 @@
</widget> </widget>
</child> </child>
</widget> </widget>
<widget class="GtkDialog" id="remote_path_dialog">
<property name="width_request">462</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Enter Remote Path</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="decorated">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkHBox" id="hbox7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-network</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">&lt;b&gt;Remote Path&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator3">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Path:</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry_path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="is_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area7">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button_add_cancel">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button_add_ok">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">-5</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="progress_dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Creating Torrent</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkProgressBar" id="progressbar">
<property name="width_request">200</property>
<property name="visible">True</property>
<property name="text" translatable="yes"></property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="remote_save_dialog">
<property name="width_request">462</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">Save .torrent as</property>
<property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="decorated">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">2</property>
<child>
<widget class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkHBox" id="hbox15">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-network</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">&lt;b&gt;Save .torrent file&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox16">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">Path:</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="entry_save_path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="is_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area4">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button_add_cancel1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="button_add_ok1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="response_id">-5</property>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface> </glade-interface>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Fri Sep 19 18:55:00 2008 --> <!--Generated with glade3 3.4.5 on Fri Sep 19 19:14:24 2008 -->
<glade-interface> <glade-interface>
<widget class="GtkDialog" id="edit_trackers_dialog"> <widget class="GtkDialog" id="edit_trackers_dialog">
<property name="width_request">400</property> <property name="width_request">400</property>
@ -343,7 +343,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-cancel</property> <property name="label">gtk-cancel</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">-6</property>
<signal name="clicked" handler="on_button_add_cancel_clicked"/> <signal name="clicked" handler="on_button_add_cancel_clicked"/>
</widget> </widget>
</child> </child>
@ -357,7 +357,7 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label">gtk-ok</property> <property name="label">gtk-ok</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
<property name="response_id">0</property> <property name="response_id">-5</property>
<signal name="clicked" handler="on_button_add_ok_clicked"/> <signal name="clicked" handler="on_button_add_ok_clicked"/>
</widget> </widget>
<packing> <packing>