11# -*- coding: utf-8 -*-
22"""
33tkfilebrowser - Alternative to filedialog for Tkinter
4- Copyright 2017 Juliette Monsel <j_4321@protonmail.com>
4+ Copyright 2017-2018 Juliette Monsel <j_4321@protonmail.com>
55
66tkfilebrowser is free software: you can redistribute it and/or modify
77it under the terms of the GNU General Public License as published by
1919
2020Main class
2121"""
22- # TODO: fix filetype display for extensions like .tar.xz
23- # TODO: improve extension change
24- # TODO: show desktop in shortcuts
22+
2523
2624import psutil
25+ from re import search
26+ from subprocess import check_output
2727from os import walk , mkdir , stat , access , W_OK
2828from os .path import exists , join , getmtime , realpath , split , expanduser , \
2929 abspath , isabs , splitext , dirname , getsize , isdir , isfile , islink
@@ -141,8 +141,6 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
141141 default = 'white' )
142142 fg = style .lookup ('TLabel' , 'foreground' , default = 'black' )
143143 active_bg = style .lookup ('TButton' , 'background' , ('active' ,))
144- # active_fg = style.lookup('TButton', 'foreground', ('active',))
145- # disabled_fg = style.lookup('TButton', 'foreground', ('disabled',))
146144 sel_bg = style .lookup ('Treeview' , 'background' , ('selected' ,))
147145 sel_fg = style .lookup ('Treeview' , 'foreground' , ('selected' ,))
148146 self .option_add ('*TCombobox*Listbox.selectBackground' , sel_bg )
@@ -182,7 +180,7 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
182180 for name , exts in filetypes :
183181 if name not in self .filetypes :
184182 self .filetypes [name ] = []
185- self .filetypes [name ]. extend ([ ext . split ( "*" )[ - 1 ]. strip () for ext in exts . split ( "|" )] )
183+ self .filetypes [name ] = r'%s$' % exts . strip (). replace ( '.' , '\.' ). replace ( '*' , '.*' )
186184 values = list (self .filetypes .keys ())
187185 w = max ([len (f ) for f in values ] + [5 ])
188186 b_filetype = ttk .Combobox (self , textvariable = self .filetype ,
@@ -196,10 +194,8 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
196194 self .filetype .trace_add ('write' , lambda * args : self ._change_filetype ())
197195 except AttributeError :
198196 self .filetype .trace ('w' , lambda * args : self ._change_filetype ())
199- # b_filetype.bind('<<ComboboxSelected>>',
200- # lambda e: self._change_filetype())
201197 else :
202- self .filetypes ["" ] = [ "" ]
198+ self .filetypes ["" ] = r".*$"
203199
204200 # --- recent files
205201 self ._recent_files = RecentFiles (cst .RECENT_FILES , 30 )
@@ -279,11 +275,13 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
279275 scroll_left .grid (row = 0 , column = 1 , sticky = "ns" )
280276 self .left_tree .configure (yscrollcommand = scroll_left .set )
281277
282- # --- list devices and bookmarked locations
278+ # list devices and bookmarked locations
279+ # -------- recent
283280 self .left_tree .insert ("" , "end" , iid = "recent" , text = _ ("Recent" ),
284281 image = self .im_recent )
285282 wrapper .add_tooltip ("recent" , _ ("Recently used" ))
286283
284+ # -------- devices
287285 devices = psutil .disk_partitions ()
288286
289287 for d in devices :
@@ -295,10 +293,26 @@ def __init__(self, parent, initialdir="", initialfile="", mode="openfile",
295293 self .left_tree .insert ("" , "end" , iid = m , text = txt ,
296294 image = self .im_drive )
297295 wrapper .add_tooltip (m , m )
296+
297+ # -------- home
298298 home = expanduser ("~" )
299299 self .left_tree .insert ("" , "end" , iid = home , image = self .im_home ,
300300 text = split (home )[- 1 ])
301301 wrapper .add_tooltip (home , home )
302+
303+ # -------- desktop
304+ try :
305+ desktop = check_output (['xdg-users-dir' , 'DESKTOP' ]).decode ().strip ()
306+ except Exception :
307+ # FileNotFoundError in python3 if xdg-users-dir is not installed,
308+ # but OSError in python2
309+ desktop = join (home , 'Desktop' )
310+ if exists (desktop ):
311+ self .left_tree .insert ("" , "end" , iid = desktop , image = self .im_folder ,
312+ text = split (desktop )[- 1 ])
313+ wrapper .add_tooltip (desktop , desktop )
314+
315+ # -------- bookmarks
302316 path_bm = join (home , ".config" , "gtk-3.0" , "bookmarks" )
303317 path_bm2 = join (home , ".gtk-bookmarks" ) # old location
304318 if exists (path_bm ):
@@ -702,8 +716,7 @@ def _display_recents(self):
702716 f = "/"
703717 if islink (p ):
704718 if isfile (p ):
705- ext = splitext (f )[- 1 ]
706- if extension == ["" ] or ext in extension :
719+ if extension == r".*$" or search (extension , f ):
707720 tags .append ("file_link" )
708721 stats = stat (p )
709722 vals = (p , display_size (stats .st_size ),
@@ -712,8 +725,7 @@ def _display_recents(self):
712725 tags .append ("folder_link" )
713726 vals = (p , "" , get_modification_date (p ))
714727 elif isfile (p ):
715- ext = splitext (f )[- 1 ]
716- if extension == ["" ] or ext in extension :
728+ if extension == r".*$" or search (extension , f ):
717729 tags .append ("file" )
718730 stats = stat (p )
719731 vals = (p , display_size (stats .st_size ),
@@ -756,11 +768,16 @@ def _change_filetype(self):
756768 else :
757769 self ._display_recents ()
758770 if self .mode == 'save' :
759- name , ext = splitext (self .entry .get ())
760- new_ext = self .filetypes [self .filetype .get ()][0 ]
761- if new_ext and ext not in self .filetypes [self .filetype .get ()]:
762- self .entry .delete (len (name ), 'end' )
763- self .entry .insert ('end' , new_ext )
771+ filename = self .entry .get ()
772+ new_ext = self .filetypes [self .filetype .get ()]
773+ if filename and not search (new_ext , filename ):
774+ old_ext = search (r'\..+$' , filename ).group ()
775+ exts = [e [2 :].replace ('\.' , '.' ) for e in new_ext [:- 1 ].split ('|' )]
776+ exts = [e for e in exts if search (r'\.[^\*]+$' , e )]
777+ if exts :
778+ filename = filename .replace (old_ext , exts [0 ])
779+ self .entry .delete (0 , 'end' )
780+ self .entry .insert (0 , filename )
764781
765782 # --- path completion in entries: key bindings
766783 def _down (self , event ):
@@ -817,12 +834,11 @@ def _completion(self, action, modif, pos, prev_txt):
817834 if self .mode is not "opendir" :
818835 files .sort (key = lambda n : n .lower ())
819836 extension = self .filetypes [self .filetype .get ()]
820- if extension == [ "" ] :
837+ if extension == r".*$" :
821838 l2 .extend ([i .replace (" " , "\ " ) for i in files if i [:len (f )] == f ])
822839 else :
823840 for i in files :
824- ext = splitext (i )[- 1 ]
825- if ext in extension and i [:len (f )] == f :
841+ if search (extension , i ) and i [:len (f )] == f :
826842 l2 .append (i .replace (" " , "\ " ))
827843 l2 .extend ([i .replace (" " , "\ " ) + "/" for i in dirs if i [:len (f )] == f ])
828844
@@ -979,7 +995,7 @@ def _display_folder_walk(self, folder, reset=True, update_bar=True):
979995 # display files
980996 files .sort (key = lambda n : n .lower ())
981997 extension = self .filetypes [self .filetype .get ()]
982- if extension == [ "" ] :
998+ if extension == ".*" :
983999 for f in files :
9841000 p = join (root , f )
9851001 if islink (p ):
@@ -1009,8 +1025,7 @@ def _display_folder_walk(self, folder, reset=True, update_bar=True):
10091025 display_modification_date (stats .st_mtime )))
10101026 else :
10111027 for f in files :
1012- ext = splitext (f )[- 1 ]
1013- if ext in extension :
1028+ if extension == r".*$" or search (extension , f ):
10141029 p = join (root , f )
10151030 if islink (p ):
10161031 tags = ("file_link" ,)
@@ -1108,7 +1123,7 @@ def _display_folder_scandir(self, folder, reset=True, update_bar=True):
11081123 i += 1
11091124 stats = f .stat ()
11101125 if b_file :
1111- if ( extension == [ "" ] or splitext ( name )[ - 1 ] in extension ):
1126+ if extension == r".*$" or search ( extension , name ):
11121127 self .right_tree .insert ("" , "end" , f .path , text = name , tags = tags ,
11131128 values = ("" ,
11141129 display_size (stats .st_size ),
0 commit comments