Salome HOME
Modif V6_4_°
[tools/eficas.git] / Pmw / Pmw_1_2 / contrib / DirBrowser.py
1 #
2 #  FILE: DirBrowser.py
3 #
4 #  DESCRIPTION:
5 #    This file provides a generic Directory browser selection widget.
6 #
7 #  AUTHOR:  MontaVista Software, Inc. <source@mvista.com>
8 #
9 #  Copyright 2001 MontaVista Software Inc.
10 #
11 #  This program is free software; you can redistribute  it and/or modify it
12 #  under  the terms of  the GNU General  Public License as published by the
13 #  Free Software Foundation;  either version 2 of the  License, or (at your
14 #  option) any later version.
15 #
16 #  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
17 #  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
18 #  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
19 #  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
20 #  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 #  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
22 #  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 #  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
24 #  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 #  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #
27 #  You should have received a copy of the  GNU General Public License along
28 #  with this program; if not, write  to the Free Software Foundation, Inc.,
29 #  675 Mass Ave, Cambridge, MA 02139, USA.
30 #
31
32
33 import os
34 import Tkinter
35 import Pmw
36
37
38 class DirBrowserDialog(Pmw.MegaToplevel):
39     def __init__(self, parent = None, **kw):
40         cwd = os.getcwd()
41         # Define the megawidget options.
42         INITOPT = Pmw.INITOPT
43         optiondefs = (
44             ('path',               cwd,             None),
45             ('hidedotfiles',       1,               INITOPT),
46             ('label',              None,            INITOPT),
47             #('labelmargin',        0,               INITOPT),
48             #('labelpos',           None,            INITOPT),
49             ('borderx',    20,  INITOPT),
50             ('bordery',    20,  INITOPT),
51             )
52         
53         self.defineoptions(kw, optiondefs)
54
55         # Initialise the base class (after defining the options).
56         Pmw.MegaToplevel.__init__(self, parent)
57
58         interior = self.interior()
59
60         self.childframe = self.createcomponent('childframe', (), None,
61                                                Tkinter.Frame,
62                                                (interior,),
63                                                borderwidth = 1,
64                                                relief = 'raised',
65                                               )
66         self.childframe.pack(expand = 1,
67                              fill = 'both',
68                              )
69
70         self.labelframe = self.createcomponent('labelframe', (), None,
71                                               Tkinter.Frame,
72                                               (self.childframe,),
73                                               borderwidth = 2,
74                                               relief = 'groove',
75                                               )
76         self.labelframe.pack(padx = 10, pady = 10, expand = 1, fill = 'both')
77         
78         if self['label']:
79             self.label = self.createcomponent('label', (), None,
80                                               Tkinter.Label,
81                                               (self.childframe,),
82                                               text = self['label'],
83                                               )
84             self.label.place(x = (10 + self['borderx']), y = 10, anchor = 'w')
85
86
87         self.workframe = self.createcomponent('workframe', (), None,
88                                               Tkinter.Frame,
89                                               (self.labelframe,),
90                                               #borderwidth = 2,
91                                               #relief = 'groove',
92                                               )
93         self.workframe.pack(padx = self['borderx'],
94                             pady = self['bordery'],
95                             expand = 1,
96                             fill = 'both',
97                             )
98
99         self.buttonframe = self.createcomponent('buttonframe', (), None,
100                                                 Tkinter.Frame,
101                                                 (interior,),
102                                                 borderwidth = 1,
103                                                 relief = 'raised',
104                                                 )
105         self.buttonframe.pack(expand = 0,
106                               fill = 'x',
107                               )
108
109         self.optbox = self.createcomponent('optbox', (), None,
110                                            Pmw.OptionMenu,
111                                            (self.workframe,),
112                                            command = self.setpath,
113                                            )
114         self.optbox.bind('<Configure>', self._setMinimumSize)
115
116         self.listbox = self.createcomponent('listbox', (), None,
117                                             Pmw.ScrolledListBox,
118                                             (self.workframe,),
119                                             dblclickcommand = self._select,
120                                             )
121
122         path = self['path']
123         self.entry = self.createcomponent('entryfield', (), None,
124                                           Pmw.EntryField,
125                                           (self.workframe,),
126                                           value = path,
127                                           command = self.enteredpath,
128                                           labelpos = 'nw',
129                                           label_text = 'Current Path:',
130                                           )
131
132         #self.createlabel(self.workframe, childCols = 1, childRows = 3)
133
134         self.buttonbox = self.createcomponent('buttonbox', (), None,
135                                               Pmw.ButtonBox,
136                                               (self.buttonframe,),
137                                               )
138         self.buttonbox.add('OK', text = 'OK',
139                            command = self.okbutton)
140         self.buttonbox.add('Cancel', text = 'Cancel',
141                            command =  self.cancelbutton)
142         self.buttonbox.add('New Directory', text = 'New Directory',
143                            command =  self.newdirbutton)
144         
145         self.buttonbox.alignbuttons()
146         self.buttonbox.pack(expand = 1, fill = 'x')
147
148         self.optbox.grid(row = 2, column = 2, sticky = 'ew')
149         self.listbox.grid(row = 3, column = 2, sticky = 'news')
150         self.entry.grid(row = 5, column = 2, sticky = 'ew')
151         self.workframe.grid_rowconfigure(3, weight = 1)
152         self.workframe.grid_rowconfigure(4, minsize = 20)
153         self.workframe.grid_columnconfigure(2, weight = 1)
154
155
156         self.setpath(self['path'])
157
158         # Check keywords and initialise options.
159         self.initialiseoptions()
160
161     def setpath(self, path):
162         path = os.path.abspath(os.path.expanduser(path))
163         
164         if os.path.isfile(path):
165             path = os.path.dirname(path)
166
167         dirlist = []
168         hidedotfiles = self['hidedotfiles']
169         try:
170             posix = (os.name == 'posix')
171             for entry in os.listdir(path):
172                 entryPath = path + '/' + entry
173                 if hidedotfiles and entry[0] == '.':
174                     # skip dot files if desired
175                     continue
176                 if not os.path.isdir(entryPath):
177                     # skip files
178                     continue
179                 if not os.access(entryPath, os.R_OK | os.X_OK):
180                     # skip directories we can't enter any way
181                     continue
182                 dirlist.append(entry)
183
184         except:
185             self.entry.setentry(self['path'])
186             return
187
188         self.entry.setentry(path)
189         
190         self['path'] = path
191         
192         dirlist.sort()
193         if path != '/':
194             dirlist.insert(0, '..')
195
196         self.listbox.setlist(dirlist)
197         pathlist = []
198         while path != '/':
199             pathlist.append(path)
200             path = os.path.dirname(path)
201         pathlist.append('/')
202         self.optbox.setitems(pathlist, 0)
203
204     def _setMinimumSize(self, event):
205         # If the optionmenu changes width, make sure it does not
206         # shrink later.
207         owidth = self.optbox.winfo_width()
208         self.workframe.grid_columnconfigure(2, minsize = owidth)
209
210     def _select(self):
211         sel = self.listbox.getcurselection()
212         if self['path'] == '/':
213             self['path'] = ''
214         if len(sel) > 0:
215             if sel[0] == '..':
216                 self.setpath(os.path.dirname(self['path']))
217             else:
218                 self.setpath(self['path'] + '/' + sel[0])
219
220
221     def getcurpath(self):
222         return self['path']
223
224     def enteredpath(self):
225         self.setpath(self.entry.get())
226
227     def okbutton(self):
228         self.deactivate(self['path'])
229
230     def cancelbutton(self):
231         self.deactivate(None)
232
233     def newdirbutton(self):
234         CreateDirectoryPopup(self.interior(), self['path'])
235         self.setpath(self['path'])
236
237
238         
239 class CreateDirectoryPopup:
240     def __init__(self, parent, path):
241         self.path = path
242         self.parent = parent
243         self.newdirpopup = Pmw.PromptDialog(parent,
244                                             buttons = ('OK', 'Cancel'),
245                                             defaultbutton = 'OK',
246                                             title = 'New Directory',
247                                             entryfield_labelpos = 'nw',
248                                             label_text = 'Enter new directory name for:\n%s'%self.path,
249                                             command = self._buttonpress
250                                             )
251
252         self.newdirpopup.activate()
253
254     def _buttonpress(self, button):
255         if button == 'OK':
256             newdirname = self.newdirpopup.get()
257             dirlist = os.listdir(self.path)
258             if newdirname in dirlist:
259                 ErrorPopup(self.parent,
260                            'Error: "%s", already exists as a file or directory.'%newdirname)
261             else:
262                 try:
263                     os.mkdir(self.path + '/' + newdirname)
264                 except:
265                     ErrorPopup(self.parent,
266                                'Error: Could not create directory: "%s"'%newdirname)
267                 else:
268                     self.newdirpopup.deactivate()
269         else:
270             self.newdirpopup.deactivate()
271             
272
273 def ErrorPopup(parent, message):
274     error = Pmw.MessageDialog(parent, title = 'Error',
275                               message_text = message,
276                               defaultbutton = 0,
277                               )
278     error.activate()
279     
280 if __name__ == '__main__':
281
282     rootWin = Tkinter.Tk()
283
284     Pmw.initialise()
285
286     rootWin.title('Directory Browser Dialog Demo')
287
288     def buildBrowser():
289         # Create the hierarchical directory browser widget
290         dirBrowserDialog = DirBrowserDialog(rootWin,
291                                             #labelpos = 'nw',
292                                             label = 'Select a directory',
293                                             title = 'Directory Selector',
294                                             #path = '~',
295                                             #hidedotfiles = 0,
296                                             )
297         dir = dirBrowserDialog.activate()
298         print 'Selected Directory:', dir
299
300     dirButton = Tkinter.Button(rootWin, text="Browser", command=buildBrowser)
301     dirButton.pack(side = 'left', padx = 10, pady = 10)
302
303     exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit)
304     exitButton.pack(side = 'left', padx = 10, pady = 10)
305
306     rootWin.mainloop()