diff --git a/ChangeLog b/ChangeLog
index c8a2b6f6b..dc3533db5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,3 +10,4 @@ Deluge 1.1.0 - "" (In Development)
* Sorting # column will place downloaders above seeds
* Remove dependency on libtorrent for add torrent dialog
* Allow adding multiple trackers at once in the edit tracker dialog
+ * Implement #28 Create Torrent Dialog
diff --git a/deluge/core/core.py b/deluge/core/core.py
index cf8e0bf03..e4c4e948b 100644
--- a/deluge/core/core.py
+++ b/deluge/core/core.py
@@ -645,7 +645,41 @@ class Core(
"""Returns the size of the file or folder 'path' and -1 if the path is
unaccessible (non-existent or insufficient privs)"""
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 ##
def export_queue_top(self, torrent_ids):
log.debug("Attempting to queue %s to top", torrent_ids)
diff --git a/deluge/metafile.py b/deluge/metafile.py
index 98904434d..2b5620a58 100644
--- a/deluge/metafile.py
+++ b/deluge/metafile.py
@@ -72,11 +72,11 @@ def decode_from_filesystem(path):
def dummy(v):
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,
- 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())}
- piece_length = 2 ** piece_len_exp
a, b = os.path.split(path)
if not target:
if b == '':
@@ -85,7 +85,7 @@ def make_meta_file(path, url, piece_len_exp, progress=dummy,
f = os.path.join(a, b + '.torrent')
else:
f = target
- info = makeinfo(path, piece_length, progress, name, content_type)
+ info = makeinfo(path, piece_length, progress, name, content_type, private)
#check_info(info)
h = file(f, 'wb')
@@ -99,6 +99,11 @@ def make_meta_file(path, url, piece_len_exp, progress=dummy,
data['safe'] = safe
if 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.close()
@@ -109,7 +114,7 @@ def calcsize(path):
return total
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?
def to_utf8(name):
if isinstance(name, unicode):
@@ -130,6 +135,7 @@ def makeinfo(path, piece_length, progress, name = None,
'characters.' % name)
return u.encode('utf-8')
path = os.path.abspath(path)
+ piece_count = 0
if os.path.isdir(path):
subs = subfiles(path)
subs.sort()
@@ -141,7 +147,8 @@ def makeinfo(path, piece_length, progress, name = None,
totalhashed = 0
for p, f in subs:
totalsize += os.path.getsize(f)
-
+ num_pieces = totalsize / piece_length
+
for p, f in subs:
pos = 0
size = os.path.getsize(f)
@@ -155,6 +162,7 @@ def makeinfo(path, piece_length, progress, name = None,
while pos < size:
a = min(size - pos, piece_length - done)
sh.update(h.read(a))
+ piece_count += 1
done += a
pos += a
totalhashed += a
@@ -163,7 +171,7 @@ def makeinfo(path, piece_length, progress, name = None,
pieces.append(sh.digest())
done = 0
sh = sha()
- progress(a)
+ progress(piece_count, num_pieces)
h.close()
if done > 0:
pieces.append(sh.digest())
@@ -176,30 +184,33 @@ def makeinfo(path, piece_length, progress, name = None,
return {'pieces': ''.join(pieces),
'piece length': piece_length, 'files': fs,
- 'name': name}
+ 'name': name,
+ 'private': private}
else:
size = os.path.getsize(path)
+ num_pieces = size / piece_length
pieces = []
p = 0
h = file(path, 'rb')
while p < size:
x = h.read(min(piece_length, size - p))
- if flag.isSet():
- return
pieces.append(sha(x).digest())
+ piece_count += 1
p += piece_length
if p > size:
p = size
- progress(min(piece_length, size - p))
+ progress(piece_count, num_pieces)
h.close()
if content_type is not None:
return {'pieces': ''.join(pieces),
'piece length': piece_length, 'length': size,
'name': to_utf8(os.path.split(path)[1]),
- 'content_type' : content_type }
+ 'content_type' : content_type,
+ 'private': private }
return {'pieces': ''.join(pieces),
'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):
r = []
diff --git a/deluge/ui/client.py b/deluge/ui/client.py
index 69662a3f9..2f8300a9f 100644
--- a/deluge/ui/client.py
+++ b/deluge/ui/client.py
@@ -169,7 +169,7 @@ class BaseClient(object):
"set_torrent_prioritize_first_last", "set_torrent_auto_managed",
"set_torrent_stop_ratio", "set_torrent_stop_at_ratio",
"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):
self.core = _core
diff --git a/deluge/ui/gtkui/createtorrentdialog.py b/deluge/ui/gtkui/createtorrentdialog.py
index 812980571..b27fbc1ef 100644
--- a/deluge/ui/gtkui/createtorrentdialog.py
+++ b/deluge/ui/gtkui/createtorrentdialog.py
@@ -33,67 +33,356 @@
import gtk
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.common
from deluge.configmanager import ConfigManager
from deluge.log import LOG as log
class CreateTorrentDialog:
- def __init__(self):
- pass
-
def show(self):
- self.config = ConfigManager("gtkui.conf")
- glade = gtk.glade.XML(
+ self.glade = gtk.glade.XML(
pkg_resources.resource_filename(
"deluge.ui.gtkui",
"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)
-
- glade.signal_autoconnect({
+
+ self.glade.signal_autoconnect({
"on_button_file_clicked": self._on_button_file_clicked,
"on_button_folder_clicked": self._on_button_folder_clicked,
"on_button_remote_path_clicked": self._on_button_remote_path_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_add_clicked": self._on_button_add_clicked,
"on_button_remove_clicked": self._on_button_remove_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):
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):
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):
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):
log.debug("_on_button_cancel_clicked")
self.dialog.destroy()
- def _on_button_create_clicked(self, widget):
- log.debug("_on_button_create_clicked")
+ def _on_button_save_clicked(self, widget):
+ 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()
+
+ 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):
log.debug("_on_button_up_clicked")
-
+ row = self.glade.get_widget("tracker_treeview").get_selection().get_selected()[1]
+ if self.trackers_liststore[row][0] == 0:
+ return
+ else:
+ self.trackers_liststore[row][0] -= 1
+
+ def _on_button_down_clicked(self, widget):
+ 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")
-
- def _on_button_down_clicked(self, widget):
- log.debug("_on_button_down_clicked")
+ row = self.glade.get_widget("tracker_treeview").get_selection().get_selected()[1]
+ self.trackers_liststore.remove(row)
+
diff --git a/deluge/ui/gtkui/glade/create_torrent_dialog.glade b/deluge/ui/gtkui/glade/create_torrent_dialog.glade
index c7504b0fd..9df3c7280 100644
--- a/deluge/ui/gtkui/glade/create_torrent_dialog.glade
+++ b/deluge/ui/gtkui/glade/create_torrent_dialog.glade
@@ -1,9 +1,8 @@
-
+
- 560
5
Create Torrent
GTK_WIN_POS_CENTER_ON_PARENT
@@ -82,10 +81,15 @@
True
True
+ False
True
+
+ False
+ False
+
@@ -279,48 +283,31 @@
-
+
True
- 2
- 2
- 5
-
-
-
-
-
- True
- True
- GTK_POLICY_AUTOMATIC
- GTK_POLICY_AUTOMATIC
- GTK_SHADOW_IN
-
-
- True
- True
-
-
-
-
- 1
- 2
- 2
-
-
+ 5
True
- 0
- 0
Comments:
- GTK_FILL
-
+ False
+
+
+
+
+
+ 1
+ False
+ False
1
@@ -394,7 +381,7 @@
True
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- gtk-go-up
+ gtk-go-up
True
0
@@ -421,7 +408,7 @@
True
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- gtk-remove
+ gtk-remove
True
0
@@ -436,7 +423,7 @@
True
True
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
- gtk-go-down
+ gtk-go-down
True
0
@@ -497,7 +484,7 @@
True
GTK_RESIZE_QUEUE
-
+
True
True
@@ -562,6 +549,11 @@
True
+ 32 KiB
+64 KiB
+128 KiB
+256 KiB
+512 KiB
False
@@ -655,20 +647,21 @@
True
True
True
- gtk-cancel
+ gtk-cancel
True
0
-
+
True
True
True
gtk-save
True
0
+
1
@@ -686,4 +679,333 @@
+
+ 462
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ Enter Remote Path
+ GTK_WIN_POS_CENTER_ON_PARENT
+ True
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ False
+ False
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-network
+
+
+ False
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Remote Path</b>
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ Path:
+
+
+ False
+ False
+
+
+
+
+ True
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 1
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ GTK_BUTTONBOX_END
+
+
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-cancel
+ True
+ -6
+
+
+
+
+ True
+ True
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-ok
+ True
+ -5
+
+
+ 1
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
+
+ 5
+ Creating Torrent
+ GTK_WIN_POS_CENTER_ON_PARENT
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ False
+
+
+ True
+ 2
+
+
+ 200
+ True
+
+
+
+ False
+ False
+ 1
+
+
+
+
+ True
+ GTK_BUTTONBOX_END
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
+
+ 462
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+ Save .torrent as
+ GTK_WIN_POS_CENTER_ON_PARENT
+ True
+ GDK_WINDOW_TYPE_HINT_DIALOG
+ False
+ False
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 2
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-network
+
+
+ False
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ <b>Save .torrent file</b>
+ True
+
+
+ False
+ False
+ 1
+
+
+
+
+ False
+ False
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+
+
+ False
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ 5
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ Path:
+
+
+ False
+ False
+
+
+
+
+ True
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ True
+
+
+ 1
+
+
+
+
+ False
+ False
+ 2
+
+
+
+
+ 1
+
+
+
+
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ GTK_BUTTONBOX_END
+
+
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-cancel
+ True
+ -6
+
+
+
+
+ True
+ True
+ True
+ True
+ True
+ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ gtk-ok
+ True
+ -5
+
+
+ 1
+
+
+
+
+ False
+ GTK_PACK_END
+
+
+
+
+
diff --git a/deluge/ui/gtkui/glade/edit_trackers.glade b/deluge/ui/gtkui/glade/edit_trackers.glade
index c45d6b6f3..960a418f5 100644
--- a/deluge/ui/gtkui/glade/edit_trackers.glade
+++ b/deluge/ui/gtkui/glade/edit_trackers.glade
@@ -1,6 +1,6 @@
-
+
400
@@ -343,7 +343,7 @@
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
gtk-cancel
True
- 0
+ -6
@@ -357,7 +357,7 @@
GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
gtk-ok
True
- 0
+ -5