]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/lib/dialogs.py
920b659af4840de9e6e81ca71e4923c84d0e988f
[wxWidgets.git] / wxPython / wxPython / lib / dialogs.py
1 #----------------------------------------------------------------------
2 # Name: wxPython.lib.dialogs
3 # Purpose: wxScrolledMessageDialog, wxMultipleChoiceDialog and
4 # function wrappers for the common dialogs by Kevin Altis.
5 #
6 # Author: Various
7 #
8 # Created: 3-January-2002
9 # RCS-ID: $Id$
10 # Copyright: (c) 2002 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------
13
14 from wxPython import wx
15 from layoutf import Layoutf
16
17 #----------------------------------------------------------------------
18
19 class wxScrolledMessageDialog(wx.wxDialog):
20 def __init__(self, parent, msg, caption, pos = wx.wxDefaultPosition, size = (500,300)):
21 wx.wxDialog.__init__(self, parent, -1, caption, pos, size)
22 x, y = pos
23 if x == -1 and y == -1:
24 self.CenterOnScreen(wx.wxBOTH)
25 text = wx.wxTextCtrl(self, -1, msg, wx.wxDefaultPosition,
26 wx.wxDefaultSize,
27 wx.wxTE_MULTILINE | wx.wxTE_READONLY)
28 ok = wx.wxButton(self, wx.wxID_OK, "OK")
29 text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok)))
30 ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,)))
31 self.SetAutoLayout(1)
32 self.Layout()
33
34
35 class wxMultipleChoiceDialog(wx.wxDialog):
36 def __init__(self, parent, msg, title, lst, pos = wx.wxDefaultPosition, size = (200,200)):
37 wx.wxDialog.__init__(self, parent, -1, title, pos, size)
38 x, y = pos
39 if x == -1 and y == -1:
40 self.CenterOnScreen(wx.wxBOTH)
41 dc = wx.wxClientDC(self)
42 height = 0
43 for line in msg.splitlines():
44 height = height + dc.GetTextExtent(msg)[1] + 4
45 stat = wx.wxStaticText(self, -1, msg)
46 self.lbox = wx.wxListBox(self, 100, wx.wxDefaultPosition,
47 wx.wxDefaultSize, lst, wx.wxLB_MULTIPLE)
48 ok = wx.wxButton(self, wx.wxID_OK, "OK")
49 cancel = wx.wxButton(self, wx.wxID_CANCEL, "Cancel")
50 stat.SetConstraints(Layoutf('t=t10#1;l=l5#1;r=r5#1;h!%d' % (height,),
51 (self,)))
52 self.lbox.SetConstraints(Layoutf('t=b10#2;l=l5#1;r=r5#1;b=t5#3',
53 (self, stat, ok)))
54 ok.SetConstraints(Layoutf('b=b5#1;x%w25#1;w!80;h!25', (self,)))
55 cancel.SetConstraints(Layoutf('b=b5#1;x%w75#1;w!80;h!25', (self,)))
56 self.SetAutoLayout(1)
57 self.lst = lst
58 self.Layout()
59
60 def GetValue(self):
61 return self.lbox.GetSelections()
62
63 def GetValueString(self):
64 sel = self.lbox.GetSelections()
65 val = []
66 for i in sel:
67 val.append(self.lst[i])
68 return tuple(val)
69
70
71
72 #----------------------------------------------------------------------
73 """
74 function wrappers for wxPython system dialogs
75 Author: Kevin Altis
76 Date: 2003-1-2
77 Rev: 3
78
79 This is the third refactor of the PythonCard dialog.py module
80 for inclusion in the main wxPython distribution. There are a number of
81 design decisions and subsequent code refactoring to be done, so I'm
82 releasing this just to get some feedback.
83
84 rev 3:
85 - result dictionary replaced by DialogResults class instance
86 - should message arg be replaced with msg? most wxWindows dialogs
87 seem to use the abbreviation?
88
89 rev 2:
90 - All dialog classes have been replaced by function wrappers
91 - Changed arg lists to more closely match wxWindows docs and wxPython.lib.dialogs
92 - changed 'returned' value to the actual button id the user clicked on
93 - added a returnedString value for the string version of the return value
94 - reworked colorDialog and fontDialog so you can pass in just a color or font
95 for the most common usage case
96 - probably need to use colour instead of color to match the English English
97 spelling in wxWindows (sigh)
98 - I still think we could lose the parent arg and just always use None
99 """
100
101 class DialogResults:
102 def __init__(self, returned):
103 self.returned = returned
104 self.accepted = returned in (wx.wxID_OK, wx.wxID_YES)
105 self.returnedString = returnedString(returned)
106
107 def __repr__(self):
108 return str(self.__dict__)
109
110 def returnedString(ret):
111 if ret == wx.wxID_OK:
112 return "Ok"
113 elif ret == wx.wxID_CANCEL:
114 return "Cancel"
115 elif ret == wx.wxID_YES:
116 return "Yes"
117 elif ret == wx.wxID_NO:
118 return "No"
119
120
121 # findDialog was created before wxPython got a Find/Replace dialog
122 # but it may be instructive as to how a function wrapper can
123 # be added for your own custom dialogs
124 # this dialog is always modal, while wxFindReplaceDialog is
125 # modeless and so doesn't lend itself to a function wrapper
126 def findDialog(parent=None, searchText='', wholeWordsOnly=0, caseSensitive=0):
127 dlg = wx.wxDialog(parent, -1, "Find", wx.wxDefaultPosition, wx.wxSize(370, 120))
128
129 wx.wxStaticText(dlg, -1, 'Find what:', wx.wxPoint(7, 10))
130 wSearchText = wx.wxTextCtrl(dlg, -1, searchText,
131 wx.wxPoint(70, 7), wx.wxSize(195, -1))
132 wSearchText.SetValue(searchText)
133 wx.wxButton(dlg, wx.wxID_OK, "Find Next", wx.wxPoint(280, 5), wx.wxDefaultSize).SetDefault()
134 wx.wxButton(dlg, wx.wxID_CANCEL, "Cancel", wx.wxPoint(280, 35), wx.wxDefaultSize)
135 wWholeWord = wx.wxCheckBox(dlg, -1, 'Match whole word only',
136 wx.wxPoint(7, 35), wx.wxDefaultSize, wx.wxNO_BORDER)
137 if wholeWordsOnly:
138 wWholeWord.SetValue(1)
139 wCase = wx.wxCheckBox(dlg, -1, 'Match case',
140 wx.wxPoint(7, 55), wx.wxDefaultSize, wx.wxNO_BORDER)
141 if caseSensitive:
142 wCase.SetValue(1)
143 wSearchText.SetSelection(0, len(wSearchText.GetValue()))
144 wSearchText.SetFocus()
145
146 result = DialogResults(dlg.ShowModal())
147 result.text = wSearchText.GetValue()
148 result.wholeword = wWholeWord.GetValue()
149 result.casesensitive = wCase.GetValue()
150 dlg.Destroy()
151 return result
152
153
154 def colorDialog(parent=None, colorData=None, color=None):
155 if colorData:
156 dialog = wx.wxColourDialog(parent, colorData)
157 else:
158 dialog = wx.wxColourDialog(parent)
159 dialog.GetColourData().SetChooseFull(1)
160 if color is not None:
161 dialog.GetColourData().SetColour(color)
162 result = DialogResults(dialog.ShowModal())
163 result.colorData = dialog.GetColourData()
164 result.color = result.colorData.GetColour().Get()
165 dialog.Destroy()
166 return result
167
168 # it is easier to just duplicate the code than
169 # try and replace color with colour in the result
170 def colourDialog(parent=None, colourData=None, colour=None):
171 if colourData:
172 dialog = wx.wxColourDialog(parent, colourData)
173 else:
174 dialog = wx.wxColourDialog(parent)
175 dialog.GetColourData().SetChooseFull(1)
176 if colour is not None:
177 dialog.GetColourData().SetColour(color)
178 result = DialogResults(dialog.ShowModal())
179 result.colourData = dialog.GetColourData()
180 result.colour = result.colourData.GetColour().Get()
181 dialog.Destroy()
182 return result
183
184
185 def fontDialog(parent=None, fontData=None, font=None):
186 if fontData is None:
187 fontData = wx.wxFontData()
188 if font is not None:
189 aFontData.SetInitialFont(font)
190 dialog = wx.wxFontDialog(parent, fontData)
191 result = DialogResults(dialog.ShowModal())
192 if result.accepted:
193 fontData = dialog.GetFontData()
194 result.fontData = fontData
195 result.color = fontData.GetColour().Get()
196 result.colour = result.color
197 result.font = fontData.GetChosenFont()
198 else:
199 result.color = None
200 result.colour = None
201 result.font = None
202 dialog.Destroy()
203 return result
204
205
206 def textEntryDialog(parent=None, message='', title='', defaultText='', style=wx.wxOK | wx.wxCANCEL):
207 dialog = wx.wxTextEntryDialog(parent, message, title, defaultText, style)
208 result = DialogResults(dialog.ShowModal())
209 result.text = dialog.GetValue()
210 dialog.Destroy()
211 return result
212
213
214 def messageDialog(parent=None, message='', title='Message box',
215 aStyle = wx.wxOK | wx.wxCANCEL | wx.wxCENTRE,
216 pos=wx.wxDefaultPosition):
217 dialog = wx.wxMessageDialog(parent, message, title, aStyle, pos)
218 result = DialogResults(dialog.ShowModal())
219 dialog.Destroy()
220 return result
221
222
223 # KEA alerts are common, so I'm providing a class rather than
224 # requiring the user code to set up the right icons and buttons
225 # the with messageDialog function
226 def alertDialog(parent=None, message='', title='Alert', pos=wx.wxDefaultPosition):
227 return messageDialog(parent, message, title, wx.wxICON_EXCLAMATION | wx.wxOK, pos)
228
229
230 def scrolledMessageDialog(parent=None, message='', title='', pos=wx.wxDefaultPosition, size=(500,300)):
231 dialog = wxScrolledMessageDialog(parent, message, title, pos, size)
232 result = DialogResults(dialog.ShowModal())
233 dialog.Destroy()
234 return result
235
236
237 def fileDialog(parent=None, title='Open', directory='', filename='', wildcard='*.*',
238 style=wx.wxOPEN | wx.wxMULTIPLE):
239 dialog = wx.wxFileDialog(parent, title, directory, filename, wildcard, style)
240 result = DialogResults(dialog.ShowModal())
241 if result.accepted:
242 result.paths = dialog.GetPaths()
243 else:
244 result.paths = None
245 dialog.Destroy()
246 return result
247
248
249 # openFileDialog and saveFileDialog are convenience functions
250 # they represent the most common usages of the fileDialog
251 # with the most common style options
252 def openFileDialog(parent=None, title='Open', directory='', filename='',
253 wildcard='All Files (*.*)|*.*',
254 style=wx.wxOPEN | wx.wxMULTIPLE):
255 return fileDialog(parent, title, directory, filename, wildcard, style)
256
257
258 def saveFileDialog(parent=None, title='Save', directory='', filename='',
259 wildcard='All Files (*.*)|*.*',
260 style=wx.wxSAVE | wx.wxHIDE_READONLY | wx.wxOVERWRITE_PROMPT):
261 return fileDialog(parent, title, directory, filename, wildcard, style)
262
263
264 def dirDialog(parent=None, message='Choose a directory', path='', style=0,
265 pos=wx.wxDefaultPosition, size=wx.wxDefaultSize):
266 dialog = wx.wxDirDialog(parent, message, path, style, pos, size)
267 result = DialogResults(dialog.ShowModal())
268 if result.accepted:
269 result.path = dialog.GetPath()
270 else:
271 result.path = None
272 dialog.Destroy()
273 return result
274
275 directoryDialog = dirDialog
276
277
278 def singleChoiceDialog(parent=None, message='', title='', lst=[],
279 style=wx.wxOK | wx.wxCANCEL | wx.wxCENTRE):
280 dialog = wx.wxSingleChoiceDialog(parent,
281 message,
282 title,
283 lst,
284 style)
285 result = DialogResults(dialog.ShowModal())
286 result.selection = dialog.GetStringSelection()
287 dialog.Destroy()
288 return result
289
290
291 def multipleChoiceDialog(parent=None, message='', title='', lst=[], pos=wx.wxDefaultPosition, size=(200,200)):
292 dialog = wxMultipleChoiceDialog(parent, message, title, lst, pos, size)
293 result = DialogResults(dialog.ShowModal())
294 result.selection = dialog.GetValueString()
295 dialog.Destroy()
296 return result
297
298
299 if __name__ == '__main__':
300 class MyApp(wx.wxApp):
301
302 def OnInit(self):
303 frame = wx.wxFrame(wx.NULL, -1, "Dialogs", size=(400, 200))
304 panel = wx.wxPanel(frame, -1)
305 self.panel = panel
306
307 frame.Show(1)
308
309 dialogNames = [
310 'alertDialog',
311 'colorDialog',
312 'directoryDialog',
313 'fileDialog',
314 'findDialog',
315 'fontDialog',
316 'messageDialog',
317 'multipleChoiceDialog',
318 'openFileDialog',
319 'saveFileDialog',
320 'scrolledMessageDialog',
321 'singleChoiceDialog',
322 'textEntryDialog',
323 ]
324 self.nameList = wx.wxListBox(panel, -1, (0, 0), (130, 180), dialogNames, style=wx.wxLB_SINGLE)
325 wx.EVT_LISTBOX(panel, self.nameList.GetId(), self.OnNameListSelected)
326
327 tstyle = wx.wxTE_RICH2 | wx.wxTE_PROCESS_TAB | wx.wxTE_MULTILINE
328 self.text1 = wx.wxTextCtrl(panel, -1, pos=(150, 0), size=(200, 180), style=tstyle)
329
330 self.SetTopWindow(frame)
331
332 return 1
333
334 def OnNameListSelected(self, evt):
335 import pprint
336 sel = evt.GetString()
337 result = None
338 if sel == 'alertDialog':
339 result = alertDialog(message='Danger Will Robinson')
340 elif sel == 'colorDialog':
341 result = colorDialog()
342 elif sel == 'directoryDialog':
343 result = directoryDialog()
344 elif sel == 'fileDialog':
345 wildcard = "JPG files (*.jpg;*.jpeg)|*.jpeg;*.JPG;*.JPEG;*.jpg|GIF files (*.gif)|*.GIF;*.gif|All Files (*.*)|*.*"
346 result = fileDialog(None, 'Open', '', '', wildcard)
347 elif sel == 'findDialog':
348 result = findDialog()
349 elif sel == 'fontDialog':
350 result = fontDialog()
351 elif sel == 'messageDialog':
352 result = messageDialog(None, 'Hello from Python and wxPython!',
353 'A Message Box', wx.wxOK | wx.wxICON_INFORMATION)
354 #wx.wxYES_NO | wx.wxNO_DEFAULT | wx.wxCANCEL | wx.wxICON_INFORMATION)
355 #result = messageDialog(None, 'message', 'title')
356 elif sel == 'multipleChoiceDialog':
357 result = multipleChoiceDialog(None, "message", "title", ['one', 'two', 'three'])
358 elif sel == 'openFileDialog':
359 result = openFileDialog()
360 elif sel == 'saveFileDialog':
361 result = saveFileDialog()
362 elif sel == 'scrolledMessageDialog':
363 msg = "Can't find the file dialog.py"
364 try:
365 # read this source file and then display it
366 import sys
367 filename = sys.argv[-1]
368 fp = open(filename)
369 message = fp.read()
370 fp.close()
371 except:
372 pass
373 result = scrolledMessageDialog(None, message, filename)
374 elif sel == 'singleChoiceDialog':
375 result = singleChoiceDialog(None, "message", "title", ['one', 'two', 'three'])
376 elif sel == 'textEntryDialog':
377 result = textEntryDialog(None, "message", "title", "text")
378
379 if result:
380 #self.text1.SetValue(pprint.pformat(result.__dict__))
381 self.text1.SetValue(str(result))
382
383 app = MyApp(0)
384 app.MainLoop()