daboide Commit
Revision 644
Date: 2006-10-08 17:03:21 -0700 (Sun, 08 Oct 2006)
Author: ed
Changed:
U trunk/ClassDesigner.py
U trunk/ClassDesignerComponents.py
U trunk/ClassDesignerControlMixin.py
Log:
Fixed the saving of embedded custom classes so that they use relative paths.
Refactored out the code for opening a class and its associated code file so
that it can be called from different parts of the ClassDesigner.
Fixed a bug that would throw an error if the Designer's Selection contained
None values.
Got pageframe-type controls to work in the ClassDesigner on sizer-less forms.
Moved the checking for minimum sizes after the instantiation, since many
objects had not yet had their 'drawn' sizes applied.
Removed several event bindings from the control mixin that were redundant.
Removed duplicate key events when received by controls within containers such
as pageframes, grids, etc.
Added a convenience prop 'UsingSizers' to the controls to replace the repeated
reference to 'self.Form.UseSizers'.
Diff:
Modified: trunk/ClassDesigner.py
===================================================================
--- trunk/ClassDesigner.py 2006-10-07 13:49:39 UTC (rev 643)
+++ trunk/ClassDesigner.py 2006-10-09 00:03:21 UTC (rev 644)
@@ -419,15 +419,13 @@
return ret
- def openClass(self, pth):
- """Called when the user selects the 'Open' menu and selects
- a saved XML file. We need to open the file, and confirm that it
is
- indeed a valid class file. If so, we then re-construct the
class in
- a new ClassDesigner window.
+ def _importClassXML(self, pth):
+ """Read in the XML and associated code file (if any), and
+ return a dict that can be used to re-create the object.
"""
xml = open(pth).read()
try:
- clsd = xtd.xmltodict(xml)
+ dct = xtd.xmltodict(xml)
except:
raise IOError, _("This does not appear to be a valid
class file.")
# Get the associated code file, if any
@@ -435,10 +433,19 @@
if os.path.exists(codePth):
try:
codeDict =
desUtil.parseCodeFile(open(codePth).read())
- desUtil.addCodeToClassDict(clsd, codeDict)
+ desUtil.addCodeToClassDict(dct, codeDict)
except StandardError, e:
print "Failed to parse code file:", e
-
+ return dct
+
+
+ def openClass(self, pth):
+ """Called when the user selects the 'Open' menu and selects
+ a saved XML file. We need to open the file, and confirm that it
is
+ indeed a valid class file. If so, we then re-construct the
class in
+ a new ClassDesigner window.
+ """
+ clsd = self._importClassXML(pth)
# See if it is a full form-based class, or an individual
component.
isFormClass = (clsd["name"] == "dForm")
if isFormClass:
@@ -1686,11 +1693,13 @@
obj.Selected = newsel
else:
for oldSel in self._selection:
- oldSel.Selected = False
+ if oldSel is not None:
+ oldSel.Selected = False
self._selection = []
for obj in objs:
- self._selection.append(obj)
- obj.Selected = True
+ if obj is not None:
+ self._selection.append(obj)
+ obj.Selected = True
if len(self._selection) > 0:
self._srcObj = self._selection[0]
else:
@@ -1748,7 +1757,7 @@
pnl = self._selection[0]
# Handle the odd behavior of pages and when adding
# controls programmatically.
- if isinstance(pnl, (dui.dPage, dui.dForm)):
+ if self.UseSizers and isinstance(pnl, (dui.dPage, dui.dForm)):
pnl = self.getMainLayoutPanel(pnl)
return pnl
@@ -1924,38 +1933,40 @@
if isPageControl:
noTabs = issubclass(cls, dui.dPageFrameNoTabs)
props["PageClass"] = self.getControlClass(dui.dPage)
-
- class PageInfoDialog(dui.dOkCancelDialog):
- def __init__(self, *args, **kwargs):
- self.noTabs = self._extractKey(kwargs,
"NoTabs", False)
- self.pageCount = 3
- self.tabPositions = ("Top", "Bottom",
"Left", "Right")
- self.tabPosSelection = 0
- super(PageInfoDialog,
self).__init__(*args, **kwargs)
-
- def addControls(self):
- self.Caption = _("Paged Control
Settings")
- gsz = dui.dGridSizer(maxCols=2, hgap=5,
vgap=12)
- lbl = dui.dLabel(self,
Caption=_("Number of pages:"))
- spn = dui.dSpinner(self,
DataSource="form",
- DataField="pageCount",
Min=1, Max=20, Value=3)
- gsz.append(lbl, halign="right")
- gsz.append(spn)
-
- if not self.noTabs:
- lbl = dui.dLabel(self,
Caption=_("Tab Position:"))
- dd = dui.dDropdownList(self,
Choices=(_("Top"),
- _("Bottom"),
_("Left"), _("Right")), ValueMode="Position",
- Value=0,
DataSource="form", DataField="tabPosSelection")
+ if not useSizers:
+ props["PageSizerClass"] = None
+
+ if not props.get("PageCount", 0):
+ class PageInfoDialog(dui.dOkCancelDialog):
+ def __init__(self, *args, **kwargs):
+ self.noTabs =
self._extractKey(kwargs, "NoTabs", False)
+ self.pageCount = 3
+ self.tabPositions = ("Top",
"Bottom", "Left", "Right")
+ self.tabPosSelection = 0
+ super(PageInfoDialog,
self).__init__(*args, **kwargs)
+
+ def addControls(self):
+ self.Caption = _("Paged Control
Settings")
+ gsz = dui.dGridSizer(maxCols=2,
hgap=5, vgap=12)
+ lbl = dui.dLabel(self,
Caption=_("Number of pages:"))
+ spn = dui.dSpinner(self,
DataSource="form",
+
DataField="pageCount", Min=1, Max=20, Value=3)
gsz.append(lbl, halign="right")
- gsz.append(dd)
- gsz.setColExpand("all", True)
-
- self.Sizer.append1x(gsz, border=30,
halign="Center", valign="Middle")
- self.refresh()
- self.layout()
-
- if not props.get("PageCount", 0):
+ gsz.append(spn)
+
+ if not self.noTabs:
+ lbl = dui.dLabel(self,
Caption=_("Tab Position:"))
+ dd =
dui.dDropdownList(self, Choices=(_("Top"),
+
_("Bottom"), _("Left"), _("Right")), ValueMode="Position",
+
Value=0, DataSource="form", DataField="tabPosSelection")
+ gsz.append(lbl,
halign="right")
+ gsz.append(dd)
+ gsz.setColExpand("all", True)
+
+ self.Sizer.append1x(gsz,
border=30, halign="Center", valign="Middle")
+ self.refresh()
+ self.layout()
+
dlg = PageInfoDialog(self.currentForm,
NoTabs=noTabs,
BasePrefKey=self.BasePrefKey+".PageInfoDialog")
dlg.AutoSize = False
@@ -2025,7 +2036,6 @@
else:
sz.insert(pos, obj)
else:
- self._srcPos = self._srcPos
if self._srcPos is not None:
parentPos =
obj.Parent.formCoordinates(obj.Parent.Position)
obj.Position = (self._srcPos[0] - parentPos[0],
self._srcPos[1] - parentPos[1])
@@ -2048,19 +2058,17 @@
if isPageControl:
pg0panel = None
- for pg in obj.Pages[::-1]:
- pg.Sizer = LayoutSizer("v")
- pg0panel = LayoutPanel(pg)
-# pg0panel.BackColor = pg.BackColor
+ if useSizers:
+ for pg in obj.Pages[::-1]:
+ pg.Sizer = LayoutSizer("v")
+ pg0panel = LayoutPanel(pg)
if useSizers:
newitem = obj.ControllingSizerItem
sz.setItemProps(newitem, itmProps)
else:
- if obj.Width < obj.defaultWd:
- dabo.ui.setAfter(obj, "Width", obj.defaultWd)
- if obj.Height < obj.defaultHt:
- dabo.ui.setAfter(obj, "Height", obj.defaultHt)
+ dabo.ui.callAfter(self.checkMinSize, obj)
+
try:
dui.callAfterInterval(500, obj.Form.layout)
except:
@@ -2079,7 +2087,7 @@
obj.fillGrid()
if not skipUpdate:
- if isPageControl:
+ if useSizers and isPageControl:
dui.callAfter(self.select, pg0panel)
else:
dui.callAfter(self.select, obj)
@@ -2107,6 +2115,13 @@
return ret
+ def checkMinSize(self, obj):
+ if obj.Height < obj.defaultHt:
+ obj.Height = obj.defaultHt
+ if obj.Width < obj.defaultWd:
+ obj.Width = obj.defaultWd
+
+
def addSlotOptions(self, obj, pop, sepBefore=False, sepAfter=False):
"""Takes an object and a context menu, and adds the appropriate
options
depending on its position in the design surface.
@@ -2221,9 +2236,7 @@
"""Creates the popup menu for selecting child objects"""
# Store the source object
self._srcObj = srcObj
- mpX, mpY = dui.getFormMousePosition()
- objX, objY = srcObj.objectCoordinates((mpX, mpY))
- self._srcPos = (mpX - objX, mpY - objY)
+ self._srcPos = dui.getFormMousePosition()
mainpop = dui.dMenu()
if self.UseSizers:
@@ -2309,11 +2322,7 @@
# Strip out the ordering information
pth = pth[1:]
self.addToMRU(self._customClassCaption, pth,
self.addCustomClass)
- xml = open(pth).read()
- try:
- clsd = xtd.xmltodict(xml)
- except:
- raise IOError, _("This does not appear to be a valid
class file.")
+ clsd = self._importClassXML(pth)
# We need to replace the 'designerClass' attribute so that
# recreateChildren() knows what to add.
nm = clsd["name"]
@@ -2334,7 +2343,9 @@
szr = None
fromSzr = False
# OK, add it in...
+ self._basePath = self._srcObj.Form._classFile
mainObj = self.recreateChildren(self._srcObj, clsd, szr,
fromSzr)
+ self._basePath = None
# This is the key that marks it as a class, and not a base
object.
prop = LayoutSaverMixin.classFlagProp
mainObj.__setattr__(prop, pth)
@@ -2373,7 +2384,7 @@
self._codeDict[obj] = cd
for att, val in atts.items():
- if att in ("children", "classID", "designerClass",
"SlotCount"):
+ if att in ("children", "classID", "code-ID",
"designerClass", "SlotCount"):
continue
elif att == "savedClass":
obj.savedClass = True
Modified: trunk/ClassDesignerComponents.py
===================================================================
--- trunk/ClassDesignerComponents.py 2006-10-07 13:49:39 UTC (rev 643)
+++ trunk/ClassDesignerComponents.py 2006-10-09 00:03:21 UTC (rev 644)
@@ -79,7 +79,13 @@
if classDict:
defVals.update(classDict.get("attributes", {}))
if isClass:
- ra["designerClass"] = clsPath
+ clsRef = os.path.abspath(clsPath)
+ if isinstance(self, dabo.ui.dForm):
+ relPath = self._classFile
+ else:
+ relPath = self.Form._classFile
+ ra["designerClass"] =
dabo.lib.utils.getPathAttributePrefix() + \
+ dabo.lib.utils.relativePath(clsRef,
relPath)
ra["savedClass"] = True
else:
ra["designerClass"] = self.getClassName()
@@ -1645,7 +1651,7 @@
"""
def afterInit(self):
self.IsContainer = True
- self.bindEvent(dEvents.KeyChar, self.Form.onKeyChar)
+# self.bindEvent(dEvents.KeyChar, self.Form.onKeyChar)
def onMouseMove(self, evt):
Modified: trunk/ClassDesignerControlMixin.py
===================================================================
--- trunk/ClassDesignerControlMixin.py 2006-10-07 13:49:39 UTC (rev 643)
+++ trunk/ClassDesignerControlMixin.py 2006-10-09 00:03:21 UTC (rev 644)
@@ -37,6 +37,8 @@
self._hiliteBorderWidth = 0
# Create the actual hilite border object
self._hiliteBorder = None
+ # Caches the form's setting for 'useSizers'
+ self._usingSizers = None
# References for resizing interactively
self._startX = self._startY = self._startWd = self._startHt = 0
# Reference for dragging interactively
@@ -97,8 +99,8 @@
self.setRootNode("Tree")
elif isinstance(self, (dabo.ui.dPageFrame, dabo.ui.dPageList,
dabo.ui.dPageSelect, dabo.ui.dPageFrameNoTabs)):
- self.defaultWd = 200
- self.defaultHt = 200
+ self.defaultWd = 400
+ self.defaultHt = 300
# Bind the active page to the current selection
self.bindEvent(dEvents.PageChanged, self.desSelectPage)
elif isinstance(self, (dabo.ui.dPanel, dabo.ui.dImage,
dabo.ui.dBitmap,
@@ -114,11 +116,11 @@
self.HiliteBorderLineStyle = "dot"
self.HiliteBorderWidth = 0
- self.bindEvent(dEvents.KeyChar, self.onKeyChar)
- self.bindEvent(dEvents.MouseLeftDown, self.onMouseLeftDown)
- self.bindEvent(dEvents.MouseLeftUp, self.onMouseLeftUp)
- self.bindEvent(dEvents.MouseMove, self.onMouseMove)
- self.bindEvent(dEvents.ContextMenu, self.onContextMenu)
+# self.bindEvent(dEvents.KeyChar, self.onKeyChar)
+# self.bindEvent(dEvents.MouseLeftDown, self.onMouseLeftDown)
+# self.bindEvent(dEvents.MouseLeftUp, self.onMouseLeftUp)
+# self.bindEvent(dEvents.MouseMove, self.onMouseMove)
+# self.bindEvent(dEvents.ContextMenu, self.onContextMenu)
# self.bindKey("left", self.Form.keyMoveLeft)
@@ -128,7 +130,9 @@
def onKeyChar(self, evt):
- print "KEY/Control", self.Name, evt.keyCode, evt.keyChar,
dKeys.key_Left
+ if isinstance(self, (dabo.ui.dPage, dabo.ui.dColumn)):
+ # The key will get processed by the container
+ return
self.Form.onKeyChar(evt)
@@ -147,7 +151,7 @@
pass
else:
evt.stop()
- if not self.Form.UseSizers:
+ if not self.UsingSizers:
self.Form.onControlLeftDown(evt)
@@ -171,40 +175,39 @@
# If it is a LayoutPanel or page, return - the event
# is handled elsewhere
evt.stop()
- if isinstance(self, (dabo.ui.dPage, LayoutPanel)):
+ if self.UsingSizers and isinstance(self, (dabo.ui.dPage,
LayoutPanel)):
return
pop = self.createContextMenu()
self.showContextMenu(pop)
def createContextMenu(self):
- if isinstance(self, (dabo.ui.dPanel,)):
- # If the control can contain child objects, get that
menu.
- # If it already has child objects, though, do not get
the menu.
+ canAddObjects = False
+ if not self.UsingSizers:
+ if self is self.Form.ActiveContainer:
+ # If the control can contain child objects, get
that menu.
+ canAddObjects = True
+ if canAddObjects:
pop = self.Form.app.getControlMenu(self, False)
-# if len(self.Children) == 0:
-# pop = self.Form.app.getControlMenu(self, True)
-# else:
-# return None
else:
pop = dabo.ui.dMenu()
if len(pop.Children):
pop.prependSeparator()
- if not self.Form.UseSizers and self.IsContainer \
+ if not self.UsingSizers and self.IsContainer \
and not self is self.Form.ActiveContainer:
pop.prepend(_("Edit Contents"),
bindfunc=self.onEditContainer)
if len(pop.Children):
pop.prependSeparator()
pop.prepend(_("Edit Code"), bindfunc=self.onEditCode)
pop.prependSeparator()
- if not self.Form.UseSizers and self is
self.Form.ActiveContainer:
+ if not self.UsingSizers and self is self.Form.ActiveContainer:
if self.Form.app.Clipboard:
pop.prepend(_("Paste"), bindfunc=self.onPaste)
else:
pop.prepend(_("Delete"), bindfunc=self.onDelete)
pop.prepend(_("Copy"), bindfunc=self.onCopy)
pop.prepend(_("Cut"), bindfunc=self.onCut)
- if self.Form.UseSizers:
+ if self.UsingSizers:
self.Application.addSlotOptions(self, pop,
sepBefore=True)
# Add the Sizer editing option
pop.appendSeparator()
@@ -247,7 +250,7 @@
if isinstance(self, dabo.ui.dPage):
dabo.ui.callAfter(self.Parent.onDelete, evt)
return
- if self.Form.UseSizers:
+ if self.UsingSizers:
self.ControllingSizer.delete(self)
else:
self.Form.select(self.Parent)
@@ -270,6 +273,7 @@
def desSelectPage(self, evt):
"""Called when a page is selected"""
+ if not self.UsingSizers: return
try:
obj = self.Application.Selection[0]
if obj.isContainedBy(self.SelectedPage):
@@ -781,7 +785,8 @@
def _getContainerState(self):
- return isinstance(self, (dabo.ui.dPanel, dabo.ui.dForm,
dabo.ui.dDialog) )
+ return isinstance(self, (dabo.ui.dPanel, dabo.ui.dPage,
dabo.ui.dForm,
+ dabo.ui.dDialog) )
def _getRegID(self):
@@ -804,12 +809,15 @@
def _setSelected(self, val):
oldval = self._selected
self._selected = val
- if self.Form.UseSizers:
+ if self.UsingSizers:
self.HiliteBorderWidth = (0, 2)[val]
else:
self.HiliteBorderWidth = (0, 2)[self is
self.Form.ActiveContainer]
if not val:
self.Form.hideHandles(self)
+ else:
+ if isinstance(self, dabo.ui.dPage):
+ self.Parent.SelectedPage = self
if hasattr(self, "_redraw"):
autoclear = self._autoClearDrawings
needRefresh = False
@@ -948,6 +956,12 @@
return ret
+ def _getUsingSizers(self):
+ if self._usingSizers is None:
+ self._usingSizers = self.Form.UseSizers
+ return self._usingSizers
+
+
DesignerEvents = property(_getDesEvents, None, None,
_("""Returns a list of the most common events for the
control.
This will determine which events are displayed in the
PropSheet
@@ -1015,6 +1029,9 @@
TreeDisplayCaption = property(_getTreeDisp, None, None,
_("Displayed text in the Designer Tree. (tuple)") )
+ UsingSizers = property(_getUsingSizers, None, None,
+ _("Convenience property. Reflects the form's UseSizers
value (bool)"))
+
if __name__ == "__main__":
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev