~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/wx/lib/imagebrowser.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#----------------------------------------------------------------------------
 
2
# Name:         BrowseImage.py
 
3
# Purpose:      Display and Select Image Files
 
4
#
 
5
# Original Author:       Lorne White
 
6
#
 
7
# Version:      2.0
 
8
# Date:         June 16, 2007
 
9
# Licence:      wxWindows license
 
10
#----------------------------------------------------------------------------
 
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
 
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
 
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
#
 
43
 
 
44
#---------------------------------------------------------------------------
 
45
 
 
46
import  os
 
47
import  sys
 
48
import  wx
 
49
 
 
50
#---------------------------------------------------------------------------
 
51
 
 
52
BAD_IMAGE = -1
 
53
ID_WHITE_BG = wx.NewId()
 
54
ID_BLACK_BG = wx.NewId()
 
55
ID_GREY_BG = wx.NewId()
 
56
ID_CHECK_BG = wx.NewId()
 
57
ID_NO_FRAME = wx.NewId()
 
58
ID_BOX_FRAME = wx.NewId()
 
59
ID_CROP_FRAME = wx.NewId()
 
60
 
 
61
def 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()
 
68
 
 
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
 
 
78
 
 
79
def GetCheckeredBitmap(blocksize=8,ntiles=4,rgb0='\xFF', rgb1='\xCC'):
 
80
    """Creates a square RGB checkered bitmap using the two specified colors.
 
81
 
 
82
    Inputs:
 
83
    
 
84
    - blocksize:  the number of pixels in each solid color square
 
85
    - ntiles:  the number of tiles along width and height.  Each tile is 2x2 blocks.
 
86
    - rbg0, rgb1:  the first and second colors, as 3-byte strings.
 
87
      If only 1 byte is provided, it is treated as a grey value.
 
88
 
 
89
    The bitmap returned will have width = height = blocksize*ntiles*2
 
90
    """
 
91
    size = blocksize*ntiles*2
 
92
 
 
93
    if len(rgb0)==1:
 
94
        rgb0 = rgb0 * 3
 
95
    if len(rgb1)==1:
 
96
        rgb1 = rgb1 * 3
 
97
 
 
98
    strip0 = (rgb0*blocksize + rgb1*blocksize)*(ntiles*blocksize)
 
99
    strip1 = (rgb1*blocksize + rgb0*blocksize)*(ntiles*blocksize)
 
100
    band = strip0 + strip1
 
101
    data = band * ntiles
 
102
    return wx.BitmapFromBuffer(size, size, data)
 
103
 
 
104
def GetNamedBitmap(name):
 
105
    return IMG_CATALOG[name].getBitmap()
 
106
 
 
107
 
 
108
class ImageView(wx.Window):
 
109
    def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, 
 
110
                 style=wx.BORDER_SUNKEN
 
111
                 ):
 
112
        wx.Window.__init__(self, parent, id, pos, size, style=style)
 
113
        
 
114
        self.image = None
 
115
 
 
116
        self.check_bmp = None
 
117
        self.check_dim_bmp = None
 
118
 
 
119
        # dark_bg is the brush/bitmap to use for painting in the whole background
 
120
        # lite_bg is the brush/bitmap/pen to use for painting the image rectangle
 
121
        self.dark_bg = None
 
122
        self.lite_bg = None
 
123
 
 
124
        self.border_mode = ID_CROP_FRAME
 
125
        self.SetBackgroundMode( ID_WHITE_BG )
 
126
        self.SetBorderMode( ID_NO_FRAME )
 
127
 
 
128
        # Changed API of wx uses tuples for size and pos now.
 
129
        self.Bind(wx.EVT_PAINT, self.OnPaint)
 
130
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
 
131
        self.Bind(wx.EVT_SIZE, self.OnSize)
 
132
 
 
133
 
 
134
    def SetValue(self, file_nm):    # display the selected file in the panel
 
135
        image = ConvertBMP(file_nm)
 
136
        self.image = image
 
137
        self.Refresh()
 
138
    
 
139
    def SetBackgroundMode(self, mode):
 
140
        self.bg_mode = mode
 
141
        self._updateBGInfo()
 
142
 
 
143
    def _updateBGInfo(self):
 
144
        bg = self.bg_mode
 
145
        border = self.border_mode
 
146
 
 
147
        self.dark_bg = None
 
148
        self.lite_bg = None
 
149
 
 
150
        if border == ID_BOX_FRAME:
 
151
            self.lite_bg = wx.BLACK_PEN
 
152
 
 
153
        if bg == ID_WHITE_BG:
 
154
            if border == ID_CROP_FRAME:
 
155
                self.SetBackgroundColour('LIGHT GREY')
 
156
                self.lite_bg = wx.WHITE_BRUSH
 
157
            else:
 
158
                self.SetBackgroundColour('WHITE')
 
159
 
 
160
        elif bg == ID_GREY_BG:
 
161
            if border == ID_CROP_FRAME:
 
162
                self.SetBackgroundColour('GREY')
 
163
                self.lite_bg = wx.LIGHT_GREY_BRUSH
 
164
            else:
 
165
                self.SetBackgroundColour('LIGHT GREY')
 
166
 
 
167
        elif bg == ID_BLACK_BG:
 
168
            if border == ID_BOX_FRAME:
 
169
                self.lite_bg = wx.WHITE_PEN
 
170
            if border == ID_CROP_FRAME:
 
171
                self.SetBackgroundColour('GREY')
 
172
                self.lite_bg = wx.BLACK_BRUSH
 
173
            else:
 
174
                self.SetBackgroundColour('BLACK')
 
175
 
 
176
        else:
 
177
            if self.check_bmp is None:
 
178
                self.check_bmp = GetCheckeredBitmap()
 
179
                self.check_dim_bmp = GetCheckeredBitmap(rgb0='\x7F', rgb1='\x66')
 
180
            if border == ID_CROP_FRAME:
 
181
                self.dark_bg = self.check_dim_bmp
 
182
                self.lite_bg = self.check_bmp
 
183
            else:
 
184
                self.dark_bg = self.check_bmp
 
185
 
 
186
        self.Refresh()
 
187
 
 
188
    def SetBorderMode(self, mode):
 
189
        self.border_mode = mode
 
190
        self._updateBGInfo()
 
191
 
 
192
    def OnSize(self, event):
 
193
        event.Skip()
 
194
        self.Refresh()
 
195
 
 
196
    def OnPaint(self, event):
 
197
        dc = wx.PaintDC(self)
 
198
        self.DrawImage(dc)
 
199
 
 
200
    def OnEraseBackground(self, evt):
 
201
        if self.bg_mode != ID_CHECK_BG:
 
202
            evt.Skip()
 
203
            return
 
204
        dc = evt.GetDC()
 
205
        if dc:
 
206
            self.PaintBackground(dc, self.dark_bg)
 
207
 
 
208
    def PaintBackground(self, dc, painter, rect=None):
 
209
        if painter is None:
 
210
            return
 
211
        if rect is None:
 
212
            pos = self.GetPosition()
 
213
            sz = self.GetSize()
 
214
        else:
 
215
            pos = rect.Position
 
216
            sz = rect.Size
 
217
 
 
218
        if type(painter)==wx.Brush:
 
219
            dc.SetPen(wx.TRANSPARENT_PEN)
 
220
            dc.SetBrush(painter)
 
221
            dc.DrawRectangle(pos.x,pos.y,sz.width,sz.height)
 
222
        elif type(painter)==wx.Pen:
 
223
            dc.SetPen(painter)
 
224
            dc.SetBrush(wx.TRANSPARENT_BRUSH)
 
225
            dc.DrawRectangle(pos.x-1,pos.y-1,sz.width+2,sz.height+2)
 
226
        else:
 
227
            self.TileBackground(dc, painter, pos.x,pos.y,sz.width,sz.height)
 
228
        
 
229
 
 
230
    def TileBackground(self, dc, bmp, x,y,w,h):
 
231
        """Tile bmp into the specified rectangle"""
 
232
        bw = bmp.GetWidth()
 
233
        bh = bmp.GetHeight()
 
234
 
 
235
        dc.SetClippingRegion(x,y,w,h)
 
236
 
 
237
        # adjust so 0,0 so we always match with a tiling starting at 0,0
 
238
        dx = x % bw
 
239
        x = x - dx
 
240
        w = w + dx
 
241
 
 
242
        dy = y % bh
 
243
        y = y - dy
 
244
        h = h + dy
 
245
 
 
246
        tx = x
 
247
        x2 = x+w
 
248
        y2 = y+h
 
249
 
 
250
        while tx < x2:
 
251
            ty = y
 
252
            while ty < y2:
 
253
                dc.DrawBitmap(bmp, tx, ty)
 
254
                ty += bh
 
255
            tx += bw
 
256
 
 
257
    def DrawImage(self, dc):
 
258
 
 
259
        if not hasattr(self,'image') or self.image is None:
 
260
            return
 
261
 
 
262
        wwidth,wheight = self.GetSize() 
 
263
        image = self.image
 
264
        bmp = None
 
265
        if image != BAD_IMAGE and image.IsOk():
 
266
            iwidth = image.GetWidth()   # dimensions of image file
 
267
            iheight = image.GetHeight()
 
268
        else:
 
269
            bmp = wx.ArtProvider.GetBitmap(wx.ART_MISSING_IMAGE, wx.ART_MESSAGE_BOX, (64,64))
 
270
            iwidth = bmp.GetWidth()
 
271
            iheight = bmp.GetHeight()
 
272
 
 
273
        # squeeze iwidth x iheight image into window, preserving aspect ratio
 
274
 
 
275
        xfactor = float(wwidth) / iwidth
 
276
        yfactor = float(wheight) / iheight
 
277
 
 
278
        if xfactor < 1.0 and xfactor < yfactor:
 
279
            scale = xfactor
 
280
        elif yfactor < 1.0 and yfactor < xfactor:
 
281
            scale = yfactor
 
282
        else:
 
283
            scale = 1.0
 
284
 
 
285
        owidth = int(scale*iwidth)
 
286
        oheight = int(scale*iheight)
 
287
 
 
288
        diffx = (wwidth - owidth)/2   # center calc
 
289
        diffy = (wheight - oheight)/2   # center calc
 
290
 
 
291
        if not bmp:
 
292
            if owidth!=iwidth or oheight!=iheight:
 
293
                sc_image = sc_image = image.Scale(owidth,oheight)
 
294
            else:
 
295
                sc_image = image
 
296
            bmp = sc_image.ConvertToBitmap()
 
297
 
 
298
        if image != BAD_IMAGE and image.IsOk():
 
299
            self.PaintBackground(dc, self.lite_bg, wx.Rect(diffx,diffy,owidth,oheight))
 
300
 
 
301
        dc.DrawBitmap(bmp, diffx, diffy, useMask=True)        # draw the image to window
 
302
 
 
303
 
 
304
class ImagePanel(wx.Panel):
 
305
    def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, 
 
306
                 style=wx.NO_BORDER
 
307
                 ):
 
308
        wx.Panel.__init__(self, parent, id, pos, size, style=style)
 
309
 
 
310
        vbox = wx.BoxSizer(wx.VERTICAL)
 
311
        self.SetSizer(vbox)
 
312
 
 
313
        self.view = ImageView(self)
 
314
        vbox.Add(self.view, 1, wx.GROW|wx.ALL, 0)
 
315
 
 
316
        hbox_ctrls = wx.BoxSizer(wx.HORIZONTAL)
 
317
        vbox.Add(hbox_ctrls, 0, wx.ALIGN_RIGHT|wx.TOP, 4)
 
318
 
 
319
        bmp = GetNamedBitmap('White')
 
320
        btn = wx.BitmapButton(self, ID_WHITE_BG, bmp, style=wx.BU_EXACTFIT)
 
321
        self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
 
322
        btn.SetToolTipString("Set background to white")
 
323
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
324
 
 
325
        bmp = GetNamedBitmap('Grey')
 
326
        btn = wx.BitmapButton(self, ID_GREY_BG, bmp, style=wx.BU_EXACTFIT)
 
327
        self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
 
328
        btn.SetToolTipString("Set background to grey")
 
329
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
330
 
 
331
        bmp = GetNamedBitmap('Black')
 
332
        btn = wx.BitmapButton(self, ID_BLACK_BG, bmp, style=wx.BU_EXACTFIT)
 
333
        self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
 
334
        btn.SetToolTipString("Set background to black")
 
335
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
336
 
 
337
        bmp = GetNamedBitmap('Checked')
 
338
        btn = wx.BitmapButton(self, ID_CHECK_BG, bmp, style=wx.BU_EXACTFIT)
 
339
        self.Bind(wx.EVT_BUTTON, self.OnSetImgBackground, btn)
 
340
        btn.SetToolTipString("Set background to chekered pattern")
 
341
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
342
 
 
343
 
 
344
        hbox_ctrls.AddSpacer(7)
 
345
 
 
346
        bmp = GetNamedBitmap('NoFrame')
 
347
        btn = wx.BitmapButton(self, ID_NO_FRAME, bmp, style=wx.BU_EXACTFIT)
 
348
        self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
 
349
        btn.SetToolTipString("No framing around image")
 
350
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
351
        
 
352
        bmp = GetNamedBitmap('BoxFrame')
 
353
        btn = wx.BitmapButton(self, ID_BOX_FRAME, bmp, style=wx.BU_EXACTFIT)
 
354
        self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
 
355
        btn.SetToolTipString("Frame image with a box")
 
356
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
357
 
 
358
        bmp = GetNamedBitmap('CropFrame')
 
359
        btn = wx.BitmapButton(self, ID_CROP_FRAME, bmp, style=wx.BU_EXACTFIT|wx.BORDER_SIMPLE)
 
360
        self.Bind(wx.EVT_BUTTON, self.OnSetBorderMode, btn)
 
361
        btn.SetToolTipString("Frame image with a dimmed background")
 
362
        hbox_ctrls.Add(btn, 0, wx.ALIGN_LEFT|wx.LEFT, 4)
 
363
 
 
364
 
 
365
    def SetValue(self, file_nm):    # display the selected file in the panel
 
366
        self.view.SetValue(file_nm)
 
367
 
 
368
    def SetBackgroundMode(self, mode):
 
369
        self.view.SetBackgroundMode(mode)
 
370
 
 
371
    def SetBorderMode(self, mode):
 
372
        self.view.SetBorderMode(mode)
 
373
 
 
374
    def OnSetImgBackground(self, event):
 
375
        mode = event.GetId()
 
376
        self.SetBackgroundMode(mode)
 
377
 
 
378
    def OnSetBorderMode(self, event):
 
379
        mode = event.GetId()
 
380
        self.SetBorderMode(mode)
 
381
 
 
382
 
 
383
 
 
384
class ImageDialog(wx.Dialog):
 
385
    def __init__(self, parent, set_dir = None):
 
386
        wx.Dialog.__init__(self, parent, -1, "Image Browser", wx.DefaultPosition, (400, 400),style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
 
387
 
 
388
        self.set_dir = os.getcwd()
 
389
        self.set_file = None
 
390
 
 
391
        if set_dir != None:
 
392
            if os.path.exists(set_dir):     # set to working directory if nothing set
 
393
                self.set_dir = set_dir
 
394
 
 
395
        vbox_top = wx.BoxSizer(wx.VERTICAL)
 
396
        self.SetSizer(vbox_top)
 
397
 
 
398
        hbox_loc = wx.BoxSizer(wx.HORIZONTAL)
 
399
        vbox_top.Add(hbox_loc, 0, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 0)
 
400
 
 
401
        loc_label = wx.StaticText( self, -1, "Folder:")
 
402
        hbox_loc.Add(loc_label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL|wx.ADJUST_MINSIZE, 5)
 
403
 
 
404
        self.dir = wx.TextCtrl( self, -1, self.set_dir, style=wx.TE_RICH|wx.TE_PROCESS_ENTER)
 
405
        self.Bind(wx.EVT_TEXT_ENTER, self.OnDirectoryTextSet, self.dir)
 
406
        hbox_loc.Add(self.dir, 1, wx.GROW|wx.ALIGN_LEFT|wx.ALL, 5)
 
407
 
 
408
        up_bmp = wx.ArtProvider.GetBitmap(wx.ART_GO_DIR_UP, wx.ART_BUTTON, (16,16))
 
409
        btn = wx.BitmapButton(self, -1, up_bmp)
 
410
        btn.SetHelpText("Up one level")
 
411
        btn.SetToolTipString("Up one level")
 
412
        self.Bind(wx.EVT_BUTTON, self.OnUpDirectory, btn)
 
413
        hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 2)
 
414
 
 
415
        folder_bmp = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_BUTTON, (16,16))
 
416
        btn = wx.BitmapButton(self, -1, folder_bmp)
 
417
        btn.SetHelpText("Browse for a &folder...")
 
418
        btn.SetToolTipString("Browse for a folder...")
 
419
        self.Bind(wx.EVT_BUTTON, self.OnChooseDirectory, btn)
 
420
        hbox_loc.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 5)
 
421
 
 
422
        hbox_nav = wx.BoxSizer(wx.HORIZONTAL)
 
423
        vbox_top.Add(hbox_nav, 0, wx.ALIGN_LEFT|wx.ALL, 0)
 
424
 
 
425
 
 
426
        label = wx.StaticText( self, -1, "Files of type:")
 
427
        hbox_nav.Add(label, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 5)
 
428
 
 
429
        self.fl_ext = '*.bmp'   # initial setting for file filtering
 
430
        self.GetFiles()     # get the file list
 
431
 
 
432
        self.fl_ext_types = (
 
433
            # display, filter
 
434
            ("All supported formats", "All"),
 
435
            ("BMP (*.bmp)", "*.bmp"),
 
436
            ("GIF (*.gif)", "*.gif"),
 
437
            ("PNG (*.png)", "*.png"),
 
438
            ("JPEG (*.jpg)", "*.jpg"),
 
439
            ("ICO (*.ico)", "*.ico"),
 
440
            ("PNM (*.pnm)", "*.pnm"),
 
441
            ("PCX (*.pcx)", "*.pcx"),
 
442
            ("TIFF (*.tif)", "*.tif"),
 
443
            ("All Files", "*.*"),
 
444
            )
 
445
        self.set_type,self.fl_ext = self.fl_ext_types[0]  # initial file filter setting
 
446
        self.fl_types = [ x[0] for x in self.fl_ext_types ]
 
447
        self.sel_type = wx.ComboBox( self, -1, self.set_type,
 
448
                                     wx.DefaultPosition, wx.DefaultSize, self.fl_types, 
 
449
                                     wx.CB_DROPDOWN )
 
450
        # after this we don't care about the order any more
 
451
        self.fl_ext_types = dict(self.fl_ext_types)
 
452
 
 
453
        self.Bind(wx.EVT_COMBOBOX, self.OnSetType, self.sel_type)
 
454
        hbox_nav.Add(self.sel_type, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
 
455
 
 
456
        splitter = wx.SplitterWindow( self, -1, wx.DefaultPosition, wx.Size(100, 100), 0 )
 
457
        splitter.SetMinimumPaneSize(100)
 
458
 
 
459
        split_left = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize, 
 
460
                               wx.NO_BORDER|wx.TAB_TRAVERSAL )
 
461
        vbox_left = wx.BoxSizer(wx.VERTICAL)
 
462
        split_left.SetSizer(vbox_left)
 
463
 
 
464
 
 
465
        self.tb = tb = wx.ListBox( split_left, -1, wx.DefaultPosition, wx.DefaultSize,
 
466
                                   self.fl_list, wx.LB_SINGLE )
 
467
        self.Bind(wx.EVT_LISTBOX, self.OnListClick, tb)
 
468
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDClick, tb)
 
469
        vbox_left.Add(self.tb, 1, wx.GROW|wx.ALL, 0)
 
470
 
 
471
        width, height = self.tb.GetSize()
 
472
 
 
473
        split_right = wx.Panel( splitter, -1, wx.DefaultPosition, wx.DefaultSize,
 
474
                                wx.NO_BORDER|wx.TAB_TRAVERSAL )
 
475
        vbox_right = wx.BoxSizer(wx.VERTICAL)
 
476
        split_right.SetSizer(vbox_right)
 
477
 
 
478
        self.image_view = ImagePanel( split_right )
 
479
        vbox_right.Add(self.image_view, 1, wx.GROW|wx.ALL, 0)
 
480
 
 
481
        splitter.SplitVertically(split_left, split_right, 150)
 
482
        vbox_top.Add(splitter, 1, wx.GROW|wx.ALL, 5)
 
483
 
 
484
        hbox_btns = wx.BoxSizer(wx.HORIZONTAL)
 
485
        vbox_top.Add(hbox_btns, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
 
486
 
 
487
        ok_btn = wx.Button( self, wx.ID_OPEN, "", wx.DefaultPosition, wx.DefaultSize, 0 )
 
488
        self.Bind(wx.EVT_BUTTON, self.OnOk, ok_btn)
 
489
        #ok_btn.SetDefault()
 
490
        hbox_btns.Add(ok_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
 
491
 
 
492
        cancel_btn = wx.Button( self, wx.ID_CANCEL, "", 
 
493
                                wx.DefaultPosition, wx.DefaultSize, 0 )
 
494
        hbox_btns.Add(cancel_btn, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
 
495
 
 
496
        self.ResetFiles()
 
497
 
 
498
    def ChangeFileTypes(self, ft_tuple):
 
499
        # Change list of file types to be supported
 
500
        self.fl_ext_types = ft_tuple
 
501
        self.set_type, self.fl_ext = self.fl_ext_types[0]  # initial file filter setting
 
502
        self.fl_types = [ x[0] for x in self.fl_ext_types ]
 
503
        self.sel_type.Clear()
 
504
        self.sel_type.AppendItems(self.fl_types)
 
505
        self.sel_type.SetSelection(0)
 
506
        self.fl_ext_types = dict(self.fl_ext_types)
 
507
 
 
508
    def GetFiles(self):     # get the file list using directory and extension values
 
509
        if self.fl_ext == "All":
 
510
            all_files = []
 
511
 
 
512
            if self.fl_types[-1] == 'All Files':
 
513
                allTypes = self.fl_types[-1:]
 
514
            else:
 
515
                allTypes = self.fl_types[1:]
 
516
            for ftypes in allTypes:    # get list of all
 
517
                filter = self.fl_ext_types[ftypes]
 
518
                #print "filter = ", filter
 
519
                self.fl_val = FindFiles(self, self.set_dir, filter)
 
520
                all_files = all_files + self.fl_val.files   # add to list of files
 
521
 
 
522
            self.fl_list = all_files
 
523
        else:
 
524
            self.fl_val = FindFiles(self, self.set_dir, self.fl_ext)
 
525
            self.fl_list = self.fl_val.files
 
526
 
 
527
 
 
528
        self.fl_list.sort()     # sort the file list
 
529
        # prepend the directories
 
530
        self.fl_ndirs = len(self.fl_val.dirs)
 
531
        self.fl_list = sorted(self.fl_val.dirs) + self.fl_list
 
532
 
 
533
    def DisplayDir(self):       # display the working directory
 
534
        if self.dir:
 
535
            ipt = self.dir.GetInsertionPoint()
 
536
            self.dir.SetValue(self.set_dir)
 
537
            self.dir.SetInsertionPoint(ipt)
 
538
 
 
539
    def OnSetType(self, event):
 
540
        val = event.GetString()      # get file type value
 
541
        self.fl_ext = self.fl_ext_types[val]
 
542
        self.ResetFiles()
 
543
 
 
544
    def OnListDClick(self, event):
 
545
        self.OnOk('dclick')
 
546
 
 
547
    def OnListClick(self, event):
 
548
        val = event.GetSelection()
 
549
        self.SetListValue(val)
 
550
 
 
551
    def SetListValue(self, val):
 
552
        file_nm = self.fl_list[val]
 
553
        self.set_file = file_val = os.path.join(self.set_dir, file_nm)
 
554
        if val>=self.fl_ndirs:
 
555
            self.image_view.SetValue(file_val)
 
556
        else:
 
557
            self.image_view.SetValue(None)
 
558
 
 
559
    def OnDirectoryTextSet(self,event):
 
560
        event.Skip()
 
561
        path = event.GetString()
 
562
        if os.path.isdir(path):
 
563
            self.set_dir = path
 
564
            self.ResetFiles()
 
565
            return
 
566
 
 
567
        if os.path.isfile(path):
 
568
            dname,fname = os.path.split(path)
 
569
            if os.path.isdir(dname):
 
570
                self.ResetFiles()
 
571
            # try to select fname in list
 
572
            try:
 
573
                idx = self.fl_list.index(fname)
 
574
                self.tb.SetSelection(idx)
 
575
                self.SetListValue(idx)
 
576
                return
 
577
            except ValueError:
 
578
                pass
 
579
 
 
580
        wx.Bell()
 
581
    
 
582
    def OnUpDirectory(self, event):
 
583
        sdir = os.path.split(self.set_dir)[0]
 
584
        self.set_dir = sdir
 
585
        self.ResetFiles()
 
586
        
 
587
    def OnChooseDirectory(self, event):     # set the new directory
 
588
        dlg = wx.DirDialog(self)
 
589
        dlg.SetPath(self.set_dir)
 
590
 
 
591
        if dlg.ShowModal() == wx.ID_OK:
 
592
            self.set_dir = dlg.GetPath()
 
593
            self.ResetFiles()
 
594
 
 
595
        dlg.Destroy()
 
596
 
 
597
    def ResetFiles(self):   # refresh the display with files and initial image
 
598
        self.DisplayDir()
 
599
        self.GetFiles()
 
600
 
 
601
        # Changed 12/8/03 jmg
 
602
        #
 
603
        # o Clear listbox first
 
604
        # o THEN check to see if there are any valid files of the selected
 
605
        #   type, 
 
606
        # o THEN if we have any files to display, set the listbox up,
 
607
        #
 
608
        # OTHERWISE
 
609
        #
 
610
        # o Leave it cleared
 
611
        # o Clear the image viewer.
 
612
        #
 
613
        # This avoids a nasty assert error.
 
614
        #
 
615
        self.tb.Clear()
 
616
        
 
617
        if len(self.fl_list):
 
618
            self.tb.Set(self.fl_list)
 
619
 
 
620
            for idir in xrange(self.fl_ndirs):
 
621
                d = self.fl_list[idir]
 
622
                # mark directories as 'True' with client data
 
623
                self.tb.SetClientData(idir, True)
 
624
                self.tb.SetString(idir,'['+d+']')
 
625
 
 
626
            try:
 
627
                self.tb.SetSelection(0)
 
628
                self.SetListValue(0)
 
629
            except:
 
630
                self.image_view.SetValue(None)
 
631
        else:
 
632
            self.image_view.SetValue(None)
 
633
 
 
634
    def GetFile(self):
 
635
        return self.set_file
 
636
 
 
637
    def GetDirectory(self):
 
638
        return self.set_dir
 
639
 
 
640
    def OnCancel(self, event):
 
641
        self.result = None
 
642
        self.EndModal(wx.ID_CANCEL)
 
643
 
 
644
    def OnOk(self, event):
 
645
        if os.path.isdir(self.set_file):
 
646
            sdir = os.path.split(self.set_file)
 
647
    
 
648
            #os.path.normapth?
 
649
            if sdir and sdir[-1]=='..':
 
650
                sdir = os.path.split(sdir[0])[0]
 
651
                sdir = os.path.split(sdir)
 
652
            self.set_dir = os.path.join(*sdir)
 
653
            self.set_file = None
 
654
            self.ResetFiles()
 
655
        elif event != 'dclick':
 
656
            self.result = self.set_file
 
657
            self.EndModal(wx.ID_OK)
 
658
 
 
659
 
 
660
 
 
661
class FindFiles:
 
662
    def __init__(self, parent, dir, mask, with_dirs=True):
 
663
        filelist = []
 
664
        dirlist = [".."]
 
665
        self.dir = dir
 
666
        self.file = ""
 
667
        mask = mask.upper()
 
668
        pattern = self.MakeRegex(mask)
 
669
 
 
670
        for i in os.listdir(dir):
 
671
            if i == "." or i == "..":
 
672
                continue
 
673
 
 
674
            path = os.path.join(dir, i)
 
675
 
 
676
            if os.path.isdir(path):
 
677
                dirlist.append(i)
 
678
                continue
 
679
 
 
680
            path = path.upper()
 
681
            value = i.upper()
 
682
 
 
683
            if pattern.match(value) != None:
 
684
                filelist.append(i)
 
685
 
 
686
 
 
687
        self.files = filelist
 
688
        if with_dirs:
 
689
            self.dirs = dirlist
 
690
 
 
691
    def MakeRegex(self, pattern):
 
692
        import re
 
693
        f = ""  # Set up a regex for file names
 
694
 
 
695
        for ch in pattern:
 
696
            if ch == "*":
 
697
                f = f + ".*"
 
698
            elif ch == ".":
 
699
                f = f + "\."
 
700
            elif ch == "?":
 
701
                f = f + "."
 
702
            else:
 
703
                f = f + ch
 
704
 
 
705
        return re.compile(f+'$')
 
706
 
 
707
    def StripExt(self, file_nm):
 
708
        fl_fld = os.path.splitext(file_nm)
 
709
        fl_name = fl_fld[0]
 
710
        ext = fl_fld[1]
 
711
        return ext[1:]
 
712
 
 
713
 
 
714
#----------------------------------------------------------------------
 
715
# This part of the file was generated by C:\Python25\Scripts\img2py
 
716
# then edited slightly.
 
717
 
 
718
from wx.lib.embeddedimage import PyEmbeddedImage
 
719
 
 
720
IMG_CATALOG = {}
 
721
 
 
722
IMG_CATALOG['White'] = PyEmbeddedImage(
 
723
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAIUlE"
 
724
    "QVQYlWNgIAIwMjAw/P//H58KRkYmYkwaVUScIqIAAMjRAxRV8+5MAAAAAElFTkSuQmCC")
 
725
 
 
726
IMG_CATALOG['Grey'] = PyEmbeddedImage(
 
727
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAIklE"
 
728
    "QVQYlWNgIAIwMjAwnDlzBo8KExMTJmJMGlVEnCKiAAC24wMULFLZGAAAAABJRU5ErkJggg==")
 
729
 
 
730
IMG_CATALOG['Black'] = PyEmbeddedImage(
 
731
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAADklE"
 
732
    "QVQYlWNgGAVDFQAAAbwAATN8mzYAAAAASUVORK5CYII=")
 
733
 
 
734
IMG_CATALOG['Checked'] = PyEmbeddedImage(
 
735
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAMUlE"
 
736
    "QVQYlWNgIAIwMjAwnDlzBlnI2NgYRQUjIxMxJtFZEQsDhkvPnj07sG4iShFRAAAougYW+urT"
 
737
    "ZwAAAABJRU5ErkJggg==")
 
738
 
 
739
IMG_CATALOG['NoFrame'] = PyEmbeddedImage(
 
740
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAANklE"
 
741
    "QVQYla2PQQoAIBACnej/X7ZbUEQtkudhVKkQJNm+EdAqpggCgB+m44kFml1bY39q0k15Bsuc"
 
742
    "CR/z8ajiAAAAAElFTkSuQmCC")
 
743
 
 
744
IMG_CATALOG['BoxFrame'] = PyEmbeddedImage(
 
745
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAAQ0lE"
 
746
    "QVQYlZ2O0QoAIAgDd9L//7I9CFEhJu1psmNOaghJ7l4RYJ0m1U0R2X4vevcHVOiG0tcHBABh"
 
747
    "8nWpIhpPLtn0rwm4WyD966x3sgAAAABJRU5ErkJggg==")
 
748
 
 
749
IMG_CATALOG['CropFrame'] = PyEmbeddedImage(
 
750
    "iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAA3NCSVQICAjb4U/gAAAASUlE"
 
751
    "QVQYlb2QMQrAQAgEZ0P+q0/RF5tCuIMUh2myhcgyjCAMIiAiDoS7XxPTCLrXZmaAJKCqgMz8"
 
752
    "YHpD7ThBkvpcz93z6wtGeQD/sQ8bfXs8NAAAAABJRU5ErkJggg==")
 
753