mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-16 13:26:33 +00:00
167 lines
7.2 KiB
Python
167 lines
7.2 KiB
Python
|
#!/usr/bin/env python
|
||
|
#
|
||
|
# files.py
|
||
|
#
|
||
|
# Copyright (C) Zach Tibbitts 2006 <zach@collegegeek.org>
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 2, 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.
|
||
|
#
|
||
|
# In addition, as a special exception, the copyright holders give
|
||
|
# permission to link the code of portions of this program with the OpenSSL
|
||
|
# library.
|
||
|
# You must obey the GNU General Public License in all respects for all of
|
||
|
# the code used other than OpenSSL. If you modify file(s) with this
|
||
|
# exception, you may extend this exception to your version of the file(s),
|
||
|
# but you are not obligated to do so. If you do not wish to do so, delete
|
||
|
# this exception statement from your version. If you delete this exception
|
||
|
# statement from all source files in the program, then also delete it here.
|
||
|
|
||
|
import os
|
||
|
import sys
|
||
|
import imp
|
||
|
import gtk
|
||
|
import dgtk
|
||
|
import common
|
||
|
from itertools import izip
|
||
|
import gobject
|
||
|
|
||
|
class FilesManager:
|
||
|
def __init__(self, manager, is_file_tab):
|
||
|
self.manager = manager
|
||
|
self.file_glade = gtk.glade.XML(common.get_glade_file("file_tab_menu.glade"), domain='deluge')
|
||
|
self.file_menu = self.file_glade.get_widget("file_tab_menu")
|
||
|
self.file_glade.signal_autoconnect({
|
||
|
"select_all": self.file_select_all,
|
||
|
"unselect_all": self.file_unselect_all,
|
||
|
"check_selected": self.file_check_selected,
|
||
|
"uncheck_selected": self.file_uncheck_selected,
|
||
|
})
|
||
|
self.file_unique_id = -1
|
||
|
# Stores file path -> gtk.TreeIter's iter mapping for quick look up
|
||
|
# in self.update_torrent_info_widget
|
||
|
self.file_store_dict = {}
|
||
|
self.file_store = gtk.ListStore(bool, str, gobject.TYPE_UINT64)
|
||
|
self.file_store_sorted = gtk.TreeModelSort(self.file_store)
|
||
|
self.is_file_tab = is_file_tab
|
||
|
if self.is_file_tab:
|
||
|
self.file_store = gtk.ListStore(bool, str, gobject.TYPE_UINT64, float)
|
||
|
self.file_store_sorted = gtk.TreeModelSort(self.file_store)
|
||
|
|
||
|
def use_unique_id(self, unique_id):
|
||
|
self.file_unique_id = unique_id
|
||
|
|
||
|
def file_view_actions(self, file_view):
|
||
|
self.file_view = file_view
|
||
|
def percent(column, cell, model, iter, data):
|
||
|
percent = float(model.get_value(iter, data))
|
||
|
percent_str = "%.2f%%"%percent
|
||
|
cell.set_property("text", percent_str)
|
||
|
self.file_selected = []
|
||
|
self.toggle_column = dgtk.add_toggle_column(self.file_view, _("Download"), 0, toggled_signal=self.file_toggled)
|
||
|
self.filename_column = dgtk.add_text_column(self.file_view, _("Filename"), 1)
|
||
|
self.filename_column.set_expand(True)
|
||
|
self.size_column = dgtk.add_func_column(self.file_view, _("Size"), dgtk.cell_data_size, 2)
|
||
|
if self.is_file_tab:
|
||
|
dgtk.add_func_column(self.file_view, _("Progress"), percent, 3)
|
||
|
self.file_view.set_model(self.file_store_sorted)
|
||
|
self.file_view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||
|
self.file_view.get_selection().set_select_function(self.file_clicked)
|
||
|
self.file_view.connect("button-press-event", self.file_view_clicked)
|
||
|
|
||
|
def remove_columns(self):
|
||
|
self.file_view.remove_column(self.size_column)
|
||
|
self.file_view.remove_column(self.filename_column)
|
||
|
self.file_view.remove_column(self.toggle_column)
|
||
|
|
||
|
def clear_file_store(self):
|
||
|
self.file_store.clear()
|
||
|
self.file_store_dict = {}
|
||
|
|
||
|
def prepare_store(self):
|
||
|
if not self.file_store_dict:
|
||
|
all_files = self.manager.get_torrent_file_info(self.file_unique_id)
|
||
|
file_filter = self.manager.get_file_filter(self.file_unique_id)
|
||
|
if file_filter is None:
|
||
|
file_filter = [False] * len(all_files)
|
||
|
if self.is_file_tab:
|
||
|
for file, filt in izip(all_files, file_filter):
|
||
|
iter = self.file_store.append([not filt, file['path'],
|
||
|
file['size'],
|
||
|
round(file['progress'], 2)])
|
||
|
self.file_store_dict[file['path']] = iter
|
||
|
else:
|
||
|
for file, filt in izip(all_files, file_filter):
|
||
|
iter = self.file_store.append([not filt, file['path'],
|
||
|
file['size']])
|
||
|
self.file_store_dict[file['path']] = iter
|
||
|
|
||
|
|
||
|
def update_store(self):
|
||
|
new_file_info = self.manager.get_torrent_file_info(self.file_unique_id)
|
||
|
for file in new_file_info:
|
||
|
iter = self.file_store_dict[file['path']]
|
||
|
if self.file_store.get_value(iter, 3) != round(file['progress'], 2):
|
||
|
self.file_store.set(iter, 3, file['progress'])
|
||
|
|
||
|
def file_select_all(self, widget):
|
||
|
self.file_view.get_selection().select_all()
|
||
|
|
||
|
def file_unselect_all(self, widget):
|
||
|
self.file_view.get_selection().unselect_all()
|
||
|
|
||
|
def file_check_selected(self, widget):
|
||
|
self.file_view.get_selection().selected_foreach(self.file_toggle_selected, True)
|
||
|
self.file_toggled_update_filter()
|
||
|
|
||
|
def file_uncheck_selected(self, widget):
|
||
|
self.file_view.get_selection().selected_foreach(self.file_toggle_selected, False)
|
||
|
self.file_toggled_update_filter()
|
||
|
|
||
|
def file_clicked(self, path):
|
||
|
return not self.file_selected
|
||
|
|
||
|
def file_view_clicked(self, widget, event):
|
||
|
if event.button == 3:
|
||
|
self.file_menu.popup(None, None, None, event.button, event.time)
|
||
|
return True
|
||
|
else:
|
||
|
self.file_selected = False
|
||
|
return False
|
||
|
|
||
|
def file_toggle_selected(self, treemodel, path, selected_iter, value):
|
||
|
child_iter = self.file_store_sorted.convert_iter_to_child_iter(None,
|
||
|
selected_iter)
|
||
|
self.file_store_sorted.get_model().set_value(child_iter, 0, value)
|
||
|
|
||
|
def file_toggled(self, renderer, path):
|
||
|
self.file_selected = True
|
||
|
file_iter = self.file_store_sorted.get_iter_from_string(path)
|
||
|
value = not renderer.get_active()
|
||
|
selection = self.file_view.get_selection()
|
||
|
if selection.iter_is_selected(file_iter):
|
||
|
selection.selected_foreach(self.file_toggle_selected, value)
|
||
|
else:
|
||
|
child_iter = self.file_store_sorted.convert_iter_to_child_iter(
|
||
|
None, file_iter)
|
||
|
self.file_store_sorted.get_model().set_value(child_iter, 0, value)
|
||
|
|
||
|
self.file_toggled_update_filter()
|
||
|
|
||
|
def file_toggled_update_filter(self):
|
||
|
file_filter = [not x[0] for x in self.file_store]
|
||
|
self.manager.set_file_filter(self.file_unique_id, file_filter)
|