readd advanced progress bar and beginnings of remap_files

This commit is contained in:
Marcos Pinto 2007-11-16 08:08:33 +00:00
parent 0b582261ec
commit 052894e805
10 changed files with 1594 additions and 1404 deletions

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,29 @@
<property name="visible">True</property> <property name="visible">True</property>
</widget> </widget>
</child> </child>
<child>
<widget class="GtkImageMenuItem" id="rename_file">
<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">_Rename File</property>
<property name="use_underline">True</property>
<signal name="activate" handler="rename_file"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image8">
<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-edit</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="rename_file_separator">
<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>
</child>
<child> <child>
<widget class="GtkImageMenuItem" id="priority_dont_download"> <widget class="GtkImageMenuItem" id="priority_dont_download">
<property name="visible">True</property> <property name="visible">True</property>

File diff suppressed because it is too large Load Diff

View File

@ -106,6 +106,43 @@ an error trying to launch the file."))
except KeyError: except KeyError:
pass pass
def rename_file(self, widget=None):
import os, gtk
import deluge.common
dlg = gtk.Dialog(_("Rename File"), None, 0,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OK, gtk.RESPONSE_OK))
dlg.set_default_response(gtk.RESPONSE_OK)
dlg.set_modal(True)
dlg.set_icon(deluge.common.get_logo(32))
label = gtk.Label(_("Enter the new name of the file"))
entry = gtk.Entry()
entry.connect("activate", lambda w : dlg.response(gtk.RESPONSE_OK))
dlg.vbox.pack_start(label)
dlg.vbox.pack_start(entry)
save_dir = self.manager.unique_IDs[self.file_unique_id].save_dir
selected_paths = self.file_view.get_selection().get_selected_rows()[1]
try:
for path in selected_paths:
child_path = self.file_store_sorted.\
convert_path_to_child_path(path)
file_name = self.file_store.get_value(
self.file_store.get_iter(child_path), 0)
file_size = self.file_store.get_value(
self.file_store.get_iter(child_path), 1)
entry.set_text(file_name)
gtk.gdk.threads_enter()
dlg.show_all()
response = dlg.run()
if response == gtk.RESPONSE_OK:
new_name = entry.get_text().decode("utf_8")
dlg.destroy()
self.manager.rename_file(self.file_unique_id, new_name, file_size)
else:
dlg.destroy()
gtk.gdk.threads_leave()
except:
pass
# From core to UI # From core to UI
def prepare_file_store(self): def prepare_file_store(self):
if not self.file_store_dict: if not self.file_store_dict:

View File

@ -1052,3 +1052,6 @@ of HD space! Oops!\nWe had to pause at least one torrent"))
torrent_path = os.path.join(torrent_path, torrent_path = os.path.join(torrent_path,
file["path"].split("/", 1)[0]) file["path"].split("/", 1)[0])
return torrent_path return torrent_path
def rename_file(self, unique_ID, filename, filesize):
return deluge_core.remap_files(unique_ID, filename, filesize)

View File

@ -929,8 +929,33 @@ static PyObject *torrent_get_torrent_state(PyObject *self, PyObject *args)
total_seeds = s.num_complete != -1? s.num_complete : connected_seeds; total_seeds = s.num_complete != -1? s.num_complete : connected_seeds;
total_peers = s.num_incomplete != -1? s.num_incomplete : connected_peers; total_peers = s.num_incomplete != -1? s.num_incomplete : connected_peers;
// The following section computes the ranges of pieces that have been downloaded
std::vector<int> downloaded_range;
bool range_opened=false;
for (unsigned int i=0; i<=s.pieces->size(); ++i) {
bool downloaded=(i<s.pieces->size() && s.pieces->at(i));
if (!range_opened) {
if (downloaded) {
range_opened=true;
downloaded_range.push_back(i);
}
} else {
if (!downloaded) {
range_opened=false;
downloaded_range.push_back(i-1);
}
}
}
PyObject *pieces_range = PyTuple_New(downloaded_range.size()/2);
for(unsigned long i=0; i<downloaded_range.size(); i+=2)
{
PyObject *rangepos;
rangepos = Py_BuildValue("[i,i]",downloaded_range[i],
downloaded_range[i+1]);
PyTuple_SetItem(pieces_range, i/2, rangepos);
}
return Py_BuildValue("{s:s,s:i,s:i,s:l,s:l,s:f,s:f,s:b,s:f,s:L,s:L,s:s,s:s,s:f,s:L,s:L,s:l,s:i,s:i,s:L,s:L,s:i,s:l,s:l,s:b,s:b,s:L,s:L,s:L}", return Py_BuildValue("{s:s,s:i,s:i,s:l,s:l,s:f,s:f,s:b,s:f,s:L,s:L,s:s,s:s,s:f,s:L,s:L,s:O,s:i,s:i,s:L,s:L,s:i,s:l,s:l,s:b,s:b,s:L,s:L,s:L}",
"name", t.handle.get_torrent_info().name().c_str(), "name", t.handle.get_torrent_info().name().c_str(),
"num_files", t.handle.get_torrent_info().num_files(), "num_files", t.handle.get_torrent_info().num_files(),
"state", s.state, "state", s.state,
@ -947,7 +972,7 @@ static PyObject *torrent_get_torrent_state(PyObject *self, PyObject *args)
"progress", s.progress, "progress", s.progress,
"total_payload_download", s.total_payload_download, "total_payload_download", s.total_payload_download,
"total_payload_upload", s.total_payload_upload, "total_payload_upload", s.total_payload_upload,
"pieces", long(s.pieces), // this is really a std::vector<bool>* "pieces", pieces_range,
"pieces_done", s.num_pieces, "pieces_done", s.num_pieces,
"block_size", s.block_size, "block_size", s.block_size,
"total_size", i.total_size(), "total_size", i.total_size(),
@ -1809,7 +1834,8 @@ static PyObject *torrent_replace_trackers(PyObject *self, PyObject *args)
trackerlist.push_back(a_entry); trackerlist.push_back(a_entry);
} }
if (trackerlist.empty()){ if (trackerlist.empty()){
printf("libtorrent didnt like that...trackers cant be empty\n"); std::vector<libtorrent::announce_entry> empty;
M_torrents->at(index).handle.replace_trackers(empty);
} }
else{ else{
M_torrents->at(index).handle.replace_trackers(trackerlist); M_torrents->at(index).handle.replace_trackers(trackerlist);
@ -1841,19 +1867,6 @@ static PyObject *torrent_prioritize_files(PyObject *self, PyObject *args)
} }
t.handle.prioritize_files(priorities_vector); t.handle.prioritize_files(priorities_vector);
#ifndef NDEBUG
int num_pieces = t.handle.get_torrent_info().num_pieces();
std::vector<int> priorities_pieces_vector(num_pieces);
priorities_pieces_vector = t.handle.piece_priorities();
std::cout << "after files prioritization\n";
for (long i = 0; i < num_pieces; i++) {
std::cout << priorities_pieces_vector.at(i);
}
std::cout << "\n";
#endif
Py_INCREF(Py_None); return Py_None; Py_INCREF(Py_None); return Py_None;
} }
@ -2009,6 +2022,34 @@ static PyObject *torrent_add_url_seed(PyObject *self, PyObject *args)
Py_INCREF(Py_None); return Py_None; Py_INCREF(Py_None); return Py_None;
} }
static PyObject *torrent_remap_files(PyObject *self, PyObject *args)
{
python_long unique_ID;
const char *file_name;
float file_size;
if (!PyArg_ParseTuple(args, "isf", &unique_ID, &file_name, &file_size))
return NULL;
long index = get_index_from_unique_ID(unique_ID);
if (PyErr_Occurred())
return NULL;
if (M_torrents->at(index).handle.is_valid()){
libtorrent:size_type new_size = file_size;
std::pair<std::string, libtorrent::size_type> list = std::make_pair(file_name, new_size);
std::vector<std::pair<std::string, libtorrent::size_type> > Vector;
Vector.push_back(list);
torrent_info t = M_torrents->at(index).handle.get_torrent_info();
bool ret = t.remap_files(Vector);
if (ret){
printf("it worked!\n");
}
else{
printf("it failed!\n");
}
}
Py_INCREF(Py_None); return Py_None;
}
//==================== //====================
// Python Module data // Python Module data
//==================== //====================
@ -2073,6 +2114,7 @@ static PyMethodDef deluge_core_methods[] =
{"get_piece_info", torrent_get_piece_info, METH_VARARGS, "."}, {"get_piece_info", torrent_get_piece_info, METH_VARARGS, "."},
{"get_all_piece_info", torrent_get_all_piece_info, METH_VARARGS, "."}, {"get_all_piece_info", torrent_get_all_piece_info, METH_VARARGS, "."},
{"get_file_piece_range", torrent_get_file_piece_range, METH_VARARGS, "."}, {"get_file_piece_range", torrent_get_file_piece_range, METH_VARARGS, "."},
{"remap_files", torrent_remap_files, METH_VARARGS, "."},
{NULL} {NULL}
}; };

View File

@ -154,6 +154,7 @@ class PreferencesDlg:
self.glade.get_widget("ratio_spinner").set_value(self.preferences.get("auto_seed_ratio")) self.glade.get_widget("ratio_spinner").set_value(self.preferences.get("auto_seed_ratio"))
self.glade.get_widget("chk_dht").set_active(self.preferences.get("enable_dht")) self.glade.get_widget("chk_dht").set_active(self.preferences.get("enable_dht"))
self.glade.get_widget("spin_gui").set_value(self.preferences.get("gui_update_interval")) self.glade.get_widget("spin_gui").set_value(self.preferences.get("gui_update_interval"))
self.glade.get_widget("chk_use_advanced_bar").set_active(self.preferences.get("use_advanced_bar"))
#smart dialog set sensitivities #smart dialog set sensitivities
if(self.preferences.get("use_default_dir")): if(self.preferences.get("use_default_dir")):
@ -271,6 +272,7 @@ class PreferencesDlg:
self.preferences.set("clear_max_ratio_torrents", self.glade.get_widget("chk_clear_max_ratio_torrents").get_active()) self.preferences.set("clear_max_ratio_torrents", self.glade.get_widget("chk_clear_max_ratio_torrents").get_active())
self.preferences.set("queue_above_completed", self.glade.get_widget("chk_queue_above_completed").get_active()) self.preferences.set("queue_above_completed", self.glade.get_widget("chk_queue_above_completed").get_active())
self.preferences.set("start_paused", self.glade.get_widget("chk_paused").get_active()) self.preferences.set("start_paused", self.glade.get_widget("chk_paused").get_active())
self.preferences.set("use_advanced_bar", self.glade.get_widget("chk_use_advanced_bar").get_active())
interface.apply_prefs() interface.apply_prefs()
interface.config.save() interface.config.save()

View File

@ -51,6 +51,7 @@ class FilesBaseManager(object):
self.file_menu = self.glade.get_widget("file_tab_menu") self.file_menu = self.glade.get_widget("file_tab_menu")
self.glade.signal_autoconnect({ self.glade.signal_autoconnect({
"open_file" : self.open_file, "open_file" : self.open_file,
"rename_file" : self.rename_file,
"select_all": self.file_select_all, "select_all": self.file_select_all,
"unselect_all": self.file_unselect_all, "unselect_all": self.file_unselect_all,
"priority_dont_download": self.priority_clicked, "priority_dont_download": self.priority_clicked,
@ -69,6 +70,9 @@ class FilesBaseManager(object):
def open_file(self): def open_file(self):
pass pass
def rename_file(self):
pass
def build_file_view(self): def build_file_view(self):
def priority(column, cell, model, iter, data): def priority(column, cell, model, iter, data):
priority = common.fpriority(model.get_value(iter, data)) priority = common.fpriority(model.get_value(iter, data))
@ -154,6 +158,8 @@ class FilesDialogManager(FilesBaseManager):
# not added yet # not added yet
self.glade.get_widget("open_file").hide() self.glade.get_widget("open_file").hide()
self.glade.get_widget("open_file_separator").hide() self.glade.get_widget("open_file_separator").hide()
self.glade.get_widget("rename_file").hide()
self.glade.get_widget("rename_file_separator").hide()
def prepare_file_store(self): def prepare_file_store(self):
for file in self.dumped_torrent: for file in self.dumped_torrent:

View File

@ -147,7 +147,8 @@ if common.windows_check():
"filename_f_width" : 220, "filename_f_width" : 220,
"size_f_width" : 90, "size_f_width" : 90,
"priority_f_width" : 140, "priority_f_width" : 140,
"start_paused": False "start_paused": False,
"use_advanced_bar" : True
} }
else: else:
DEFAULT_PREFS = { DEFAULT_PREFS = {
@ -257,7 +258,8 @@ else:
"filename_f_width" : 220, "filename_f_width" : 220,
"size_f_width" : 90, "size_f_width" : 90,
"priority_f_width" : 140, "priority_f_width" : 140,
"start_paused": False "start_paused": False,
"use_advanced_bar" : True
} }
class Preferences: class Preferences:
@ -287,9 +289,9 @@ class Preferences:
def __setitem__(self, key, value): def __setitem__(self, key, value):
if key not in self.mapping or self.mapping[key]!=value: if key not in self.mapping or self.mapping[key]!=value:
self.mapping[key] = value self.mapping[key] = value
for hook in self.change_hooks: for hook in self.change_hooks:
if (hook[0]==key): hook[1]() if (hook[0]==key): hook[1]()
def __delitem__(self, key): def __delitem__(self, key):
del self.mapping[key] del self.mapping[key]

View File

@ -31,6 +31,7 @@
# statement from all source files in the program, then also delete it here. # statement from all source files in the program, then also delete it here.
import common import common
import gtk
class DetailsTabManager(object): class DetailsTabManager(object):
def __init__(self, glade, manager): def __init__(self, glade, manager):
@ -40,6 +41,8 @@ class DetailsTabManager(object):
# Look into glade's widget prefix function # Look into glade's widget prefix function
self.progress_bar = glade.get_widget("progressbar") self.progress_bar = glade.get_widget("progressbar")
self.custom_progress = glade.get_widget("custom_progress")
self.custom_progress.connect("expose_event", self.paint_customprogress)
self.name = glade.get_widget("summary_name") self.name = glade.get_widget("summary_name")
self.total_size = glade.get_widget("summary_total_size") self.total_size = glade.get_widget("summary_total_size")
self.num_files = glade.get_widget("summary_num_files") self.num_files = glade.get_widget("summary_num_files")
@ -58,7 +61,57 @@ class DetailsTabManager(object):
self.next_announce = glade.get_widget("summary_next_announce") self.next_announce = glade.get_widget("summary_next_announce")
self.eta = glade.get_widget("summary_eta") self.eta = glade.get_widget("summary_eta")
self.torrent_path = glade.get_widget("summary_torrent_path") self.torrent_path = glade.get_widget("summary_torrent_path")
self.advanced_progressbar=glade.get_widget("advanced_progressbar")
self.last_state=None
self.prefchanged_progress()
self.manager.config.onValueChanged('use_advanced_bar',self.prefchanged_progress)
def prefchanged_progress(self):
self.use_advanced_bar=self.manager.config.get("use_advanced_bar")
if self.use_advanced_bar:
self.progress_bar.hide()
self.advanced_progressbar.show()
else:
self.progress_bar.show()
self.advanced_progressbar.hide()
def paint_customprogress(self,arg1=None,arg2=None):
# Draw the custom progress bar
progress_window=self.custom_progress.window
colormap=self.custom_progress.get_colormap()
gc=progress_window.new_gc()
size=progress_window.get_size()
progress_window.begin_paint_rect(gtk.gdk.Rectangle(0,0,size[0],size[1]))
height=size[1]
if height>25: height=25
top=(size[1]-height)/2
gc.set_foreground(colormap.alloc_color('#F0F0FF'))
progress_window.draw_rectangle(gc,True,0,top,size[0],height-1)
gc.set_foreground(colormap.alloc_color('#A0A0AF'))
progress_window.draw_line(gc,0,top+4,size[0],top+4)
state=self.last_state
if state!=None:
gc.set_foreground(colormap.alloc_color('#2020FF'))
progress_window.draw_rectangle(gc,True,0,top,int(size[0]*float(state['progress'])),4)
num_pieces=state["num_pieces"]
for pieces_range in state['pieces']:
range_first=pieces_range[0]*size[0]/num_pieces
range_length=((pieces_range[1]-pieces_range[0]+1)*size[0]/num_pieces)
if range_length==0:
range_length=1
gc.set_foreground(colormap.alloc_color('#8080FF'))
else:
gc.set_foreground(colormap.alloc_color('#2020FF'))
progress_window.draw_rectangle(gc,True,range_first,top+5,range_length,height-5)
gc.set_foreground(colormap.alloc_color('dim gray'))
progress_window.draw_line(gc,0,top,0,top+height)
progress_window.draw_line(gc,0,top,size[0],top)
gc.set_foreground(colormap.alloc_color('white'))
progress_window.draw_line(gc,0,top+height,size[0]-1,top+height)
progress_window.draw_line(gc,size[0]-1,top,size[0]-1,top+height)
progress_window.end_paint()
# Done drawing custom progress bar
def update(self, unique_id): def update(self, unique_id):
state = self.manager.get_torrent_state(unique_id) state = self.manager.get_torrent_state(unique_id)
@ -108,9 +161,13 @@ class DetailsTabManager(object):
self.upload_speed.set_text(common.fspeed(state["upload_rate"])) self.upload_speed.set_text(common.fspeed(state["upload_rate"]))
self.seeders.set_text(common.fseed(state)) self.seeders.set_text(common.fseed(state))
self.peers.set_text(common.fpeer(state)) self.peers.set_text(common.fpeer(state))
self.progress_bar.set_fraction(float(state['progress'])) self.last_state=state
self.progress_bar.set_text(common.fpcnt(state["progress"])) if self.use_advanced_bar:
self.eta.set_text(common.estimate_eta(state)) self.paint_customprogress()
else:
self.progress_bar.set_fraction(float(state['progress']))
self.progress_bar.set_text(common.fpcnt(state["progress"]))
self.share_ratio.set_text( '%.3f' % self.manager.calc_ratio(unique_id, self.share_ratio.set_text( '%.3f' % self.manager.calc_ratio(unique_id,
state)) state))
self.torrent_path.set_text(self.manager.get_torrent_path(unique_id)) self.torrent_path.set_text(self.manager.get_torrent_path(unique_id))