Skip to content

Commit

Permalink
Merge pull request #535 from kivy/matham-patch-1
Browse files Browse the repository at this point in the history
Make win filechooser use modern windows browser and fix small issues.
  • Loading branch information
matham authored Jan 23, 2020
2 parents 34e0184 + a4991d0 commit 48c8b62
Showing 1 changed file with 35 additions and 22 deletions.
57 changes: 35 additions & 22 deletions plyer/platforms/win/filechooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from plyer.facades import FileChooser
from win32com.shell.shell import (
SHBrowseForFolder as browse,
SHGetPathFromIDList as get_path
SHGetPathFromIDList as get_path, SHILCreateFromPath
)
from win32com.shell import shellcon
import win32gui
import win32con
import pywintypes
from os.path import dirname, splitext, join
import pathlib
from os.path import dirname, splitext, join, isdir


class Win32FileChooser(object):
Expand Down Expand Up @@ -64,10 +66,13 @@ def run(self):
args = {}

if self.path:
args["InitialDir"] = dirname(self.path)
_, ext = splitext(self.path)
args["File"] = self.path
args["DefExt"] = ext
if isdir(self.path):
args["InitialDir"] = self.path
else:
args["InitialDir"] = dirname(self.path)
_, ext = splitext(self.path)
args["File"] = self.path
args["DefExt"] = ext and ext[1:] # no period

args["Title"] = self.title if self.title else "Pick a file..."
args["CustomFilter"] = 'Other file types\x00*.*\x00'
Expand All @@ -82,8 +87,8 @@ def run(self):
filters += f[0] + "\x00" + ";".join(f[1:]) + "\x00"
args["Filter"] = filters

flags = win32con.OFN_EXTENSIONDIFFERENT
flags |= win32con.OFN_OVERWRITEPROMPT
flags = win32con.OFN_OVERWRITEPROMPT
flags |= win32con.OFN_HIDEREADONLY

if self.multiple:
flags |= win32con.OFN_ALLOWMULTISELECT
Expand All @@ -93,40 +98,48 @@ def run(self):

args["Flags"] = flags

# GetOpenFileNameW, GetSaveFileNameW will raise
# pywintypes.error: (0, '...', 'No error message is available')
# which is most likely due to incorrect type handling from the
# win32gui side; return empty list in that case after exception
if self.mode == "open":
self.fname, _, _ = win32gui.GetOpenFileNameW(**args)
elif self.mode == "save":
self.fname, _, _ = win32gui.GetSaveFileNameW(**args)
try:
if self.mode == "open":
self.fname, _, _ = win32gui.GetOpenFileNameW(**args)
elif self.mode == "save":
self.fname, _, _ = win32gui.GetSaveFileNameW(**args)
except pywintypes.error as e:
# if canceled, it's not really an error
if not e.winerror:
self._handle_selection(self.selection)
return self.selection
raise

if self.fname:
if self.multiple:
seq = str(self.fname).split("\x00")
dir_n, base_n = seq[0], seq[1:]
self.selection = [
join(dir_n, i) for i in base_n
]
if len(seq) > 1:
dir_n, base_n = seq[0], seq[1:]
self.selection = [
join(dir_n, i) for i in base_n
]
else:
self.selection = seq
else:
self.selection = str(self.fname).split("\x00")

else: # dir mode
BIF_EDITBOX = shellcon.BIF_EDITBOX
BIF_NEWDIALOGSTYLE = 0x00000040
# From http://goo.gl/UDqCqo
pidl, name, images = browse( # pylint: disable=unused-variable
win32gui.GetDesktopWindow(),
None,
self.title if self.title else "Pick a folder...",
0, None, None
BIF_NEWDIALOGSTYLE | BIF_EDITBOX, None, None
)

# pidl is None when nothing is selected
# and e.g. the dialog is closed afterwards with Cancel
if pidl:
self.selection = [str(get_path(pidl).decode('utf-8'))]

except (RuntimeError, pywintypes.error):
except (RuntimeError, pywintypes.error, Exception):
# ALWAYS! let user know what happened
import traceback
traceback.print_exc()
Expand Down

0 comments on commit 48c8b62

Please sign in to comment.