2007-07-15 19:24:37 +00:00
#!/usr/bin/env python
2007-07-23 21:59:32 +00:00
# -*- coding: utf-8 -*-
2007-07-15 19:24:37 +00:00
#
# 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.
from itertools import izip
2007-07-18 12:47:24 +00:00
2007-07-15 19:24:37 +00:00
import gobject
2007-07-18 12:47:24 +00:00
import gtk
2007-07-22 19:17:50 +00:00
import gtk . glade
2007-07-18 12:47:24 +00:00
import common
import dgtk
2007-07-23 14:24:38 +00:00
import pref
2007-07-15 19:24:37 +00:00
2007-07-18 09:06:24 +00:00
class FilesBaseManager ( object ) :
def __init__ ( self , file_store ) :
2007-07-18 12:47:24 +00:00
file_glade = gtk . glade . XML ( common . get_glade_file ( " file_tab_menu.glade " ) ,
domain = ' deluge ' )
self . file_menu = file_glade . get_widget ( " file_tab_menu " )
file_glade . signal_autoconnect ( {
" select_all " : self . file_select_all ,
" unselect_all " : self . file_unselect_all ,
" priority_dont_download " : self . priority_clicked ,
" priority_normal " : self . priority_clicked ,
" priority_high " : self . priority_clicked ,
" priority_highest " : self . priority_clicked ,
} )
2007-07-18 09:06:24 +00:00
self . file_store = file_store
# We need file_store_sorted so original file_store keeps unchanged
# when file_view is sorted. And from file_store we have to pass
# files priorities to manager.prioritize_files() in the exact same
# order as we get files from manager.get_torrent_file_info()
2007-07-16 03:23:36 +00:00
self . file_store_sorted = gtk . TreeModelSort ( self . file_store )
2007-07-15 19:24:37 +00:00
2007-07-16 03:23:36 +00:00
def build_file_view ( self , file_view ) :
2007-07-15 19:24:37 +00:00
self . file_view = file_view
2007-07-18 09:06:24 +00:00
2007-07-18 12:47:24 +00:00
def priority ( column , cell , model , iter , data ) :
priority = common . fpriority ( model . get_value ( iter , data ) )
cell . set_property ( " text " , priority )
2007-07-18 10:00:41 +00:00
filename_column = dgtk . add_text_column ( self . file_view , _ ( " Filename " ) ,
2007-07-18 12:47:24 +00:00
0 )
2007-07-18 10:00:41 +00:00
filename_column . set_expand ( True )
dgtk . add_func_column ( self . file_view , _ ( " Size " ) , dgtk . cell_data_size ,
2007-07-18 12:47:24 +00:00
1 )
dgtk . add_func_column ( self . file_view , _ ( " Priority " ) , priority , 2 )
2007-07-18 09:06:24 +00:00
2007-07-15 19:24:37 +00:00
self . file_view . set_model ( self . file_store_sorted )
self . file_view . get_selection ( ) . set_mode ( gtk . SELECTION_MULTIPLE )
2007-07-22 17:17:30 +00:00
2007-07-18 12:47:24 +00:00
self . file_view . connect ( " button-press-event " , self . mouse_clicked )
2007-07-15 19:24:37 +00:00
def clear_file_store ( self ) :
self . file_store . clear ( )
self . file_store_dict = { }
2007-07-18 09:06:24 +00:00
def prepare_file_store ( self ) :
pass
2007-07-15 19:24:37 +00:00
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 ( )
2007-07-21 21:04:10 +00:00
2007-07-23 14:24:38 +00:00
def compact_allocation_warning ( self ) :
2007-07-21 21:04:10 +00:00
msgBox = gtk . MessageDialog ( parent = None , buttons = gtk . BUTTONS_OK ,
2007-07-23 14:24:38 +00:00
message_format = ( _ ( " File priority can only be set when using full allocation. \n Please change your preference to disable compact allocation, then remove and readd this torrent. " ) ) )
2007-07-21 21:04:10 +00:00
msgBox . run ( )
msgBox . destroy ( )
2007-07-15 19:24:37 +00:00
2007-07-18 12:47:24 +00:00
def priority_clicked ( self , widget ) :
2007-07-23 14:24:38 +00:00
widget_name = widget . get_name ( )
priority = { ' priority_dont_download ' : common . PRIORITY_DONT_DOWNLOAD ,
' priority_normal ' : common . PRIORITY_NORMAL ,
' priority_high ' : common . PRIORITY_HIGH ,
' priority_highest ' : common . PRIORITY_HIGHEST } [ widget_name ]
selected_paths = self . file_view . get_selection ( ) . get_selected_rows ( ) [ 1 ]
for path in selected_paths :
child_path = self . file_store_sorted . \
convert_path_to_child_path ( path )
self . file_store . set_value ( self . file_store . get_iter ( child_path ) , 2 ,
2007-07-18 12:47:24 +00:00
priority )
2007-07-23 14:24:38 +00:00
self . update_priorities ( )
2007-07-22 17:17:30 +00:00
2007-07-18 12:47:24 +00:00
def mouse_clicked ( self , widget , event ) :
2007-07-15 19:24:37 +00:00
if event . button == 3 :
2007-07-22 17:17:30 +00:00
data = self . file_view . get_path_at_pos ( int ( event . x ) , int ( event . y ) )
if data is None :
return True
path , col , cellx , celly = data
2007-07-22 17:35:39 +00:00
is_selected = self . file_view . get_selection ( ) . path_is_selected ( path )
if not is_selected :
self . file_view . grab_focus ( )
self . file_view . set_cursor ( path , col , 0 )
2007-07-15 19:24:37 +00:00
self . file_menu . popup ( None , None , None , event . button , event . time )
2007-07-22 17:35:39 +00:00
return is_selected
2007-07-15 19:24:37 +00:00
else :
return False
2007-07-18 12:47:24 +00:00
def update_priorities ( self ) :
2007-07-18 09:06:24 +00:00
pass
class FilesTabManager ( FilesBaseManager ) :
def __init__ ( self , manager ) :
2007-07-18 12:47:24 +00:00
file_store = gtk . ListStore ( str , gobject . TYPE_UINT64 ,
gobject . TYPE_UINT , float )
2007-07-18 09:06:24 +00:00
super ( FilesTabManager , self ) . __init__ ( file_store )
self . manager = manager
self . file_unique_id = None
# Stores file path -> gtk.TreeIter's iter mapping for quick look up
# in self.update_file_store()
self . file_store_dict = { }
def build_file_view ( self , file_view ) :
super ( FilesTabManager , self ) . build_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 )
dgtk . add_func_column ( file_view , _ ( " Progress " ) , percent , 3 )
def set_unique_id ( self , unique_id ) :
self . file_unique_id = unique_id
2007-07-23 14:24:38 +00:00
def priority_clicked ( self , widget ) :
state = self . manager . get_torrent_state ( self . file_unique_id )
if state [ " compact_mode " ] :
self . compact_allocation_warning ( )
else :
super ( FilesTabManager , self ) . priority_clicked ( widget )
2007-07-18 12:47:24 +00:00
# From core to UI
2007-07-18 09:06:24 +00:00
def prepare_file_store ( self ) :
if not self . file_store_dict :
all_files = self . manager . get_torrent_file_info ( self . file_unique_id )
file_priorities = self . manager . get_priorities ( self . file_unique_id )
for file , priority in izip ( all_files , file_priorities ) :
2007-07-18 12:47:24 +00:00
iter = self . file_store . append ( [ file [ ' path ' ] , file [ ' size ' ] ,
priority , round ( file [ ' progress ' ] , 2 ) ] )
2007-07-18 09:06:24 +00:00
self . file_store_dict [ file [ ' path ' ] ] = iter
2007-07-18 12:47:24 +00:00
# From core to UI
2007-07-18 09:06:24 +00:00
def update_file_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 ' ] ]
2007-07-22 19:17:50 +00:00
dgtk . update_store ( self . file_store , iter , ( 3 , ) ,
( round ( file [ ' progress ' ] , 2 ) , ) )
2007-07-18 12:47:24 +00:00
# From UI to core
def update_priorities ( self ) :
2007-07-18 09:06:24 +00:00
file_priorities = [ ]
for x in self . file_store :
2007-07-18 12:47:24 +00:00
file_priorities . append ( x [ 2 ] )
2007-07-18 09:06:24 +00:00
self . manager . prioritize_files ( self . file_unique_id , file_priorities )
class FilesDialogManager ( FilesBaseManager ) :
def __init__ ( self , dumped_torrent ) :
2007-07-18 12:47:24 +00:00
file_store = gtk . ListStore ( str , gobject . TYPE_UINT64 ,
gobject . TYPE_UINT )
2007-07-18 09:06:24 +00:00
super ( FilesDialogManager , self ) . __init__ ( file_store )
2007-07-15 19:24:37 +00:00
2007-07-18 09:06:24 +00:00
self . dumped_torrent = dumped_torrent
2007-07-23 14:24:38 +00:00
self . config = pref . Preferences ( )
2007-07-18 09:06:24 +00:00
def prepare_file_store ( self ) :
for file in self . dumped_torrent :
2007-07-18 12:47:24 +00:00
self . file_store . append ( [ file [ ' path ' ] , file [ ' size ' ] ,
common . PRIORITY_NORMAL ] )
2007-07-23 14:24:38 +00:00
def priority_clicked ( self , widget ) :
if self . config . get ( " use_compact_storage " ) :
self . compact_allocation_warning ( )
else :
super ( FilesDialogManager , self ) . priority_clicked ( widget )
2007-07-18 09:06:24 +00:00
def get_priorities ( self ) :
file_priorities = [ ]
for x in self . file_store :
2007-07-18 12:47:24 +00:00
file_priorities . append ( x [ 2 ] )
2007-07-18 09:06:24 +00:00
return file_priorities