Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.8, 0.8.1, and 0.8.2

gtklib: add NativeFolderSelectDialog class

GetSaveFileNameW does not allow folder selection near as I can tell
SHBrowseForFolder() needed quite a bit of work before it would start
in the correct place, and allow new folders to be added, and allow the
user to enter paths. But this seems to mostly work.

Changeset ecc23800cfaf

Parent f791ec26e7c5

by Steve Borho

Changes to one file · Browse files at ecc23800cfaf Showing diff from parent f791ec26e7c5 Diff from another changeset...

Change 1 of 1 Show Entire File hggtk/​gtklib.py Stacked
 
233
234
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
@@ -233,3 +233,65 @@
  result = False   file_save.destroy()   return result + +class NativeFolderSelectDialog: + """Wrap the windows folder dialog, or display default gtk dialog if + that isn't available""" + def __init__(self, initial = None, title = _('Select Folder')): + self.initial = initial or os.getcwd() + self.title = title + + def run(self): + """run the file dialog, either return a file name, or False if + the user aborted the dialog""" + try: + import win32com, win32gui, pywintypes + return self.runWindows() + except ImportError, e: + print e + return self.runCompatible() + + def runWindows(self): + from win32com.shell import shell, shellcon + import win32gui, pywintypes + + def BrowseCallbackProc(hwnd, msg, lp, data): + if msg== shellcon.BFFM_INITIALIZED: + win32gui.SendMessage(hwnd, shellcon.BFFM_SETSELECTION, 1, data) + elif msg == shellcon.BFFM_SELCHANGED: + # Set the status text of the + # For this message, 'lp' is the address of the PIDL. + pidl = shell.AddressAsPIDL(lp) + try: + path = shell.SHGetPathFromIDList(pidl) + win32gui.SendMessage(hwnd, shellcon.BFFM_SETSTATUSTEXT, 0, path) + except shell.error: + # No path for this PIDL + pass + + fname = None + try: + flags = shellcon.BIF_EDITBOX | 0x40 #shellcon.BIF_NEWDIALOGSTYLE + pidl, _, _ = shell.SHBrowseForFolder(0, + None, + self.title, + flags, + BrowseCallbackProc, # callback function + self.initial) # 'data' param for the callback + if pidl: + fname = shell.SHGetPathFromIDList(pidl) + except (pywintypes.error, pywintypes.com_error): + pass + return fname + + def runCompatible(self): + dialog = gtk.FileChooserDialog(title=None, + action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, + buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, + gtk.STOCK_OPEN,gtk.RESPONSE_OK)) + dialog.set_default_response(gtk.RESPONSE_OK) + response = dialog.run() + if response == gtk.RESPONSE_OK: + return dialog.get_filename() + dialog.destroy() + return None