Files
Phoenix/wx/lib/imagebrowser.py
Scott Talbert 173d079681 Fix a bunch of Python 3.10 issues with pure-Python classes and demos
In Python 3.10, a change[1] was implemented where extension functions
that take integer arguments will no longer silently accept non-integer
arguments (e.g., floats) that can only be converted to integers with a
loss of precision.  This PR fixes most of these issues in the pure-Python
classes and demos by explicitly converting the parameters to int before
passing them to wxWidgets.  There is loss of precision, but this was
happening before (automatically) anyway as most wxWidgets DeviceContext
functions operate using integers.

Additionally, the PR fixes a few sizing issues, mostly with SpinCtrls being
too small on GTK3.

This is an example of the relevant exception:
Traceback (most recent call last):
  File "/usr/lib64/python3.10/site-packages/wx/lib/agw/pygauge.py", line 355, in OnPaint
    r.width = w
TypeError: 'float' object cannot be interpreted as an integer

Fixes #2038.

[1] https://bugs.python.org/issue37999
2021-12-01 14:19:00 -05:00

854 lines
27 KiB
Python

#----------------------------------------------------------------------------
# Name: BrowseImage.py
# Purpose: Display and Select Image Files
#
# Original Author: Lorne White
#
# Version: 2.0
# Date: June 16, 2007
# Licence: wxWindows license
# Tags: phoenix-port
#----------------------------------------------------------------------------
# 2.0 Release - Bill Baxter (wbaxter@gmail.com)
# Date: June 16, 2007
# o Changed to use sizers instead of fixed placement.
# o Made dialog resizeable
# o Added a splitter between file list and view pane
# o Made directory path editable
# o Added an "up" button" to go to the parent dir
# o Changed to show directories in file list
# o Don't select images on double click any more
# o Added a 'broken image' display for files that wx fails to identify
# o Redesigned appearance -- using bitmap buttons now, and rearranged things
# o Fixed display of masked gifs
# o Fixed zooming logic to show shrunken images at correct aspect ratio
# o Added different background modes for preview (white/grey/dark/checkered)
# o Added framing modes for preview (no frame/box frame/tinted border)
#
#----------------------------------------------------------------------------
#
# 12/08/2003 - Jeff Grimmett (grimmtooth@softhome.net)
#
# o Updated for wx namespace
# o Corrected a nasty bug or two - see comments below.
# o There was a duplicate ImageView.DrawImage() method. Que?
#
#----------------------------------------------------------------------------
# 1.0 Release - Lorne White
# Date: January 29, 2002
# Create list of all available image file types
# View "All Image" File Types as default filter
# Sort the file list
# Use newer "re" function for patterns
#
# Tags: phoenix-port, documented, unittest
#---------------------------------------------------------------------------
"""
This module provides the :class:`~lib.imagebrowser.ImageDialog` which allows to view and select
an image.
Description
===========
The :class:`wx.ImageDialog` allows the user to view images and select one.
Usage
=====
A simple usage would be::
import wx
import wx.lib.mixins.inspection as wit
import wx.lib.imagebrowser as ib
app = wit.InspectableApp()
with ib.ImageDialog(None) as dlg:
if dlg.ShowModal() == wx.ID_OK:
# show the selected file
print("You Selected File: " + dlg.GetFile())
else:
print("You pressed Cancel")
app.MainLoop()
"""
import os
import wx
if 'wxOSX' in wx.PlatformInfo:
# The wx.BitmapButton doesn't do so well on OSX with very small bitmaps,
# so use a custom class there.
import wx.lib.buttons
class BitmapButton(wx.lib.buttons.GenBitmapButton):
def __init__(self, *args, **kw):
super(BitmapButton, self).__init__(*args, **kw)
self.SetBezelWidth(1)
self.SetInitialSize()
print(self.GetSize(), self.GetBestSize())
else:
BitmapButton = wx.BitmapButton
_ = wx.GetTranslation
#---------------------------------------------------------------------------
BAD_IMAGE = -1
ID_WHITE_BG = wx.NewIdRef()
ID_BLACK_BG = wx.NewIdRef()
ID_GREY_BG = wx.NewIdRef()
ID_CHECK_BG = wx.NewIdRef()
ID_NO_FRAME = wx.NewIdRef()
ID_BOX_FRAME = wx.NewIdRef()
ID_CROP_FRAME = wx.NewIdRef()
def ConvertBMP(file_nm):
"""
Convert file
:param string `file_nm`: path to file
:return: :class:`wx.Image` or BAD_IMAGE
"""
if file_nm is None:
return None
fl_fld = os.path.splitext(file_nm)
ext = fl_fld[1]
ext = ext[1:].lower()
# Don't try to create it directly because wx throws up
# an annoying messasge dialog if the type isn't supported.
if wx.Image.CanRead(file_nm):
image = wx.Image(file_nm, wx.BITMAP_TYPE_ANY)
return image
# BAD_IMAGE means a bad image, None just means no image (i.e. directory)
return BAD_IMAGE
def GetCheckeredBitmap(blocksize=8, ntiles=4, rgb0=b'\xFF', rgb1=b'\xCC'):
"""
Creates a square RGB checkered bitmap using the two specified colors.
The bitmap returned will have width = height = blocksize*ntiles*2
:param int `blocksize`: the number of pixels in each solid color square
:param int `ntiles1`: the number of tiles along width and height. Each
tile is 2x2 blocks.
:param `rbg0`: the first color, as 3-character bytes object.
:param `rgb1`: the second color, as 3-character bytes object. If only 1
character is provided, it is treated as a grey value.
:return: :class:`wx.Bitmap`
"""
assert isinstance(rgb0, bytes)
assert isinstance(rgb1, bytes)
size = blocksize*ntiles*2
if len(rgb0)==1:
rgb0 = rgb0 * 3
if len(rgb1)==1:
rgb1 = rgb1 * 3
strip0 = (rgb0*blocksize + rgb1*blocksize)*(ntiles*blocksize)
strip1 = (rgb1*blocksize + rgb0*blocksize)*(ntiles*blocksize)
band = strip0 + strip1
data = band * ntiles
return wx.Bitmap.FromBuffer(size, size, data)
def GetNamedBitmap(name):
return IMG_CATALOG[name].GetBitmap()
class ImageView(wx.Window):
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.BORDER_SUNKEN
):
wx.Window.__init__(self, parent, id, pos, size, style=style)
self.image = None
self.check_bmp = None
self.check_dim_bmp = None
# dark_bg is the brush/bitmap to use for painting in the whole background
# lite_bg is the brush/bitmap/pen to use for painting the image rectangle
self.dark_bg = None
self.lite_bg = None
self.border_mode = ID_CROP_FRAME
self.SetBackgroundMode( ID_WHITE_BG )
self.SetBorderMode( ID_NO_FRAME )
# Changed API of wx uses tuples for size and pos now.
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
self.Bind(wx.EVT_SIZE, self.OnSize)
def SetValue(self, file_nm): # display the selected file in the panel
image = ConvertBMP(file_nm)
self.image = image
self.Refresh()
def SetBackgroundMode(self, mode):
self.bg_mode = mode
self._updateBGInfo()
def _updateBGInfo(self):
bg = self.bg_mode
border = self.border_mode
self.dark_bg = None
self.lite_bg = None
if border == ID_BOX_FRAME:
self.lite_bg = wx.BLACK_PEN
if bg == ID_WHITE_BG:
if border == ID_CROP_FRAME:
self.SetBackgroundColour('LIGHT GREY')
self.lite_bg = wx.WHITE_BRUSH
else:
self.SetBackgroundColour('WHITE')
elif bg == ID_GREY_BG:
if border == ID_CROP_FRAME:
self.SetBackgroundColour('GREY')
self.lite_bg = wx.LIGHT_GREY_BRUSH
else:
self.SetBackgroundColour('LIGHT GREY')
elif bg == ID_BLACK_BG:
if border == ID_BOX_FRAME:
self.lite_bg = wx.WHITE_PEN
if border == ID_CROP_FRAME:
self.SetBackgroundColour('GREY')
self.lite_bg = wx.BLACK_BRUSH
else:
self.SetBackgroundColour('BLACK')
else:
if self.check_bmp is None:
self.check_bmp = GetCheckeredBitmap()
self.check_dim_bmp = GetCheckeredBitmap(rgb0=b'\x7F', rgb1=b'\x66')
if border == ID_CROP_FRAME:
self.dark_bg = self.check_dim_bmp
self.lite_bg = self.check_bmp
else:
self.dark_bg = self.check_bmp
self.Refresh()
def SetBorderMode(self, mode):
self.border_mode = mode
self._updateBGInfo()
def OnSize(self, event):
event.Skip()
self.Refresh()
def OnPaint(self, event):
dc = wx.PaintDC(self)
self.DrawImage(dc)
def OnEraseBackground(self, evt):
if self.bg_mode != ID_CHECK_BG:
evt.Skip()
return
dc = evt.GetDC()
if dc:
self.PaintBackground(dc, self.dark_bg)
def PaintBackground(self, dc, painter, rect=None):
if painter is None:
return
if rect is None:
pos = self.GetPosition()
sz = self.GetSize()
else:
pos = rect.Position
sz = rect.Size
if type(painter)==wx.Brush:
dc.SetPen(wx.TRANSPARENT_PEN)
dc.SetBrush(painter)
dc.DrawRectangle(pos.x,pos.y,sz.width,sz.height)
elif type(painter)==wx.Pen:
dc.SetPen(painter)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.DrawRectangle(pos.x-1,pos.y-1,sz.width+2,sz.height+2)
else:
self.TileBackground(dc, painter, pos.x,pos.y,sz.width,sz.height)
def TileBackground(self, dc, bmp, x,y,w,h):
"""Tile bmp into the specified rectangle"""
bw = bmp.GetWidth()
bh = bmp.GetHeight()
dc.SetClippingRegion(x,y,w,h)
# adjust so 0,0 so we always match with a tiling starting at 0,0
dx = x % bw
x = x - dx
w = w + dx
dy = y % bh
y = y - dy
h = h + dy
tx = x
x2 = x+w
y2 = y+h
while tx < x2:
ty = y
while ty < y2:
dc.DrawBitmap(bmp, tx, ty)
ty += bh
tx += bw
def DrawImage(self, dc):
if not hasattr(self,'image') or self.image is None:
return
wwidth,wheight = self.GetSize()
image = self.image
bmp = None
if image != BAD_IMAGE and image.IsOk():
iwidth = image.GetWidth() # dimensions of image file
iheight = image.GetHeight()
else:
bmp = wx.ArtProvider.GetBitmap(wx.ART_MISSING_IMAGE, wx.ART_MESSAGE_BOX, (64,64))
iwidth = bmp.GetWidth()
iheight = bmp.GetHeight()
# squeeze iwidth x iheight image into window, preserving aspect ratio
xfactor = float(wwidth) / iwidth
yfactor = float(wheight) / iheight
if xfactor < 1.0 and xfactor < yfactor:
scale = xfactor
elif yfactor < 1.0 and yfactor < xfactor:
scale = yfactor
else:
scale = 1.0
owidth = int(scale*iwidth)
oheight = int(scale*iheight)
diffx = (wwidth - owidth)//2 # center calc
diffy = (wheight - oheight)//2 # center calc
if not bmp:
if owidth!=iwidth or oheight!=iheight:
sc_image = sc_image = image.Scale(owidth,oheight)
else:
sc_image = image
bmp = sc_image.ConvertToBitmap()
if image != BAD_IMAGE and image.IsOk():
self.PaintBackground(dc, self.lite_bg, wx.Rect(diffx,diffy,owidth,oheight))
dc.DrawBitmap(bmp, diffx, diffy, useMask=True) # draw the image to window
class ImagePanel(wx.Panel):
def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
style=wx.NO_BORDER
):
wx.Panel.__init__(self, parent, id, pos, size, style=style)
vbox = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox)
self.view = ImageView(self)
vbox.Add(self.view, 1, wx.GROW|wx.ALL, 0)
hbox_ctrls = wx.BoxSizer(wx.HORIZONTAL)
vbox.Add(hbox_ctrls, 0, wx.ALIGN_RIGHT|wx.TOP, 4)
bmp = GetNamedBitmap('White')
btn = BitmapButton(self, ID_WHITE_BG, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
btn.SetToolTip(_("Set background to white"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
bmp = GetNamedBitmap('Grey')
btn = BitmapButton(self, ID_GREY_BG, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
btn.SetToolTip(_("Set background to grey"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
bmp = GetNamedBitmap('Black')
btn = BitmapButton(self, ID_BLACK_BG, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
btn.SetToolTip(_("Set background to black"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
bmp = GetNamedBitmap('Checked')
btn = BitmapButton(self, ID_CHECK_BG, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
btn.SetToolTip(_("Set background to checkered pattern"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
hbox_ctrls.AddSpacer(7)
bmp = GetNamedBitmap('NoFrame')
btn = BitmapButton(self, ID_NO_FRAME, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
btn.SetToolTip(_("No framing around image"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
bmp = GetNamedBitmap('BoxFrame')
btn = BitmapButton(self, ID_BOX_FRAME, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
btn.SetToolTip(_("Frame image with a box"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
bmp = GetNamedBitmap('CropFrame')
btn = BitmapButton(self, ID_CROP_FRAME, bmp, style=wx.BU_EXACTFIT)
self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
btn.SetToolTip(_("Frame image with a dimmed background"))
hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
def SetValue(self, file_nm): # display the selected file in the panel
self.view.SetValue(file_nm)
def SetBackgroundMode(self, mode):
self.view.SetBackgroundMode(mode)
def SetBorderMode(self, mode):
self.view.SetBorderMode(mode)
def OnSetImgBackground(self, event):
mode = event.GetId()
self.SetBackgroundMode(mode)
def OnSetBorderMode(self, event):
mode = event.GetId()
self.SetBorderMode(mode)
class ImageDialog(wx.Dialog):
"""
:class:`wx.ImageDialog` derived from :class:`Dialog` allows the user
to display images and to select an image.
"""
def __init__(self, parent, set_dir = None):
"""
Default class constructor.
:param wx.Window `parent`: parent window.
:param string `set_dir`: path to set as working directory
"""
wx.Dialog.__init__(self, parent, -1, _("Image Browser"),
wx.DefaultPosition, (400, 400),
style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
self.set_dir = os.getcwd()
self.set_file = None
if set_dir is not None:
if os.path.exists(set_dir): # set to working directory if nothing set
self.set_dir = set_dir
vbox_top = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(vbox_top)
hbox_loc = wx.BoxSizer(wx.HORIZONTAL)
vbox_top.Add(hbox_loc, 0, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 0)
loc_label = wx.StaticText( self, -1, "Folder:")
hbox_loc.Add(loc_label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ADJUST_MINSIZE, 5)
self.dir = wx.TextCtrl( self, -1, self.set_dir, style=wx.TE_RICH|wx.TE_PROCESS_ENTER)
self.Bind(wx.EVT_TEXT_ENTER, self.OnDirectoryTextSet, self.dir)
hbox_loc.Add(self.dir, 1, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 5)
up_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_DIR_UP, wx.ART_BUTTON, (16,16))
btn = BitmapButton(self, -1, up_bmp, style=wx.BU_EXACTFIT)
btn.SetHelpText(_("Up one level"))
btn.SetToolTip(_("Up one level"))
self.Bind(wx.EVT_BUTTON, self.OnUpDirectory, btn)
hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 2)
folder_bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_BUTTON, (16,16))
btn = BitmapButton(self, -1, folder_bmp, style=wx.BU_EXACTFIT)
btn.SetHelpText(_("Browse for a &folder..."))
btn.SetToolTip(_("Browse for a folder..."))
self.Bind(wx.EVT_BUTTON, self.OnChooseDirectory, btn)
hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5)
hbox_nav = wx.BoxSizer(wx.HORIZONTAL)
vbox_top.Add(hbox_nav, 0, wx.ALIGN_LEFT|wx.ALL, 0)
label = wx.StaticText( self, -1, "Files of type:")
hbox_nav.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
self.fl_ext = '*.bmp' # initial setting for file filtering
self.GetFiles() # get the file list
self.fl_ext_types = (
# display, filter
("All supported formats", "All"),
("BMP (*.bmp)", "*.bmp"),
("GIF (*.gif)", "*.gif"),
("PNG (*.png)", "*.png"),
("JPEG (*.jpg)", "*.jpg"),
("ICO (*.ico)", "*.ico"),
("PNM (*.pnm)", "*.pnm"),
("PCX (*.pcx)", "*.pcx"),
("TIFF (*.tif)", "*.tif"),
("All Files", "*.*"),
)
self.set_type,self.fl_ext = self.fl_ext_types[0] # initial file filter setting
self.fl_types = [ x[0] for x in self.fl_ext_types ]
self.sel_type = wx.ComboBox( self, -1, self.set_type,
wx.DefaultPosition, wx.DefaultSize, self.fl_types,
wx.CB_DROPDOWN )
# after this we don't care about the order any more
self.fl_ext_types = dict(self.fl_ext_types)
self.Bind(wx.EVT_COMBOBOX, self.OnSetType, self.sel_type)
hbox_nav.Add(self.sel_type, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
splitter = wx.SplitterWindow( self, -1, wx.DefaultPosition, wx.Size(100, 100), 0 )
splitter.SetMinimumPaneSize(100)
split_left = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
wx.NO_BORDER|wx.TAB_TRAVERSAL )
vbox_left = wx.BoxSizer(wx.VERTICAL)
split_left.SetSizer(vbox_left)
self.tb = tb = wx.ListBox( split_left, -1, wx.DefaultPosition, wx.DefaultSize,
self.fl_list, wx.LB_SINGLE )
self.Bind(wx.EVT_LISTBOX, self.OnListClick, tb)
self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDClick, tb)
vbox_left.Add(self.tb, 1, wx.GROW|wx.ALL, 0)
width, height = self.tb.GetSize()
split_right = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
wx.NO_BORDER|wx.TAB_TRAVERSAL )
vbox_right = wx.BoxSizer(wx.VERTICAL)
split_right.SetSizer(vbox_right)
self.image_view = ImagePanel( split_right )
vbox_right.Add(self.image_view, 1, wx.GROW|wx.ALL, 0)
splitter.SplitVertically(split_left, split_right, 150)
vbox_top.Add(splitter, 1, wx.GROW|wx.ALL, 5)
hbox_btns = wx.BoxSizer(wx.HORIZONTAL)
vbox_top.Add(hbox_btns, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
ok_btn = wx.Button( self, wx.ID_OPEN, "", wx.DefaultPosition, wx.DefaultSize, 0 )
self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn)
#ok_btn.SetDefault()
hbox_btns.Add(ok_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
cancel_btn = wx.Button( self, wx.ID_CANCEL, "",
wx.DefaultPosition, wx.DefaultSize, 0 )
hbox_btns.Add(cancel_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
self.ResetFiles()
def ChangeFileTypes(self, ft_tuple):
"""
Change list of file types to be supported
:param tuple `ft_tuple`: tuple of files types, e.g. to support just
.gif and .png you would use:
(("GIF (*.gif)", "*.gif"),
("PNG (*.png)", "*.png"))
"""
self.fl_ext_types = ft_tuple
self.set_type, self.fl_ext = self.fl_ext_types[0] # initial file filter setting
self.fl_types = [ x[0] for x in self.fl_ext_types ]
self.sel_type.Clear()
self.sel_type.AppendItems(self.fl_types)
self.sel_type.SetSelection(0)
self.fl_ext_types = dict(self.fl_ext_types)
def GetFiles(self):
# get the file list using directory and extension values
if self.fl_ext == "All":
all_files = []
if self.fl_types[-1] == 'All Files':
allTypes = self.fl_types[-1:]
else:
allTypes = self.fl_types[1:]
for ftypes in allTypes: # get list of all
filter = self.fl_ext_types[ftypes]
#print("filter = ", filter)
self.fl_val = FindFiles(self, self.set_dir, filter)
all_files = all_files + self.fl_val.files # add to list of files
self.fl_list = all_files
else:
self.fl_val = FindFiles(self, self.set_dir, self.fl_ext)
self.fl_list = self.fl_val.files
self.fl_list.sort() # sort the file list
# prepend the directories
self.fl_ndirs = len(self.fl_val.dirs)
self.fl_list = sorted(self.fl_val.dirs) + self.fl_list
def DisplayDir(self):
# display the working directory
if self.dir:
ipt = self.dir.GetInsertionPoint()
self.dir.SetValue(self.set_dir)
self.dir.SetInsertionPoint(ipt)
def OnSetType(self, event):
val = event.GetString() # get file type value
self.fl_ext = self.fl_ext_types[val]
self.ResetFiles()
def OnListDClick(self, event):
self.OnOk('dclick')
def OnListClick(self, event):
val = event.GetSelection()
self.SetListValue(val)
def SetListValue(self, val):
file_nm = self.fl_list[val]
self.set_file = file_val = os.path.join(self.set_dir, file_nm)
if val>=self.fl_ndirs:
self.image_view.SetValue(file_val)
else:
self.image_view.SetValue(None)
def OnDirectoryTextSet(self,event):
event.Skip()
path = event.GetString()
if os.path.isdir(path):
self.set_dir = path
self.ResetFiles()
return
if os.path.isfile(path):
dname,fname = os.path.split(path)
if os.path.isdir(dname):
self.ResetFiles()
# try to select fname in list
try:
idx = self.fl_list.index(fname)
self.tb.SetSelection(idx)
self.SetListValue(idx)
return
except ValueError:
pass
wx.Bell()
def OnUpDirectory(self, event):
sdir = os.path.split(self.set_dir)[0]
self.set_dir = sdir
self.ResetFiles()
def OnChooseDirectory(self, event):
# set the new directory
dlg = wx.DirDialog(self)
dlg.SetPath(self.set_dir)
if dlg.ShowModal() == wx.ID_OK:
self.set_dir = dlg.GetPath()
self.ResetFiles()
dlg.Destroy()
def ResetFiles(self):
# refresh the display with files and initial image
self.DisplayDir()
self.GetFiles()
# Changed 12/8/03 jmg
#
# o Clear listbox first
# o THEN check to see if there are any valid files of the selected
# type,
# o THEN if we have any files to display, set the listbox up,
#
# OTHERWISE
#
# o Leave it cleared
# o Clear the image viewer.
#
# This avoids a nasty assert error.
#
self.tb.Clear()
if len(self.fl_list):
self.tb.Set(self.fl_list)
for idir in range(self.fl_ndirs):
d = self.fl_list[idir]
# mark directories as 'True' with client data
self.tb.SetClientData(idir, True)
self.tb.SetString(idir,'['+d+']')
try:
self.tb.SetSelection(0)
self.SetListValue(0)
except Exception:
self.image_view.SetValue(None)
else:
self.image_view.SetValue(None)
def GetFile(self):
"""
Get selected file
:return: File selected or None
"""
return self.set_file
def GetDirectory(self):
"""
Get directory
:return: get the current directory
"""
return self.set_dir
def OnCancel(self, event):
self.result = None
self.EndModal(wx.ID_CANCEL)
def OnOk(self, event):
if os.path.isdir(self.set_file):
sdir = os.path.split(self.set_file)
#os.path.normapth?
if sdir and sdir[-1]=='..':
sdir = os.path.split(sdir[0])[0]
sdir = os.path.split(sdir)
self.set_dir = os.path.join(*sdir)
self.set_file = None
self.ResetFiles()
elif event != 'dclick':
self.result = self.set_file
self.EndModal(wx.ID_OK)
class FindFiles:
def __init__(self, parent, dir, mask, with_dirs=True):
filelist = []
dirlist = [".."]
self.dir = dir
self.file = ""
mask = mask.upper()
pattern = self.MakeRegex(mask)
for i in os.listdir(dir):
if i == "." or i == "..":
continue
path = os.path.join(dir, i)
if os.path.isdir(path):
dirlist.append(i)
continue
path = path.upper()
value = i.upper()
if pattern.match(value) is not None:
filelist.append(i)
self.files = filelist
if with_dirs:
self.dirs = dirlist
def MakeRegex(self, pattern):
import re
f = "" # Set up a regex for file names
for ch in pattern:
if ch == "*":
f = f + ".*"
elif ch == ".":
f = f + "\."
elif ch == "?":
f = f + "."
else:
f = f + ch
return re.compile(f+'$')
def StripExt(self, file_nm):
fl_fld = os.path.splitext(file_nm)
fl_name = fl_fld[0]
ext = fl_fld[1]
return ext[1:]
#----------------------------------------------------------------------
# This part of the file was generated by C:\Python25\Scripts\img2py
# then edited slightly.
from wx.lib.embeddedimage import PyEmbeddedImage
IMG_CATALOG = {}
IMG_CATALOG['White'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAIUlE"
"QVQYlWNgIAIwMjAw/P//H58KRkYmYkwaVUScIqIAAMjRAxRV8+5MAAAAAElFTkSuQmCC")
IMG_CATALOG['Grey'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAIklE"
"QVQYlWNgIAIwMjAwnDlzBo8KExMTJmJMGlVEnCKiAAC24wMULFLZGAAAAABJRU5ErkJggg==")
IMG_CATALOG['Black'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAADklE"
"QVQYlWNgGAVDFQAAAbwAATN8mzYAAAAASUVORK5CYII=")
IMG_CATALOG['Checked'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAMUlE"
"QVQYlWNgIAIwMjAwnDlzBlnI2NgYRQUjIxMxJtFZEQsDhkvPnj07sG4iShFRAAAougYW+urT"
"ZwAAAABJRU5ErkJggg==")
IMG_CATALOG['NoFrame'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAANklE"
"QVQYla2PQQoAIBACnej/X7ZbUEQtkudhVKkQJNm+EdAqpggCgB+m44kFml1bY39q0k15Bsuc"
"CR/z8ajiAAAAAElFTkSuQmCC")
IMG_CATALOG['BoxFrame'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAQ0lE"
"QVQYlZ2O0QoAIAgDd9L//7I9CFEhJu1psmNOaghJ7l4RYJ0m1U0R2X4vevcHVOiG0tcHBABh"
"8nWpIhpPLtn0rwm4WyD966x3sgAAAABJRU5ErkJggg==")
IMG_CATALOG['CropFrame'] = PyEmbeddedImage(
"iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAASUlE"
"QVQYlb2QMQrAQAgEZ0P+q0/RF5tCuIMUh2myhcgyjCAMIiAiDoS7XxPTCLrXZmaAJKCqgMz8"
"YHpD7ThBkvpcz93z6wtGeQD/sQ8bfXs8NAAAAABJRU5ErkJggg==")