2424import psutil
2525from re import search
2626from subprocess import check_output
27- from os import walk , mkdir , stat , access , W_OK
27+ from os import walk , mkdir , stat , access , W_OK , listdir
2828from os .path import exists , join , getmtime , realpath , split , expanduser , \
2929 abspath , isabs , splitext , dirname , getsize , isdir , isfile , islink
3030try :
4444_ = cst ._
4545
4646
47+ class Stats :
48+ """Fake stats class to create dummy stats for broken links."""
49+ def __init__ (self , ** kwargs ):
50+ self ._prop = kwargs
51+
52+ def __getattr__ (self , attr ):
53+ if attr not in self ._prop :
54+ raise AttributeError ("Stats has no attribute %s." % attr )
55+ else :
56+ return self ._prop [attr ]
57+
58+
4759class FileBrowser (tk .Toplevel ):
4860 """Filebrowser dialog class."""
4961 def __init__ (self , parent , initialdir = "" , initialfile = "" , mode = "openfile" ,
@@ -52,9 +64,9 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
5264 foldercreation = True , ** kw ):
5365 """
5466 Create a filebrowser dialog.
55-
67+
5668 Arguments:
57-
69+
5870 parent : Tk or Toplevel instance
5971 parent window
6072
@@ -66,15 +78,15 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
6678
6779 initialfile : str
6880 initially selected item (just the name, not the full path)
69-
70- mode : str
81+
82+ mode : str
7183 kind of dialog: "openfile", "opendir" or "save"
72-
84+
7385 multiple_selection : bool
7486 whether to allow multiple items selection (open modes only)
75-
87+
7688 defaultext : str (e.g. '.png')
77- extension added to filename if none is given (default is none)
89+ extension added to filename if none is given (default is none)
7890
7991 filetypes : list ``[("name", "*.ext1|*.ext2|.."), ...]``
8092 only the files of given filetype will be displayed,
@@ -194,6 +206,7 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
194206 self .im_folder = cst .PhotoImage (file = cst .IM_FOLDER , master = self )
195207 self .im_desktop = cst .PhotoImage (file = cst .IM_DESKTOP , master = self )
196208 self .im_file_link = cst .PhotoImage (file = cst .IM_FILE_LINK , master = self )
209+ self .im_link_broken = cst .PhotoImage (file = cst .IM_LINK_BROKEN , master = self )
197210 self .im_folder_link = cst .PhotoImage (file = cst .IM_FOLDER_LINK , master = self )
198211 self .im_new = cst .PhotoImage (file = cst .IM_NEW , master = self )
199212 self .im_drive = cst .PhotoImage (file = cst .IM_DRIVE , master = self )
@@ -401,6 +414,7 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
401414 self .right_tree .tag_configure ("file" , image = self .im_file )
402415 self .right_tree .tag_configure ("folder_link" , image = self .im_folder_link )
403416 self .right_tree .tag_configure ("file_link" , image = self .im_file_link )
417+ self .right_tree .tag_configure ("link_broken" , image = self .im_link_broken )
404418 if mode == "opendir" :
405419 self .right_tree .tag_configure ("file" , foreground = "gray" )
406420 self .right_tree .tag_configure ("file_link" , foreground = "gray" )
@@ -961,6 +975,100 @@ def _update_path_bar(self, path):
961975 self .path_bar_buttons .append (b )
962976 b .grid (row = 0 , column = i + 2 , sticky = "ns" )
963977
978+ def _display_folder_listdir (self , folder , reset = True , update_bar = True ):
979+ """
980+ Display the content of folder in self.right_tree.
981+ Arguments:
982+ * reset (boolean): forget all the part of the history right of self._hist_index
983+ * update_bar (boolean): update the buttons in path bar
984+ """
985+ print ('listdir' )
986+ # remove trailing / if any
987+ folder = abspath (folder )
988+ # reorganize display if previous was 'recent'
989+ if not self .path_bar .winfo_ismapped ():
990+ self .path_bar .grid ()
991+ self .right_tree .configure (displaycolumns = ("size" , "date" ))
992+ w = self .right_tree .winfo_width () - 205
993+ if w < 0 :
994+ w = 250
995+ self .right_tree .column ("#0" , width = w )
996+ self .right_tree .column ("size" , stretch = False , width = 85 )
997+ self .right_tree .column ("date" , width = 120 )
998+ if self .foldercreation :
999+ self .b_new_folder .grid ()
1000+ # reset history
1001+ if reset :
1002+ if not self ._hist_index == - 1 :
1003+ self .history = self .history [:self ._hist_index + 1 ]
1004+ self ._hist_index = - 1
1005+ self .history .append (folder )
1006+ # update path bar
1007+ if update_bar :
1008+ self ._update_path_bar (folder )
1009+ self .path_var .set (folder )
1010+ # disable new folder creation if no write access
1011+ if self .foldercreation :
1012+ if access (folder , W_OK ):
1013+ self .b_new_folder .state (('!disabled' ,))
1014+ else :
1015+ self .b_new_folder .state (('disabled' ,))
1016+ # clear self.right_tree
1017+ self .right_tree .delete (* self .right_tree .get_children ("" ))
1018+ self .right_tree .delete (* self .hidden )
1019+ self .hidden = ()
1020+ root = folder
1021+ extension = self .filetypes [self .filetype .get ()]
1022+ content = listdir (folder )
1023+ i = 0
1024+ for f in content :
1025+ p = join (root , f )
1026+ if f [0 ] == "." :
1027+ tags = ("hidden" ,)
1028+ if not self .hide :
1029+ tags = (str (i % 2 ),)
1030+ i += 1
1031+ else :
1032+ tags = (str (i % 2 ),)
1033+ i += 1
1034+ if isfile (p ):
1035+ if extension == r".*$" or search (extension , f ):
1036+ if islink (p ):
1037+ tags = tags + ("file_link" ,)
1038+ else :
1039+ tags = tags + ("file" ,)
1040+ try :
1041+ stats = stat (p )
1042+ except OSError :
1043+ self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1044+ values = ("" , "??" , "??" ))
1045+ else :
1046+ self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1047+ values = ("" ,
1048+ display_size (stats .st_size ),
1049+ display_modification_date (stats .st_mtime )))
1050+ elif isdir (p ):
1051+ if islink (p ):
1052+ tags = tags + ("folder_link" ,)
1053+ else :
1054+ tags = tags + ("folder" ,)
1055+
1056+ self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1057+ values = ("" , "" , get_modification_date (p )))
1058+ else : # broken link
1059+ tags = tags + ("link_broken" ,)
1060+ self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1061+ values = ("" , "??" , "??" ))
1062+
1063+ items = self .right_tree .get_children ("" )
1064+ if items :
1065+ self .right_tree .focus_set ()
1066+ self .right_tree .focus (items [0 ])
1067+ if self .hide :
1068+ self .hidden = self .right_tree .tag_has ("hidden" )
1069+ self .right_tree .detach (* self .right_tree .tag_has ("hidden" ))
1070+ self ._sort_files_by_name (False )
1071+
9641072 def _display_folder_walk (self , folder , reset = True , update_bar = True ):
9651073 """
9661074 Display the content of folder in self.right_tree.
@@ -1026,13 +1134,18 @@ def _display_folder_walk(self, folder, reset=True, update_bar=True):
10261134 # display files
10271135 files .sort (key = lambda n : n .lower ())
10281136 extension = self .filetypes [self .filetype .get ()]
1029- if extension == ".*" :
1030- for f in files :
1137+ for f in files :
1138+ if extension == r".*$" or search ( extension , f ) :
10311139 p = join (root , f )
10321140 if islink (p ):
10331141 tags = ("file_link" ,)
10341142 else :
10351143 tags = ("file" ,)
1144+ try :
1145+ stats = stat (p )
1146+ except FileNotFoundError :
1147+ stats = Stats (st_size = "??" , st_mtime = "??" )
1148+ tags = ("link_broken" ,)
10361149 if f [0 ] == "." :
10371150 tags = tags + ("hidden" ,)
10381151 if not self .hide :
@@ -1042,47 +1155,10 @@ def _display_folder_walk(self, folder, reset=True, update_bar=True):
10421155 tags = tags + (str (i % 2 ),)
10431156 i += 1
10441157
1045- try :
1046- stats = stat (p )
1047- except OSError :
1048- self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1049- values = ("" ,
1050- display_size (0 ),
1051- display_modification_date (cst .TODAY )))
1052- else :
1053- self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1054- values = ("" ,
1055- display_size (stats .st_size ),
1056- display_modification_date (stats .st_mtime )))
1057- else :
1058- for f in files :
1059- if extension == r".*$" or search (extension , f ):
1060- p = join (root , f )
1061- if islink (p ):
1062- tags = ("file_link" ,)
1063- else :
1064- tags = ("file" ,)
1065- if f [0 ] == "." :
1066- tags = tags + ("hidden" ,)
1067- if not self .hide :
1068- tags = tags + (str (i % 2 ),)
1069- i += 1
1070- else :
1071- tags = tags + (str (i % 2 ),)
1072- i += 1
1073-
1074- try :
1075- stats = stat (p )
1076- except OSError :
1077- self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1078- values = ("" ,
1079- display_size (0 ),
1080- display_modification_date (cst .TODAY )))
1081- else :
1082- self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1083- values = ("" ,
1084- display_size (stats .st_size ),
1085- display_modification_date (stats .st_mtime )))
1158+ self .right_tree .insert ("" , "end" , p , text = f , tags = tags ,
1159+ values = ("" ,
1160+ display_size (stats .st_size ),
1161+ display_modification_date (stats .st_mtime )))
10861162 items = self .right_tree .get_children ("" )
10871163 if items :
10881164 self .right_tree .focus_set ()
@@ -1091,7 +1167,7 @@ def _display_folder_walk(self, folder, reset=True, update_bar=True):
10911167 self .hidden = self .right_tree .tag_has ("hidden" )
10921168 self .right_tree .detach (* self .right_tree .tag_has ("hidden" ))
10931169 except StopIteration :
1094- self ._display_folder_walk ( expanduser ( '~' ) , reset , update_bar )
1170+ self ._display_folder_listdir ( folder , reset , update_bar )
10951171
10961172 def _display_folder_scandir (self , folder , reset = True , update_bar = True ):
10971173 """
@@ -1139,11 +1215,17 @@ def _display_folder_scandir(self, folder, reset=True, update_bar=True):
11391215 try :
11401216 content = sorted (scandir (folder ), key = key_sort_files )
11411217 i = 0
1142- tags_array = [["folder" , "folder_link" ], ["file" , "file_link" ]]
1218+ tags_array = [["folder" , "folder_link" ],
1219+ ["file" , "file_link" ]]
11431220 for f in content :
11441221 b_file = f .is_file ()
11451222 name = f .name
1146- tags = (tags_array [b_file ][f .is_symlink ()],)
1223+ try :
1224+ stats = f .stat ()
1225+ tags = (tags_array [b_file ][f .is_symlink ()],)
1226+ except FileNotFoundError :
1227+ stats = Stats (st_size = "??" , st_mtime = "??" )
1228+ tags = ("link_broken" ,)
11471229 if name [0 ] == '.' :
11481230 tags = tags + ("hidden" ,)
11491231 if not self .hide :
@@ -1152,7 +1234,6 @@ def _display_folder_scandir(self, folder, reset=True, update_bar=True):
11521234 else :
11531235 tags = tags + (str (i % 2 ),)
11541236 i += 1
1155- stats = f .stat ()
11561237 if b_file :
11571238 if extension == r".*$" or search (extension , name ):
11581239 self .right_tree .insert ("" , "end" , f .path , text = name , tags = tags ,
0 commit comments