@@ -30,18 +30,10 @@ def __init__(self, root):
3030 self .y_var = tk .StringVar (value = "None" )
3131 self .unround_var = tk .BooleanVar (value = True )
3232
33- # File type checkboxes
34- self .filetype_vars = {
35- "Text Files" : tk .BooleanVar (value = True ),
36- "Python Files" : tk .BooleanVar (value = True ),
37- "Image Files" : tk .BooleanVar (value = False ),
38- "Document Files" : tk .BooleanVar (value = False ),
39- "Audio Files" : tk .BooleanVar (value = False ),
40- "Video Files" : tk .BooleanVar (value = False )
41- }
4233
43- # File type definitions
34+ # File type definitions (including "All files")
4435 self .filetype_definitions = {
36+ "All Files" : ("All files" , "*.*" ),
4537 "Text Files" : ("Text files" , "*.txt" ),
4638 "Python Files" : ("Python files" , "*.py" ),
4739 "Image Files" : ("Image files" , "*.png *.jpg *.jpeg *.gif *.bmp *.tiff" ),
@@ -50,6 +42,14 @@ def __init__(self, root):
5042 "Video Files" : ("Video files" , "*.mp4 *.avi *.mov *.mkv *.wmv" )
5143 }
5244
45+ # File type variables for checkboxes
46+ self .filetype_vars = {}
47+ for filetype in self .filetype_definitions .keys ():
48+ self .filetype_vars [filetype ] = tk .BooleanVar (value = filetype in ["Text Files" , "Python Files" ])
49+
50+ # File type order (for drag and drop)
51+ self .filetype_order = list (self .filetype_definitions .keys ())
52+
5353 # Main frame
5454 main_frame = tk .Frame (root )
5555 main_frame .pack (expand = True , fill = "both" , padx = 10 , pady = 10 )
@@ -125,81 +125,83 @@ def __init__(self, root):
125125 )
126126 unround_check .pack (side = tk .LEFT )
127127
128- # Configuration controls - Row 3 (File Types Checkboxes )
128+ # Configuration controls - Row 3 (Integrated File Types Management )
129129 config_row3 = tk .Frame (config_frame )
130130 config_row3 .pack (fill = "x" , pady = (0 , 10 ))
131131
132132 # File types label
133133 ttk .Label (config_row3 , text = "File Types:" ).pack (side = tk .LEFT )
134134
135- # File types checkboxes frame
135+ # File types checkboxes in simple rows
136136 filetypes_frame = tk .Frame (config_row3 )
137137 filetypes_frame .pack (side = tk .LEFT , padx = (5 , 0 ), fill = "x" , expand = True )
138138
139- # Create checkboxes in two rows
139+ # Create checkboxes in rows
140140 checkbox_row1 = tk .Frame (filetypes_frame )
141141 checkbox_row1 .pack (fill = "x" , pady = (0 , 5 ))
142142
143143 checkbox_row2 = tk .Frame (filetypes_frame )
144144 checkbox_row2 .pack (fill = "x" )
145145
146- # Row 1 checkboxes (3 items)
147- self .text_files_check = ttk .Checkbutton (
148- checkbox_row1 ,
149- text = "Text Files" ,
150- variable = self .filetype_vars ["Text Files" ],
151- command = self .update_filetypes_from_checkboxes
152- )
153- self .text_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
146+ # Create checkboxes for all file types
147+ self .filetype_checkboxes = {}
148+ row1_filetypes = self .filetype_order [:4 ] # First 4 filetypes
149+ row2_filetypes = self .filetype_order [4 :] # Remaining filetypes
150+
151+ # Row 1 checkboxes
152+ for i , filetype in enumerate (row1_filetypes ):
153+ var = self .filetype_vars [filetype ]
154+ checkbox = ttk .Checkbutton (
155+ checkbox_row1 ,
156+ text = filetype ,
157+ variable = var ,
158+ command = self .update_filetypes_from_checkboxes
159+ )
160+ checkbox .pack (side = tk .LEFT , padx = (0 , 15 ))
161+ self .filetype_checkboxes [filetype ] = checkbox
162+
163+ # Row 2 checkboxes
164+ for i , filetype in enumerate (row2_filetypes ):
165+ var = self .filetype_vars [filetype ]
166+ checkbox = ttk .Checkbutton (
167+ checkbox_row2 ,
168+ text = filetype ,
169+ variable = var ,
170+ command = self .update_filetypes_from_checkboxes
171+ )
172+ checkbox .pack (side = tk .LEFT , padx = (0 , 15 ))
173+ self .filetype_checkboxes [filetype ] = checkbox
154174
155- self .python_files_check = ttk .Checkbutton (
156- checkbox_row1 ,
157- text = "Python Files" ,
158- variable = self .filetype_vars ["Python Files" ],
159- command = self .update_filetypes_from_checkboxes
160- )
161- self .python_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
175+ # Configuration controls - Row 4 (Selected File Types Order)
176+ config_row4 = tk .Frame (config_frame )
177+ config_row4 .pack (fill = "x" , pady = (0 , 10 ))
162178
163- self .image_files_check = ttk .Checkbutton (
164- checkbox_row1 ,
165- text = "Image Files" ,
166- variable = self .filetype_vars ["Image Files" ],
167- command = self .update_filetypes_from_checkboxes
168- )
169- self .image_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
170-
171- # Row 2 checkboxes (3 items)
172- self .document_files_check = ttk .Checkbutton (
173- checkbox_row2 ,
174- text = "Document Files" ,
175- variable = self .filetype_vars ["Document Files" ],
176- command = self .update_filetypes_from_checkboxes
177- )
178- self .document_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
179+ # Selected file types order label
180+ ttk .Label (config_row4 , text = "Selected File Types Order:" ).pack (side = tk .LEFT )
179181
180- self .audio_files_check = ttk .Checkbutton (
181- checkbox_row2 ,
182- text = "Audio Files" ,
183- variable = self .filetype_vars ["Audio Files" ],
184- command = self .update_filetypes_from_checkboxes
185- )
186- self .audio_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
182+ # Selected file types order management frame
183+ selected_order_frame = tk .Frame (config_row4 )
184+ selected_order_frame .pack (side = tk .LEFT , padx = (5 , 0 ), fill = "x" , expand = True )
187185
188- self .video_files_check = ttk .Checkbutton (
189- checkbox_row2 ,
190- text = "Video Files" ,
191- variable = self .filetype_vars ["Video Files" ],
192- command = self .update_filetypes_from_checkboxes
193- )
194- self .video_files_check .pack (side = tk .LEFT , padx = (0 , 15 ))
186+ # Selected file types listbox
187+ self .selected_filetypes_listbox = tk .Listbox (selected_order_frame , height = 3 , selectmode = tk .SINGLE )
188+ self .selected_filetypes_listbox .pack (side = tk .LEFT , fill = "x" , expand = True )
195189
196- # Configuration controls - Row 4 (Initial Directory)
197- config_row4 = tk .Frame (config_frame )
198- config_row4 .pack (fill = "x" , pady = (0 , 10 ))
190+ # Selected order control buttons
191+ selected_order_buttons_frame = tk .Frame (selected_order_frame )
192+ selected_order_buttons_frame .pack (side = tk .LEFT , padx = (5 , 0 ))
193+
194+ ttk .Label (selected_order_buttons_frame , text = "Order:" ).pack (side = tk .TOP , pady = (0 , 5 ))
195+ ttk .Button (selected_order_buttons_frame , text = "↑" , width = 4 , command = self .move_selected_filetype_up ).pack (side = tk .TOP , pady = (0 , 2 ))
196+ ttk .Button (selected_order_buttons_frame , text = "↓" , width = 4 , command = self .move_selected_filetype_down ).pack (side = tk .TOP , pady = (0 , 2 ))
197+
198+ # Configuration controls - Row 5 (Initial Directory)
199+ config_row5 = tk .Frame (config_frame )
200+ config_row5 .pack (fill = "x" , pady = (0 , 10 ))
199201
200202 # Initial directory entry
201- ttk .Label (config_row4 , text = "Initial Dir:" ).pack (side = tk .LEFT )
202- initialdir_entry = ttk .Entry (config_row4 , textvariable = self .initialdir_var , width = 60 )
203+ ttk .Label (config_row5 , text = "Initial Dir:" ).pack (side = tk .LEFT )
204+ initialdir_entry = ttk .Entry (config_row5 , textvariable = self .initialdir_var , width = 60 )
203205 initialdir_entry .pack (side = tk .LEFT , padx = (5 , 0 ), fill = "x" , expand = True )
204206 initialdir_entry .bind ("<KeyRelease>" , lambda e : self .validate_and_generate_code ())
205207
@@ -249,6 +251,9 @@ def __init__(self, root):
249251 self .result_text .pack (side = tk .LEFT , fill = "both" , expand = True )
250252 scrollbar .pack (side = tk .RIGHT , fill = "y" )
251253
254+ # Initialize selected filetypes listbox
255+ self .update_selected_filetypes_listbox ()
256+
252257 # Initialize dialog type settings and generate initial code
253258 self .update_dialog_type ()
254259
@@ -355,9 +360,10 @@ def test_current_settings(self):
355360 try :
356361 # Parse filetypes if provided
357362 filetypes = None
358- if self .filetypes_var .get ():
363+ filetypes_value = self .filetypes_var .get ()
364+ if filetypes_value and filetypes_value != "None" :
359365 try :
360- filetypes = eval (self . filetypes_var . get () )
366+ filetypes = eval (filetypes_value )
361367 except (SyntaxError , NameError , TypeError , ValueError ):
362368 # If evaluation fails, use default
363369 filetypes = None
@@ -503,34 +509,97 @@ def update_dialog_type(self):
503509
504510 def _set_filetype_checkboxes_state (self , state ):
505511 """Set the state of all file type checkboxes."""
506- checkboxes = [
507- self .text_files_check ,
508- self .python_files_check ,
509- self .image_files_check ,
510- self .document_files_check ,
511- self .audio_files_check ,
512- self .video_files_check
513- ]
514-
515- for checkbox in checkboxes :
512+ for checkbox in self .filetype_checkboxes .values ():
516513 checkbox .config (state = state )
517514
518515 def update_filetypes_from_checkboxes (self ):
519516 """Update file types from checkbox selections."""
520517 selected_types = []
521518
522- for filetype , var in self .filetype_vars .items ():
523- if var .get ():
519+ # Use the order from filetype_order
520+ for filetype in self .filetype_order :
521+ if filetype in self .filetype_vars and self .filetype_vars [filetype ].get ():
524522 description , pattern = self .filetype_definitions [filetype ]
525523 selected_types .append ((description , pattern ))
526524
527- # "All files" is automatically added by PathBrowser when filetypes is None or empty
525+ # Update selected filetypes listbox
526+ self .update_selected_filetypes_listbox ()
528527
529528 # Convert to string format
530- filetypes_str = str (selected_types )
529+ filetypes_str = str (selected_types ) if selected_types else "None"
531530 self .filetypes_var .set (filetypes_str )
531+
532532 self .generate_code ()
533533
534+
535+ def update_selected_filetypes_listbox (self ):
536+ """Update the selected filetypes listbox display."""
537+ self .selected_filetypes_listbox .delete (0 , tk .END )
538+
539+ # Get selected filetypes in order
540+ selected_filetypes = []
541+ for filetype in self .filetype_order :
542+ if filetype in self .filetype_vars and self .filetype_vars [filetype ].get ():
543+ selected_filetypes .append (filetype )
544+
545+ # Add to listbox
546+ for filetype in selected_filetypes :
547+ self .selected_filetypes_listbox .insert (tk .END , filetype )
548+
549+ def move_selected_filetype_up (self ):
550+ """Move selected filetype up in the selected list."""
551+ selection = self .selected_filetypes_listbox .curselection ()
552+ if selection and selection [0 ] > 0 :
553+ index = selection [0 ]
554+ # Get the selected filetype from the listbox
555+ selected_filetype = self .selected_filetypes_listbox .get (index )
556+
557+ # Find its position in the main order
558+ main_index = self .filetype_order .index (selected_filetype )
559+ prev_index = None
560+
561+ # Find the previous selected filetype in main order
562+ for i in range (main_index - 1 , - 1 , - 1 ):
563+ if self .filetype_order [i ] in self .filetype_vars and self .filetype_vars [self .filetype_order [i ]].get ():
564+ prev_index = i
565+ break
566+
567+ if prev_index is not None :
568+ # Swap in main order
569+ self .filetype_order [main_index ], self .filetype_order [prev_index ] = \
570+ self .filetype_order [prev_index ], self .filetype_order [main_index ]
571+ self .update_selected_filetypes_listbox ()
572+ # Keep the same item selected
573+ self .selected_filetypes_listbox .selection_set (index - 1 )
574+ self .update_filetypes_from_checkboxes ()
575+
576+ def move_selected_filetype_down (self ):
577+ """Move selected filetype down in the selected list."""
578+ selection = self .selected_filetypes_listbox .curselection ()
579+ if selection and selection [0 ] < self .selected_filetypes_listbox .size () - 1 :
580+ index = selection [0 ]
581+ # Get the selected filetype from the listbox
582+ selected_filetype = self .selected_filetypes_listbox .get (index )
583+
584+ # Find its position in the main order
585+ main_index = self .filetype_order .index (selected_filetype )
586+ next_index = None
587+
588+ # Find the next selected filetype in main order
589+ for i in range (main_index + 1 , len (self .filetype_order )):
590+ if self .filetype_order [i ] in self .filetype_vars and self .filetype_vars [self .filetype_order [i ]].get ():
591+ next_index = i
592+ break
593+
594+ if next_index is not None :
595+ # Swap in main order
596+ self .filetype_order [main_index ], self .filetype_order [next_index ] = \
597+ self .filetype_order [next_index ], self .filetype_order [main_index ]
598+ self .update_selected_filetypes_listbox ()
599+ # Keep the same item selected
600+ self .selected_filetypes_listbox .selection_set (index + 1 )
601+ self .update_filetypes_from_checkboxes ()
602+
534603 def generate_code (self ):
535604 """Generate Python code for the current pathchooser configuration."""
536605 dialog_type = self .dialog_type_var .get ()
@@ -561,17 +630,22 @@ def generate_code(self):
561630
562631 # Add filetypes for appropriate dialogs (not for asksavefile with fixed filename)
563632 if dialog_type in ["askopenfile" , "askopenfiles" , "askpath" ] and self .filetypes_var .get ():
564- try :
565- # Try to evaluate the filetypes string
566- filetypes = eval (self .filetypes_var .get ())
567- if filetypes :
568- code_lines .append (" filetypes=[" )
569- for filetype in filetypes :
570- code_lines .append (f" { filetype } ," )
571- code_lines .append (" ]," )
572- except (SyntaxError , NameError , TypeError , ValueError ):
573- # If evaluation fails, add as string
574- code_lines .append (f" filetypes={ self .filetypes_var .get ()} ," )
633+ filetypes_value = self .filetypes_var .get ()
634+ if filetypes_value == "None" :
635+ # Don't add filetypes parameter when None (will use default "All files")
636+ pass
637+ else :
638+ try :
639+ # Try to evaluate the filetypes string
640+ filetypes = eval (filetypes_value )
641+ if filetypes :
642+ code_lines .append (" filetypes=[" )
643+ for filetype in filetypes :
644+ code_lines .append (f" { filetype } ," )
645+ code_lines .append (" ]," )
646+ except (SyntaxError , NameError , TypeError , ValueError ):
647+ # If evaluation fails, add as string
648+ code_lines .append (f" filetypes={ filetypes_value } ," )
575649
576650 # Add select parameter for askpath
577651 if dialog_type == "askpath" and self .select_var .get () != "file" :
0 commit comments