]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/imagebrowser.py
Merge recent wxPython changes from 2.8 branch to HEAD
[wxWidgets.git] / wxPython / wx / lib / imagebrowser.py
CommitLineData
d14a1e28
RD
1#----------------------------------------------------------------------------
2# Name: BrowseImage.py
3# Purpose: Display and Select Image Files
4#
fe45b493 5# Original Author: Lorne White
d14a1e28 6#
fe45b493
RD
7# Version: 2.0
8# Date: June 16, 2007
d14a1e28
RD
9# Licence: wxWindows license
10#----------------------------------------------------------------------------
fe45b493
RD
11# 2.0 Release - Bill Baxter (wbaxter@gmail.com)
12# Date: June 16, 2007
13# o Changed to use sizers instead of fixed placement.
14# o Made dialog resizeable
15# o Added a splitter between file list and view pane
16# o Made directory path editable
17# o Added an "up" button" to go to the parent dir
18# o Changed to show directories in file list
19# o Don't select images on double click any more
20# o Added a 'broken image' display for files that wx fails to identify
21# o Redesigned appearance -- using bitmap buttons now, and rearranged things
22# o Fixed display of masked gifs
23# o Fixed zooming logic to show shrunken images at correct aspect ratio
24# o Added different background modes for preview (white/grey/dark/checkered)
25# o Added framing modes for preview (no frame/box frame/tinted border)
26#
b881fc78
RD
27#----------------------------------------------------------------------------
28#
29# 12/08/2003 - Jeff Grimmett (grimmtooth@softhome.net)
30#
31# o Updated for wx namespace
32# o Corrected a nasty bug or two - see comments below.
33# o There was a duplicate ImageView.DrawImage() method. Que?
34#
fe45b493
RD
35#----------------------------------------------------------------------------
36# 1.0 Release - Lorne White
37# Date: January 29, 2002
38# Create list of all available image file types
39# View "All Image" File Types as default filter
40# Sort the file list
41# Use newer "re" function for patterns
42#
1fded56b 43
d14a1e28
RD
44#---------------------------------------------------------------------------
45
b881fc78
RD
46import os
47import sys
b881fc78
RD
48import wx
49
d14a1e28
RD
50#---------------------------------------------------------------------------
51
fe45b493
RD
52BAD_IMAGE = -1
53ID_WHITE_BG = wx.NewId()
54ID_BLACK_BG = wx.NewId()
55ID_GREY_BG = wx.NewId()
56ID_CHECK_BG = wx.NewId()
57ID_NO_FRAME = wx.NewId()
58ID_BOX_FRAME = wx.NewId()
59ID_CROP_FRAME = wx.NewId()
60
d14a1e28
RD
61def ConvertBMP(file_nm):
62 if file_nm is None:
63 return None
64
65 fl_fld = os.path.splitext(file_nm)
66 ext = fl_fld[1]
67 ext = ext[1:].lower()
d14a1e28 68
fe45b493
RD
69 # Don't try to create it directly because wx throws up
70 # an annoying messasge dialog if the type isn't supported.
71 if wx.Image.CanRead(file_nm):
72 image = wx.Image(file_nm, wx.BITMAP_TYPE_ANY)
73 return image
74
75 # BAD_IMAGE means a bad image, None just means no image (i.e. directory)
76 return BAD_IMAGE
77
d14a1e28 78
fe45b493
RD
79def GetCheckeredBitmap(blocksize=8,ntiles=4,rgb0='\xFF', rgb1='\xCC'):
80 """Creates a square RGB checkered bitmap using the two specified colors.
b881fc78 81
fe45b493
RD
82 Inputs:
83 - blocksize: the number of pixels in each solid color square
84 - ntiles: the number of tiles along width and height. Each tile is 2x2 blocks.
85 - rbg0,rgb1: the first and second colors, as 3-byte strings.
86 If only 1 byte is provided, it is treated as a grey value.
87
88 The bitmap returned will have width = height = blocksize*ntiles*2
89 """
90 size = blocksize*ntiles*2
91
92 if len(rgb0)==1:
93 rgb0 = rgb0 * 3
94 if len(rgb1)==1:
95 rgb1 = rgb1 * 3
96
97 strip0 = (rgb0*blocksize + rgb1*blocksize)*(ntiles*blocksize)
98 strip1 = (rgb1*blocksize + rgb0*blocksize)*(ntiles*blocksize)
99 band = strip0 + strip1
100 data = band * ntiles
101 return wx.BitmapFromBuffer(size, size, data)
102
103def GetNamedBitmap(name):
104 return IMG_CATALOG[name].getBitmap()
d14a1e28 105
b881fc78
RD
106
107class ImageView(wx.Window):
fe45b493
RD
108 def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
109 style=wx.BORDER_SUNKEN
110 ):
111 wx.Window.__init__(self, parent, id, pos, size, style=style)
112
d14a1e28 113 self.image = None
fe45b493
RD
114
115 self.check_bmp = None
116 self.check_dim_bmp = None
117
118 # dark_bg is the brush/bitmap to use for painting in the whole background
119 # lite_bg is the brush/bitmap/pen to use for painting the image rectangle
120 self.dark_bg = None
121 self.lite_bg = None
122
123 self.border_mode = ID_CROP_FRAME
124 self.SetBackgroundMode( ID_WHITE_BG )
125 self.SetBorderMode( ID_NO_FRAME )
d14a1e28 126
b881fc78 127 # Changed API of wx uses tuples for size and pos now.
b881fc78 128 self.Bind(wx.EVT_PAINT, self.OnPaint)
fe45b493
RD
129 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
130 self.Bind(wx.EVT_SIZE, self.OnSize)
d14a1e28 131
d14a1e28
RD
132
133 def SetValue(self, file_nm): # display the selected file in the panel
134 image = ConvertBMP(file_nm)
135 self.image = image
136 self.Refresh()
fe45b493
RD
137
138 def SetBackgroundMode(self, mode):
139 self.bg_mode = mode
140 self._updateBGInfo()
d14a1e28 141
fe45b493
RD
142 def _updateBGInfo(self):
143 bg = self.bg_mode
144 border = self.border_mode
d14a1e28 145
fe45b493
RD
146 self.dark_bg = None
147 self.lite_bg = None
148
149 if border == ID_BOX_FRAME:
150 self.lite_bg = wx.BLACK_PEN
151
152 if bg == ID_WHITE_BG:
153 if border == ID_CROP_FRAME:
154 self.SetBackgroundColour('LIGHT GREY')
155 self.lite_bg = wx.WHITE_BRUSH
156 else:
157 self.SetBackgroundColour('WHITE')
158
159 elif bg == ID_GREY_BG:
160 if border == ID_CROP_FRAME:
161 self.SetBackgroundColour('GREY')
162 self.lite_bg = wx.LIGHT_GREY_BRUSH
163 else:
164 self.SetBackgroundColour('LIGHT GREY')
165
166 elif bg == ID_BLACK_BG:
167 if border == ID_BOX_FRAME:
168 self.lite_bg = wx.WHITE_PEN
169 if border == ID_CROP_FRAME:
170 self.SetBackgroundColour('GREY')
171 self.lite_bg = wx.BLACK_BRUSH
172 else:
173 self.SetBackgroundColour('BLACK')
174
175 else:
176 if self.check_bmp is None:
177 self.check_bmp = GetCheckeredBitmap()
178 self.check_dim_bmp = GetCheckeredBitmap(rgb0='\x7F', rgb1='\x66')
179 if border == ID_CROP_FRAME:
180 self.dark_bg = self.check_dim_bmp
181 self.lite_bg = self.check_bmp
182 else:
183 self.dark_bg = self.check_bmp
184
185 self.Refresh()
186
187 def SetBorderMode(self, mode):
188 self.border_mode = mode
189 self._updateBGInfo()
d14a1e28 190
fe45b493
RD
191 def OnSize(self, event):
192 event.Skip()
193 self.Refresh()
b881fc78 194
fe45b493
RD
195 def OnPaint(self, event):
196 dc = wx.PaintDC(self)
197 self.DrawImage(dc)
198
199 def OnEraseBackground(self, evt):
200 if self.bg_mode != ID_CHECK_BG:
201 evt.Skip()
202 return
203 dc = evt.GetDC()
204 if not dc:
205 dc = wx.ClientDC(self)
206 rect = self.GetUpdateRegion().GetBox()
207 dc.SetClippingRect(rect)
208 self.PaintBackground(dc, self.dark_bg)
209
210 def PaintBackground(self, dc, painter, rect=None):
211 if painter is None:
d14a1e28 212 return
fe45b493
RD
213 if rect is None:
214 pos = self.GetPosition()
215 sz = self.GetSize()
216 else:
217 pos = rect.Position
218 sz = rect.Size
219
220 if type(painter)==wx.Brush:
221 dc.SetPen(wx.TRANSPARENT_PEN)
222 dc.SetBrush(painter)
223 dc.DrawRectangle(pos.x,pos.y,sz.width,sz.height)
224 elif type(painter)==wx.Pen:
225 dc.SetPen(painter)
226 dc.SetBrush(wx.TRANSPARENT_BRUSH)
227 dc.DrawRectangle(pos.x-1,pos.y-1,sz.width+2,sz.height+2)
228 else:
229 self.TileBackground(dc, painter, pos.x,pos.y,sz.width,sz.height)
230
231
232 def TileBackground(self, dc, bmp, x,y,w,h):
233 """Tile bmp into the specified rectangle"""
234 bw = bmp.GetWidth()
235 bh = bmp.GetHeight()
236
237 dc.SetClippingRegion(x,y,w,h)
238
239 # adjust so 0,0 so we always match with a tiling starting at 0,0
240 dx = x % bw
241 x = x - dx
242 w = w + dx
d14a1e28 243
fe45b493
RD
244 dy = y % bh
245 y = y - dy
246 h = h + dy
247
248 tx = x
249 x2 = x+w
250 y2 = y+h
251
252 while tx < x2:
253 ty = y
254 while ty < y2:
255 dc.DrawBitmap(bmp, tx, ty)
256 ty += bh
257 tx += bw
258
259 def DrawImage(self, dc):
260
261 if not hasattr(self,'image') or self.image is None:
0b0849b5 262 return
d14a1e28 263
fe45b493
RD
264 wwidth,wheight = self.GetSize()
265 image = self.image
266 bmp = None
267 if image != BAD_IMAGE and image.IsOk():
268 iwidth = image.GetWidth() # dimensions of image file
269 iheight = image.GetHeight()
270 else:
271 bmp = wx.ArtProvider.GetBitmap(wx.ART_MISSING_IMAGE, wx.ART_MESSAGE_BOX, (64,64))
272 iwidth = bmp.GetWidth()
273 iheight = bmp.GetHeight()
d14a1e28 274
fe45b493 275 # squeeze iwidth x iheight image into window, preserving aspect ratio
d14a1e28 276
fe45b493
RD
277 xfactor = float(wwidth) / iwidth
278 yfactor = float(wheight) / iheight
d14a1e28 279
fe45b493
RD
280 if xfactor < 1.0 and xfactor < yfactor:
281 scale = xfactor
282 elif yfactor < 1.0 and yfactor < xfactor:
283 scale = yfactor
284 else:
285 scale = 1.0
d14a1e28 286
fe45b493
RD
287 owidth = int(scale*iwidth)
288 oheight = int(scale*iheight)
d14a1e28 289
fe45b493
RD
290 diffx = (wwidth - owidth)/2 # center calc
291 diffy = (wheight - oheight)/2 # center calc
292
293 if not bmp:
294 if owidth!=iwidth or oheight!=iheight:
295 sc_image = sc_image = image.Scale(owidth,oheight)
296 else:
297 sc_image = image
298 bmp = sc_image.ConvertToBitmap()
299
300 if image != BAD_IMAGE and image.IsOk():
301 self.PaintBackground(dc, self.lite_bg, wx.Rect(diffx,diffy,owidth,oheight))
302
303 dc.DrawBitmap(bmp, diffx, diffy, useMask=True) # draw the image to window
304
305
306class ImagePanel(wx.Panel):
307 def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize,
308 style=wx.NO_BORDER
309 ):
310 wx.Panel.__init__(self, parent, id, pos, size, style=style)
311
312 vbox = wx.BoxSizer(wx.VERTICAL)
313 self.SetSizer(vbox)
314
315 self.view = ImageView(self)
316 vbox.Add(self.view, 1, wx.GROW|wx.ALL, 0)
317
318 hbox_ctrls = wx.BoxSizer(wx.HORIZONTAL)
319 vbox.Add(hbox_ctrls, 0, wx.ALIGN_RIGHT|wx.TOP, 4)
320
321 bmp = GetNamedBitmap('White')
322 btn = wx.BitmapButton(self, ID_WHITE_BG, bmp, style=wx.BU_EXACTFIT)
323 self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
324 btn.SetToolTipString("Set background to white")
325 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
d14a1e28 326
fe45b493
RD
327 bmp = GetNamedBitmap('Grey')
328 btn = wx.BitmapButton(self, ID_GREY_BG, bmp, style=wx.BU_EXACTFIT)
329 self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
330 btn.SetToolTipString("Set background to grey")
331 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
d14a1e28 332
fe45b493
RD
333 bmp = GetNamedBitmap('Black')
334 btn = wx.BitmapButton(self, ID_BLACK_BG, bmp, style=wx.BU_EXACTFIT)
335 self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
336 btn.SetToolTipString("Set background to black")
337 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
338
339 bmp = GetNamedBitmap('Checked')
340 btn = wx.BitmapButton(self, ID_CHECK_BG, bmp, style=wx.BU_EXACTFIT)
341 self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
342 btn.SetToolTipString("Set background to chekered pattern")
343 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
344
345
346 hbox_ctrls.AddSpacer(7)
347
348 bmp = GetNamedBitmap('NoFrame')
349 btn = wx.BitmapButton(self, ID_NO_FRAME, bmp, style=wx.BU_EXACTFIT)
350 self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
351 btn.SetToolTipString("No framing around image")
352 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
353
354 bmp = GetNamedBitmap('BoxFrame')
355 btn = wx.BitmapButton(self, ID_BOX_FRAME, bmp, style=wx.BU_EXACTFIT)
356 self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
357 btn.SetToolTipString("Frame image with a box")
358 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
359
360 bmp = GetNamedBitmap('CropFrame')
361 btn = wx.BitmapButton(self, ID_CROP_FRAME, bmp, style=wx.BU_EXACTFIT|wx.BORDER_SIMPLE)
362 self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
363 btn.SetToolTipString("Frame image with a dimmed background")
364 hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
365
366
367 def SetValue(self, file_nm): # display the selected file in the panel
368 self.view.SetValue(file_nm)
369
370 def SetBackgroundMode(self, mode):
371 self.view.SetBackgroundMode(mode)
372
373 def SetBorderMode(self, mode):
374 self.view.SetBorderMode(mode)
375
376 def OnSetImgBackground(self, event):
377 mode = event.GetId()
378 self.SetBackgroundMode(mode)
379
380 def OnSetBorderMode(self, event):
381 mode = event.GetId()
382 self.SetBorderMode(mode)
383
384
385
386class ImageDialog(wx.Dialog):
387 def __init__(self, parent, set_dir = None):
388 wx.Dialog.__init__(self, parent, -1, "Image Browser", wx.DefaultPosition, (400, 400),style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
d14a1e28
RD
389
390 self.set_dir = os.getcwd()
391 self.set_file = None
392
393 if set_dir != None:
394 if os.path.exists(set_dir): # set to working directory if nothing set
395 self.set_dir = set_dir
396
fe45b493
RD
397 vbox_top = wx.BoxSizer(wx.VERTICAL)
398 self.SetSizer(vbox_top)
399
400 hbox_loc = wx.BoxSizer(wx.HORIZONTAL)
401 vbox_top.Add(hbox_loc, 0, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 0)
d14a1e28 402
fe45b493
RD
403 loc_label = wx.StaticText( self, -1, "Folder:")
404 hbox_loc.Add(loc_label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ADJUST_MINSIZE, 5)
d14a1e28 405
fe45b493
RD
406 self.dir = wx.TextCtrl( self, -1, self.set_dir, style=wx.TE_RICH|wx.TE_PROCESS_ENTER)
407 self.Bind(wx.EVT_TEXT_ENTER, self.OnDirectoryTextSet, self.dir)
408 hbox_loc.Add(self.dir, 1, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 5)
d14a1e28 409
fe45b493
RD
410 up_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_DIR_UP, wx.ART_BUTTON, (16,16))
411 btn = wx.BitmapButton(self, -1, up_bmp)
412 btn.SetHelpText("Up one level")
413 btn.SetToolTipString("Up one level")
414 self.Bind(wx.EVT_BUTTON, self.OnUpDirectory, btn)
415 hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 2)
416
417 folder_bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_BUTTON, (16,16))
418 btn = wx.BitmapButton(self, -1, folder_bmp)
419 btn.SetHelpText("Browse for a &folder...")
420 btn.SetToolTipString("Browse for a folder...")
421 self.Bind(wx.EVT_BUTTON, self.OnChooseDirectory, btn)
422 hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5)
423
424 hbox_nav = wx.BoxSizer(wx.HORIZONTAL)
425 vbox_top.Add(hbox_nav, 0, wx.ALIGN_LEFT|wx.ALL, 0)
426
427
428 label = wx.StaticText( self, -1, "Files of type:")
429 hbox_nav.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
d14a1e28
RD
430
431 self.fl_ext = '*.bmp' # initial setting for file filtering
432 self.GetFiles() # get the file list
433
fe45b493
RD
434 self.fl_ext_types = (
435 # display, filter
436 ("All supported formats", "All"),
437 ("BMP (*.bmp)", "*.bmp"),
438 ("GIF (*.gif)", "*.gif"),
439 ("PNG (*.png)", "*.png"),
440 ("JPEG (*.jpg)", "*.jpg"),
441 ("ICO (*.ico)", "*.ico"),
442 ("PNM (*.pnm)", "*.pnm"),
443 ("PCX (*.pcx)", "*.pcx"),
444 ("TIFF (*.tif)", "*.tif"),
445 ("All Files", "*.*"),
446 )
447 self.set_type,self.fl_ext = self.fl_ext_types[0] # initial file filter setting
448 self.fl_types = [ x[0] for x in self.fl_ext_types ]
449 self.sel_type = wx.ComboBox( self, -1, self.set_type,
450 wx.DefaultPosition, wx.DefaultSize, self.fl_types,
451 wx.CB_DROPDOWN )
452 # after this we don't care about the order any more
453 self.fl_ext_types = dict(self.fl_ext_types)
454
455 self.Bind(wx.EVT_COMBOBOX, self.OnSetType, self.sel_type)
456 hbox_nav.Add(self.sel_type, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
457
458 splitter = wx.SplitterWindow( self, -1, wx.DefaultPosition, wx.Size(100, 100), 0 )
459 splitter.SetMinimumPaneSize(100)
460
461 split_left = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
462 wx.NO_BORDER|wx.TAB_TRAVERSAL )
463 vbox_left = wx.BoxSizer(wx.VERTICAL)
464 split_left.SetSizer(vbox_left)
d14a1e28 465
fe45b493
RD
466
467 self.tb = tb = wx.ListBox( split_left, -1, wx.DefaultPosition, wx.DefaultSize,
468 self.fl_list, wx.LB_SINGLE )
b881fc78
RD
469 self.Bind(wx.EVT_LISTBOX, self.OnListClick, tb)
470 self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDClick, tb)
fe45b493 471 vbox_left.Add(self.tb, 1, wx.GROW|wx.ALL, 0)
d14a1e28 472
b881fc78 473 width, height = self.tb.GetSize()
d14a1e28 474
fe45b493
RD
475 split_right = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
476 wx.NO_BORDER|wx.TAB_TRAVERSAL )
477 vbox_right = wx.BoxSizer(wx.VERTICAL)
478 split_right.SetSizer(vbox_right)
d14a1e28 479
fe45b493
RD
480 self.image_view = ImagePanel( split_right )
481 vbox_right.Add(self.image_view, 1, wx.GROW|wx.ALL, 0)
d14a1e28 482
fe45b493
RD
483 splitter.SplitVertically(split_left, split_right, 150)
484 vbox_top.Add(splitter, 1, wx.GROW|wx.ALL, 5)
d14a1e28 485
fe45b493
RD
486 hbox_btns = wx.BoxSizer(wx.HORIZONTAL)
487 vbox_top.Add(hbox_btns, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
d14a1e28 488
fe45b493
RD
489 ok_btn = wx.Button( self, wx.ID_OPEN, "", wx.DefaultPosition, wx.DefaultSize, 0 )
490 self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn)
491 #ok_btn.SetDefault()
492 hbox_btns.Add(ok_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
493
494 cancel_btn = wx.Button( self, wx.ID_CANCEL, "",
495 wx.DefaultPosition, wx.DefaultSize, 0 )
496 hbox_btns.Add(cancel_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
d14a1e28
RD
497
498 self.ResetFiles()
499
fe45b493 500
d14a1e28
RD
501 def GetFiles(self): # get the file list using directory and extension values
502 if self.fl_ext == "All":
503 all_files = []
b881fc78 504
d14a1e28
RD
505 for ftypes in self.fl_types[1:-1]: # get list of all available image types
506 filter = self.fl_ext_types[ftypes]
b881fc78 507 #print "filter = ", filter
d14a1e28
RD
508 self.fl_val = FindFiles(self, self.set_dir, filter)
509 all_files = all_files + self.fl_val.files # add to list of files
b881fc78 510
d14a1e28
RD
511 self.fl_list = all_files
512 else:
513 self.fl_val = FindFiles(self, self.set_dir, self.fl_ext)
514 self.fl_list = self.fl_val.files
515
fe45b493 516
d14a1e28 517 self.fl_list.sort() # sort the file list
fe45b493
RD
518 # prepend the directories
519 self.fl_ndirs = len(self.fl_val.dirs)
520 self.fl_list = sorted(self.fl_val.dirs) + self.fl_list
d14a1e28
RD
521
522 def DisplayDir(self): # display the working directory
0c8f2860 523 if self.dir:
fe45b493
RD
524 ipt = self.dir.GetInsertionPoint()
525 self.dir.SetValue(self.set_dir)
526 self.dir.SetInsertionPoint(ipt)
d14a1e28
RD
527
528 def OnSetType(self, event):
529 val = event.GetString() # get file type value
530 self.fl_ext = self.fl_ext_types[val]
531 self.ResetFiles()
532
533 def OnListDClick(self, event):
fe45b493 534 self.OnOk('dclick')
d14a1e28
RD
535
536 def OnListClick(self, event):
537 val = event.GetSelection()
538 self.SetListValue(val)
539
540 def SetListValue(self, val):
541 file_nm = self.fl_list[val]
542 self.set_file = file_val = os.path.join(self.set_dir, file_nm)
fe45b493
RD
543 if val>=self.fl_ndirs:
544 self.image_view.SetValue(file_val)
545 else:
546 self.image_view.SetValue(None)
d14a1e28 547
fe45b493
RD
548 def OnDirectoryTextSet(self,event):
549 event.Skip()
550 path = event.GetString()
551 if os.path.isdir(path):
552 self.set_dir = path
553 self.ResetFiles()
554 return
555
556 if os.path.isfile(path):
557 dname,fname = os.path.split(path)
558 if os.path.isdir(dname):
559 self.ResetFiles()
560 # try to select fname in list
561 try:
562 idx = self.fl_list.index(fname)
563 self.tb.SetSelection(idx)
564 self.SetListValue(idx)
565 return
566 except ValueError:
567 pass
568
569 wx.Bell()
570
571 def OnUpDirectory(self, event):
572 sdir = os.path.split(self.set_dir)[0]
573 self.set_dir = sdir
574 self.ResetFiles()
575
576 def OnChooseDirectory(self, event): # set the new directory
b881fc78 577 dlg = wx.DirDialog(self)
d14a1e28 578 dlg.SetPath(self.set_dir)
b881fc78
RD
579
580 if dlg.ShowModal() == wx.ID_OK:
d14a1e28
RD
581 self.set_dir = dlg.GetPath()
582 self.ResetFiles()
b881fc78 583
d14a1e28
RD
584 dlg.Destroy()
585
586 def ResetFiles(self): # refresh the display with files and initial image
587 self.DisplayDir()
588 self.GetFiles()
b881fc78
RD
589
590 # Changed 12/8/03 jmg
591 #
592 # o Clear listbox first
593 # o THEN check to see if there are any valid files of the selected
594 # type,
595 # o THEN if we have any files to display, set the listbox up,
596 #
597 # OTHERWISE
598 #
599 # o Leave it cleared
600 # o Clear the image viewer.
601 #
602 # This avoids a nasty assert error.
603 #
604 self.tb.Clear()
605
606 if len(self.fl_list):
607 self.tb.Set(self.fl_list)
608
fe45b493
RD
609 for idir in xrange(self.fl_ndirs):
610 d = self.fl_list[idir]
611 # mark directories as 'True' with client data
612 self.tb.SetClientData(idir, True)
613 self.tb.SetString(idir,'['+d+']')
614
b881fc78
RD
615 try:
616 self.tb.SetSelection(0)
617 self.SetListValue(0)
618 except:
619 self.image_view.SetValue(None)
620 else:
d14a1e28
RD
621 self.image_view.SetValue(None)
622
623 def GetFile(self):
624 return self.set_file
625
626 def GetDirectory(self):
627 return self.set_dir
628
629 def OnCancel(self, event):
630 self.result = None
b881fc78 631 self.EndModal(wx.ID_CANCEL)
d14a1e28
RD
632
633 def OnOk(self, event):
fe45b493
RD
634 if os.path.isdir(self.set_file):
635 sdir = os.path.split(self.set_file)
636
637 #os.path.normapth?
638 if sdir and sdir[-1]=='..':
639 sdir = os.path.split(sdir[0])[0]
640 sdir = os.path.split(sdir)
641 self.set_dir = os.path.join(*sdir)
642 self.set_file = None
643 self.ResetFiles()
644 elif event != 'dclick':
645 self.result = self.set_file
646 self.EndModal(wx.ID_OK)
b881fc78 647
b881fc78 648
d14a1e28
RD
649
650class FindFiles:
fe45b493 651 def __init__(self, parent, dir, mask, with_dirs=True):
d14a1e28
RD
652 filelist = []
653 dirlist = [".."]
654 self.dir = dir
655 self.file = ""
656 mask = mask.upper()
657 pattern = self.MakeRegex(mask)
b881fc78 658
d14a1e28
RD
659 for i in os.listdir(dir):
660 if i == "." or i == "..":
661 continue
b881fc78 662
d14a1e28 663 path = os.path.join(dir, i)
fe45b493
RD
664
665 if os.path.isdir(path):
666 dirlist.append(i)
667 continue
668
d14a1e28
RD
669 path = path.upper()
670 value = i.upper()
671
672 if pattern.match(value) != None:
673 filelist.append(i)
674
fe45b493 675
04c4117b 676 self.files = filelist
fe45b493
RD
677 if with_dirs:
678 self.dirs = dirlist
d14a1e28
RD
679
680 def MakeRegex(self, pattern):
681 import re
682 f = "" # Set up a regex for file names
b881fc78 683
d14a1e28
RD
684 for ch in pattern:
685 if ch == "*":
686 f = f + ".*"
687 elif ch == ".":
688 f = f + "\."
689 elif ch == "?":
690 f = f + "."
691 else:
692 f = f + ch
b881fc78 693
d14a1e28
RD
694 return re.compile(f+'$')
695
696 def StripExt(self, file_nm):
697 fl_fld = os.path.splitext(file_nm)
698 fl_name = fl_fld[0]
699 ext = fl_fld[1]
700 return ext[1:]
fe45b493
RD
701
702
703#----------------------------------------------------------------------
704# This part of the file was generated by C:\Python25\Scripts\img2py
705# then edited slightly.
706
707import cStringIO, zlib
708
709
710IMG_CATALOG = {}
711
712class ImageClass: pass
713
714def getWhiteData():
715 return zlib.decompress(
716'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
717o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4*z\xba8\x86HLMNP`202\
7180\xf8\xf3\xff\xbf\xfc|.77\xb5$\x1f\xa9P\x979J\x8b\x18\x18N\\d\x16\t\xfd\xfc\
719\xce\x07\xa8\x98\xc1\xd3\xd5\xcfe\x9dSB\x13\x00\xcc1\x1b\xb3' )
720
721def getWhiteBitmap():
722 return wx.BitmapFromImage(getWhiteImage())
723
724def getWhiteImage():
725 stream = cStringIO.StringIO(getWhiteData())
726 return wx.ImageFromStream(stream)
727
728IMG_CATALOG['White'] = ImageClass()
729IMG_CATALOG['White'].getData = getWhiteData
730IMG_CATALOG['White'].getImage = getWhiteImage
731IMG_CATALOG['White'].getBitmap = getWhiteBitmap
732
733
734#----------------------------------------------------------------------
735def getGreyData():
736 return zlib.decompress(
737'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
738o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4*y\xba8\x86HLMNP`202\
7390\x98cY\xcc\xd6\xcf%,,\xac\x96\xe4#\x15\xea2Gi\x11\x03\xc3\xb6\xc7\xcc":A7%\
740\x80\xaa\x19<]\xfd\\\xd69%4\x01\x00{m\x18s' )
741
742def getGreyBitmap():
743 return wx.BitmapFromImage(getGreyImage())
744
745def getGreyImage():
746 stream = cStringIO.StringIO(getGreyData())
747 return wx.ImageFromStream(stream)
748
749IMG_CATALOG['Grey'] = ImageClass()
750IMG_CATALOG['Grey'].getData = getGreyData
751IMG_CATALOG['Grey'].getImage = getGreyImage
752IMG_CATALOG['Grey'].getBitmap = getGreyBitmap
753
754
755#----------------------------------------------------------------------
756def getBlackData():
757 return zlib.decompress(
758'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
759o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\xf2y\xba8\x86HLMN\
760\x90`u\x16e``\xdc\xc3\xc0h\\3\xdb\x0c(\xc3\xe0\xe9\xea\xe7\xb2\xce)\xa1\t\
761\x00\xb6`\x12\x08' )
762
763def getBlackBitmap():
764 return wx.BitmapFromImage(getBlackImage())
765
766def getBlackImage():
767 stream = cStringIO.StringIO(getBlackData())
768 return wx.ImageFromStream(stream)
769
770IMG_CATALOG['Black'] = ImageClass()
771IMG_CATALOG['Black'].getData = getBlackData
772IMG_CATALOG['Black'].getImage = getBlackImage
773IMG_CATALOG['Black'].getBitmap = getBlackBitmap
774
775
776#----------------------------------------------------------------------
777def getCheckedData():
778 return zlib.decompress(
779'x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
780o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\x1az\xba8\x86HLMNP`\
7812020\x98cY\xcc\x16y\xe2\xc6\r\tWVeeaC\xb5\x8b\x91\x82\xdc\xccm\xde\xe7\xe7\
782\xd9Zo\xc8S\xf2\x12\x0cd`\xd0\xd8\xc5&\xf6\xeb\xd5\xe5t\xa0f\x06OW?\x97uN\tM\
783\x00qL\x1f\x94' )
784
785def getCheckedBitmap():
786 return wx.BitmapFromImage(getCheckedImage())
787
788def getCheckedImage():
789 stream = cStringIO.StringIO(getCheckedData())
790 return wx.ImageFromStream(stream)
791
792IMG_CATALOG['Checked'] = ImageClass()
793IMG_CATALOG['Checked'].getData = getCheckedData
794IMG_CATALOG['Checked'].getImage = getCheckedImage
795IMG_CATALOG['Checked'].getBitmap = getCheckedBitmap
796
797
798#----------------------------------------------------------------------
799def getNoFrameData():
800 return zlib.decompress(
801"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
802o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4\x9ay\xba8\x86HL]\
803\xdb\xef\xc8\xc5\xa0 \xc04\xf7\xc5\xff\xf8m\xd1\x01.\xba\x93\x9e'\x86\xac\
804\x14P\xb9\xb9O\xf0\x82\xd62\x0e\xa6\x06\xf9e\x8f;Yg\xc5F'\xd7g]\xf2\xadd;=\
805\x87S\xfe\xf3\xc7\x15\x8f\x80&0x\xba\xfa\xb9\xacsJh\x02\x00\x07\xac't" )
806
807def getNoFrameBitmap():
808 return wx.BitmapFromImage(getNoFrameImage())
809
810def getNoFrameImage():
811 stream = cStringIO.StringIO(getNoFrameData())
812 return wx.ImageFromStream(stream)
813
814IMG_CATALOG['NoFrame'] = ImageClass()
815IMG_CATALOG['NoFrame'].getData = getNoFrameData
816IMG_CATALOG['NoFrame'].getImage = getNoFrameImage
817IMG_CATALOG['NoFrame'].getBitmap = getNoFrameBitmap
818
819
820#----------------------------------------------------------------------
821def getBoxFrameData():
822 return zlib.decompress(
823"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
824o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4:{\xba8\x86HL\x9d\
825\xdbw\x91\x8bA\x81\x83\xb9\xfc\xd2\xff\xff\x9bl9\x02\x15\xd5\xdefnJ\xf6\xcb\
826\xe2\xf0|\x17'\x980W\xed\xaa\xaf\xe0\xcd:\xfd\xaa\xef\xec!/\xda.]ggaH\xfcT\
827\xbaRI\xca_\xef\xe6\x97\xf5\x9c;\xa2\x15\xfe\xbe^S\xbe\th\x1c\x83\xa7\xab\
828\x9f\xcb:\xa7\x84&\x00k\xdd.\x08" )
829
830def getBoxFrameBitmap():
831 return wx.BitmapFromImage(getBoxFrameImage())
832
833def getBoxFrameImage():
834 stream = cStringIO.StringIO(getBoxFrameData())
835 return wx.ImageFromStream(stream)
836
837IMG_CATALOG['BoxFrame'] = ImageClass()
838IMG_CATALOG['BoxFrame'].getData = getBoxFrameData
839IMG_CATALOG['BoxFrame'].getImage = getBoxFrameImage
840IMG_CATALOG['BoxFrame'].getBitmap = getBoxFrameBitmap
841
842
843#----------------------------------------------------------------------
844def getCropFrameData():
845 return zlib.decompress(
846"x\xda\xeb\x0c\xf0s\xe7\xe5\x92\xe2b``\xe0\xf5\xf4p\t\x02\xd2< \xcc\xc1\x04$\
847o\x8a\x9f\xde\x00\xa4\x98\x8b\x9d<C888n?\xf4\x7f\x00\xe4zz\xba8\x86HL\xdd;\
848\xc1\x90\xeb\x80\x03\x07K\xba\xf3\xbf\xd5\xfe\x17\xc5g;\xedh\x16i\xcf\xdc\
849\xd4z\xc2\xa8G\x81GIA\x89\xafew\xbc\xf0e\x8e]\xd7\xd3\xd2\x1aT\x16\xacj8\xf3\
850'\xa1\xca\xf9\xad\x85\xe3\xa4_1\xe7\xef~~\xcd\xedV\xc9\xf0\x7f#\xbftm\xb5\
851\x8d\t\x03\xc8TW?\x97uN\tM\x00\x9c@0\x82" )
852
853def getCropFrameBitmap():
854 return wx.BitmapFromImage(getCropFrameImage())
855
856def getCropFrameImage():
857 stream = cStringIO.StringIO(getCropFrameData())
858 return wx.ImageFromStream(stream)
859
860IMG_CATALOG['CropFrame'] = ImageClass()
861IMG_CATALOG['CropFrame'].getData = getCropFrameData
862IMG_CATALOG['CropFrame'].getImage = getCropFrameImage
863IMG_CATALOG['CropFrame'].getBitmap = getCropFrameBitmap