| Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2 """module containing layouts which combine finder ui modules"""
3 __docformat__ = "restructuredtext"
4 import sys
5 import string
6
7 from mrv.path import Path
8
9 from control import *
10 from finder import *
11 from option import *
12
13 from util import ( FrameDecorator, handleUnsavedModifications )
14
15 import mrv.maya.ui as ui
16 import mrv.maya
17 from mrv.maya.util import (logException, notifyException)
18
19 from mrv.maya.ref import FileReference
20 import maya.utils as mutil
21 import maya.cmds as cmds
22
23 __all__ = ('FinderLayout', 'FileOpenFinder', 'FileReferenceFinder', 'FileSaveFinder')
26 """Implements a layout with a finder as well a surrounding elements. It can
27 be configured using class configuration variables, and allows easy modification
28 through derivation
29
30 **Instance Variables**
31 * finder
32 * options"""
33
34 #{ Configuration
35 # used as names for buttons
36 k_confirm_name = "OK"
37 k_cancel_name = "Cancel"
38 k_stack_item_remove_name = "Remove Item"
39
40 t_finder=Finder
41 t_finder_provider = FileProvider
42 t_filepath = FilePathControl
43 t_options=None
44 t_bookmarks=BookmarkControl
45 t_root_selector=FileRootSelectorControl
46 t_stack=None
47 t_filter=FileFilterControl
48 #} END configuration
49
52
54 """Initialize all ui elements
55 :param kwargs: The following keywords are defined
56 * **defaultRoots**: default False, if True, show all roots available
57 on the system."""
58 num_splits = 1 + (self.t_options is not None)
59 config = (num_splits == 1 and "single") or "vertical%i" % num_splits
60 pane = ui.PaneLayout(configuration=config)
61 pane.p_paneSize=(1, 75, 100)
62
63 # attach the elements
64 t, b, l, r = self.kSides
65 m = 2
66
67 try:
68 pane.p_staticWidthPane=1
69 except (RuntimeError, TypeError):
70 # maya >= 2011
71 pass
72 # END exception handling
73
74 # populate main pane
75 if pane:
76 if self.t_stack is not None:
77 finder_form = ui.FormLayout()
78 if finder_form:
79
80 sdc = FrameDecorator("Stack", self.t_stack)
81 self.stack = sdc.layout
82 popup = ui.PopupMenu(markingMenu=True)
83 self._create_stack_menu(popup)
84
85
86 fdc = FrameDecorator("Finder", self.t_finder)
87 self.finder = fdc.layout
88 fi, st = fdc, sdc
89
90 finder_form.setup(
91 attachForm=(
92 (fi, t, m),
93 (fi, b, m),
94 (fi, l, m),
95 (st, t, m),
96 (st, b, m),
97 (st, r, m),
98 ),
99 attachNone=(
100 (st, l)
101 ),
102 attachControl=(
103 (fi, r, m, st)
104 )
105 )
106 # END finder form
107 self.setActive()
108 else:
109 self.finder = self.t_finder()
110 # END handle stack
111
112 # setup RMB menu
113 finder_popup = ui.PopupMenu(markingMenu=True)
114 self._create_finder_menu(finder_popup)
115 # END popupMenu
116
117 if self.t_options is not None:
118 self.options = self.t_options()
119 # END pane layout
120 self.setActive()
121
122 # if we have a filter, set it to the finder
123
124 # FILEPATH
125 ##########
126 fp = self.t_filepath()
127 fp.setEditable(False)
128 self.fpctrl = fp
129 self.finder.url_changed = fp.setPath
130
131
132 # BOOKMARKS AND SELECTOR
133 ########################
134 num_panes = (self.t_bookmarks is not None) + (self.t_root_selector is not None)
135 assert num_panes, "Require at least one bookmark type or a selector type"
136
137 config = "horizontal%i" % num_panes
138 lpane = ui.PaneLayout(configuration=config)
139
140 if lpane:
141 self.rootselector, self.bookmarks = None, None
142 if self.t_root_selector:
143 rdc = FrameDecorator("Roots", self.t_root_selector)
144 self.rootselector = rdc.layout
145 self.rootselector.root_changed = self.finder.setProvider
146
147 if kwargs.get('defaultRoots', False):
148 roots = list()
149 if not sys.platform.startswith('win'):
150 roots.append(Path("/"))
151 else:
152 # just try all accessible drives
153 for letter in string.ascii_uppercase:
154 try:
155 p = Path(letter + ":\\")
156 p.stat()
157 roots.append(p)
158 except OSError:
159 continue
160 # END ignore exceptions
161 # END for each letter
162 # END handle roots
163
164 if self.t_finder_provider is not None:
165 for rootpath in roots:
166 self.rootselector.addItem(self.t_finder_provider(rootpath))
167 # END for each rootpath
168 if roots:
169 self.rootselector.setSelectedItem(roots[0])
170 # END if we have a provider type
171 # END handle default roots
172 # END root selector setup
173 lpane.setActive()
174 if self.t_bookmarks:
175 bdc = FrameDecorator("Bookmarks", self.t_bookmarks)
176 self.bookmarks = bdc.layout
177 self.bookmarks.bookmark_changed = self._on_bookmark_change
178
179 # BOOKMARK POPUP
180 pmenu = ui.PopupMenu(markingMenu=True)
181 pmenu.e_postMenuCommand = self._build_bookmark_popup
182 # END bookmarks setup
183 # END left pane layout
184 self.setActive()
185
186 # FILTER ELEMENT
187 ################
188 assert self.t_filter is not None, "Require filter element, replace it by a dummy filter if it is not required"
189 self.filter = self.t_filter()
190 fil = self.filter
191 self.setActive()
192
193
194 # BUTTONS
195 #########
196 bl = self._create_button_layout()
197
198
199 # CONTROL ASSEMBLY
200 ##################
201 self.setup(
202 attachForm=(
203 (fil, t, m),
204 (fil, l, m),
205 (fil, r, m),
206 (lpane, l, m),
207 (lpane, b, m),
208 (pane, r, m),
209 (fp, b, m),
210 (bl, r, m),
211 (bl, b, m),
212 ),
213
214 attachNone=(
215 (fp, t),
216 (lpane, r),
217 (fil, b),
218 (bl, l),
219 (bl, t),
220 ),
221
222 attachControl=(
223 (lpane, t, m, fil),
224 (pane, t, m, fil),
225 (pane, b, m, bl),
226 (pane, l, m, lpane),
227 (fp, l, m, lpane),
228 (fp, r, m, bl),
229 ),
230 )
231 # END setup
232
233 #{ Subclass Interface
234
245
246
250
287
288 #}END subclass interface
289
290 #{ Callbacks
291
294
296 """helper routine closing the parent window if there is one"""
297 p = self.parent()
298 if isinstance(p, ui.Window):
299 # If its not deferred, it will crash maya for some reason, maybe
300 # something related to garbage collection.
301 mutil.executeDeferred(self.parent().delete)
302 elif isinstance(p, ui.FormLayout) and p.startswith('layoutDialog'):
303 cmds.layoutDialog(dismiss='close')
304 # END close window
305
309
315
317 popup.p_deleteAllItems = True
318 popup.setActive()
319
320 mi = ui.MenuItem(label="Add Bookmark")
321 mi.p_enable = self.finder.selectedUrl() is not None
322 if mi.p_enable:
323 mi.e_command = self._on_add_bookmark
324 # END setup command
325
326 mi = ui.MenuItem(label="Remove Bookmark")
327 mi.p_enable = len(self.bookmarks.selectedItems()) == 1
328 if mi.p_enable:
329 mi.e_command = self._on_remove_bookmark
330 # END setup command
331
332 @logException
334 url = self.finder.selectedUrl()
335 provider = self.finder.provider()
336
337 if not hasattr(provider, 'root'):
338 raise TypeError("Provider doesn't support the 'root' method")
339 # END verify interface
340
341 self.bookmarks.addItem((provider.root(), url))
342
343 @logException
346
347 @logException
349 """Propagate changed bookmarks to changed roots. If necessary, add a new
350 root to the root selector. Otherwise just set the root and url of the finder"""
351 cur_provider = self.finder.provider()
352 if cur_provider and root == cur_provider.root() and self.finder.selectedUrl() == url:
353 return
354 # END early bailout
355
356 if self.rootselector is None:
357 ptype = type(cur_provider)
358 assert ptype is not type(None), "Finder needs provider to be set beforehand"
359 self.finder.setProvider(ptype(root))
360 else:
361 actual_provider = None
362 root_item = root
363 # find a provider matching the root - if not, add it
364 for provider in self.rootselector.providers():
365 if provider.root() == root:
366 actual_provider = provider
367 break
368 # END handle provider match
369 # END for each provider
370
371 if actual_provider is None:
372 actual_provider = self.t_finder_provider(root)
373 self.rootselector.addItem(actual_provider)
374 # END add a new provider to root selector
375
376 self.rootselector.setSelectedItem(root_item)
377 # END handle existance of rootselector
378 self.finder.setUrl(url, allow_memory=False)
379
384 """Finder optimized to choose a location to save a file"""
385 #{ Configuration
386 k_confirm_name = "Save File"
387 t_stack = None
388
389 t_filepath = FilePathControlEditable
390 t_options=None
391 #} END configuration
392
394 super(FileSaveFinder, self).__init__(*args, **kwargs)
395 self.bookmarks.k_bookmark_store = "MRV_SAVE_Bookmarks"
396
397 # filepath field is editable in this case
398 self.fpctrl.setEditable(True)
399
400 @notifyException
406
409 """Finder customized for opening files"""
410
411 #{ Configuration
412 k_confirm_name = "Open File"
413 t_stack = None
414
415 t_options=FileOpenOptions
416 #} END configuration
417
419 super(FileOpenFinder, self).__init__(*args, **kwargs)
420 self.bookmarks.k_bookmark_store = "MRV_OPEN_Bookmarks"
421
422 @notifyException
434
437 """Finder Layout for creating references"""
438
439 #{ Configuration
440
441 k_add_single = "Add to Stack"
442 k_add_and_confirm = "Add to Stack and Confirm"
443 k_confirm_name = "Create Reference(s)"
444 k_stack_item_remove_name = "Remove File from Stack"
445
446 t_stack=FileStack
447 t_options=None
448 #} END configuration
449
451 super(FileReferenceFinder, self).__init__(*args, **kwargs)
452 self.bookmarks.k_bookmark_store = "MRV_REF_Bookmarks"
453
461
462
463 #{ Subclass Interface
464
466 """Create reference to the given reference paths, being strings to the file
467 in question"""
468 for ref in refpaths:
469 FileReference.create(ref)
470 # END for each ref to create
471
472 #} END subclass interface
473
474 #{ Callbacks
475
476 @notifyException
478 prov = self.finder.provider()
479 if prov is None:
480 raise AssertionError("Finder is not setup")
481
482 # default is always add
483 url = self.finder.selectedUrl(absolute=True)
484 if url is None:
485 raise ValueError("Please select a path and retry")
486 # END handle nothing selected
487
488 self.stack.addItem(url)
489
490 if menu_item.p_label == self.k_add_and_confirm:
491 self._confirm_button_pressed()
492 # END handle confirm
493
494 @notifyException
506
507
508 #} END callbacks
509
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Apr 19 18:00:24 2011 | http://epydoc.sourceforge.net |