5 # This file provides a generic Directory browser selection widget.
7 # AUTHOR: MontaVista Software, Inc. <source@mvista.com>
9 # Copyright 2001 MontaVista Software Inc.
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.
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.
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.
38 class DirBrowserDialog(Pmw.MegaToplevel):
39 def __init__(self, parent = None, **kw):
41 # Define the megawidget options.
45 ('hidedotfiles', 1, INITOPT),
46 ('label', None, INITOPT),
47 #('labelmargin', 0, INITOPT),
48 #('labelpos', None, INITOPT),
49 ('borderx', 20, INITOPT),
50 ('bordery', 20, INITOPT),
53 self.defineoptions(kw, optiondefs)
55 # Initialise the base class (after defining the options).
56 Pmw.MegaToplevel.__init__(self, parent)
58 interior = self.interior()
60 self.childframe = self.createcomponent('childframe', (), None,
66 self.childframe.pack(expand = 1,
70 self.labelframe = self.createcomponent('labelframe', (), None,
76 self.labelframe.pack(padx = 10, pady = 10, expand = 1, fill = 'both')
79 self.label = self.createcomponent('label', (), None,
84 self.label.place(x = (10 + self['borderx']), y = 10, anchor = 'w')
87 self.workframe = self.createcomponent('workframe', (), None,
93 self.workframe.pack(padx = self['borderx'],
94 pady = self['bordery'],
99 self.buttonframe = self.createcomponent('buttonframe', (), None,
105 self.buttonframe.pack(expand = 0,
109 self.optbox = self.createcomponent('optbox', (), None,
112 command = self.setpath,
114 self.optbox.bind('<Configure>', self._setMinimumSize)
116 self.listbox = self.createcomponent('listbox', (), None,
119 dblclickcommand = self._select,
123 self.entry = self.createcomponent('entryfield', (), None,
127 command = self.enteredpath,
129 label_text = 'Current Path:',
132 #self.createlabel(self.workframe, childCols = 1, childRows = 3)
134 self.buttonbox = self.createcomponent('buttonbox', (), None,
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)
145 self.buttonbox.alignbuttons()
146 self.buttonbox.pack(expand = 1, fill = 'x')
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)
156 self.setpath(self['path'])
158 # Check keywords and initialise options.
159 self.initialiseoptions()
161 def setpath(self, path):
162 path = os.path.abspath(os.path.expanduser(path))
164 if os.path.isfile(path):
165 path = os.path.dirname(path)
168 hidedotfiles = self['hidedotfiles']
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
176 if not os.path.isdir(entryPath):
179 if not os.access(entryPath, os.R_OK | os.X_OK):
180 # skip directories we can't enter any way
182 dirlist.append(entry)
185 self.entry.setentry(self['path'])
188 self.entry.setentry(path)
194 dirlist.insert(0, '..')
196 self.listbox.setlist(dirlist)
199 pathlist.append(path)
200 path = os.path.dirname(path)
202 self.optbox.setitems(pathlist, 0)
204 def _setMinimumSize(self, event):
205 # If the optionmenu changes width, make sure it does not
207 owidth = self.optbox.winfo_width()
208 self.workframe.grid_columnconfigure(2, minsize = owidth)
211 sel = self.listbox.getcurselection()
212 if self['path'] == '/':
216 self.setpath(os.path.dirname(self['path']))
218 self.setpath(self['path'] + '/' + sel[0])
221 def getcurpath(self):
224 def enteredpath(self):
225 self.setpath(self.entry.get())
228 self.deactivate(self['path'])
230 def cancelbutton(self):
231 self.deactivate(None)
233 def newdirbutton(self):
234 CreateDirectoryPopup(self.interior(), self['path'])
235 self.setpath(self['path'])
239 class CreateDirectoryPopup:
240 def __init__(self, parent, path):
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
252 self.newdirpopup.activate()
254 def _buttonpress(self, button):
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)
263 os.mkdir(self.path + '/' + newdirname)
265 ErrorPopup(self.parent,
266 'Error: Could not create directory: "%s"'%newdirname)
268 self.newdirpopup.deactivate()
270 self.newdirpopup.deactivate()
273 def ErrorPopup(parent, message):
274 error = Pmw.MessageDialog(parent, title = 'Error',
275 message_text = message,
280 if __name__ == '__main__':
282 rootWin = Tkinter.Tk()
286 rootWin.title('Directory Browser Dialog Demo')
289 # Create the hierarchical directory browser widget
290 dirBrowserDialog = DirBrowserDialog(rootWin,
292 label = 'Select a directory',
293 title = 'Directory Selector',
297 dir = dirBrowserDialog.activate()
298 print 'Selected Directory:', dir
300 dirButton = Tkinter.Button(rootWin, text="Browser", command=buildBrowser)
301 dirButton.pack(side = 'left', padx = 10, pady = 10)
303 exitButton = Tkinter.Button(rootWin, text="Quit", command=rootWin.quit)
304 exitButton.pack(side = 'left', padx = 10, pady = 10)