daboide Commit
Revision 647
Date: 2006-10-09 18:06:52 -0700 (Mon, 09 Oct 2006)
Author: ed
Changed:
U trunk/ClassDesigner.py
U trunk/ClassDesignerComponents.py
U trunk/ClassDesignerFormMixin.py
U trunk/ClassDesignerMenu.py
U trunk/sample.cnxml
U trunk/wizards/QuickLayoutWizard.py
Log:
Added a 'name' attribute to the sample.cnxml file.
The rest of the changes greatly enhance the wizard for adding data-bound
controls from a connection file. For the VFP folks out there, this is like
building a form from the data environment.
The wizard runs now in both sizer and non-sizer forms. You now have the option
of not only editing the caption for a field, but also changing the control
class for any field. Also, if a form already has a connection defined, it skips
the part where it asks you to select a connection.
I removed the menu item to run the wizard, as it really never belonged there.
Now you can right-click on a layout slot in a sizer-based design, or on the
main panel of a non-sizer-based design, and add controls from the Data
Environment from the context menu.
Diff:
Modified: trunk/ClassDesigner.py
===================================================================
--- trunk/ClassDesigner.py 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/ClassDesigner.py 2006-10-10 01:06:52 UTC (rev 647)
@@ -1759,6 +1759,8 @@
# controls programmatically.
if self.UseSizers and isinstance(pnl, (dui.dPage, dui.dForm)):
pnl = self.getMainLayoutPanel(pnl)
+ elif not self.UseSizers:
+ pnl = self.currentForm.ActiveContainer
return pnl
@@ -2965,38 +2967,85 @@
elif typ.startswith("column;"):
useGrid = typ.endswith("labels on left")
- if useGrid:
- sz, pnl = self.addSizer("grid", pnl=pnl,
rows=0, cols=0)
+ # Collections of the added labels/controls. Used
+ # for final alignment in non-sizer cases.
+ lbls = []
+ ctls = []
+ if self.UseSizers:
+ if useGrid:
+ sz, pnl = self.addSizer("grid",
pnl=pnl, rows=0, cols=0)
+ else:
+ sz, pnl = self.addSizer("box",
orient="v", pnl=pnl, slots=0)
+ if outBorder:
+ if sz.ControllingSizer:
+
sz.ControllingSizer.setItemProp(sz, "DefaultBorder", outBorder)
+ # We need to first detach the sizer
without destroying it.
+ if useGrid:
+ sz.VGap = spacing
+ sz.HGap = colSpacing
else:
- sz, pnl = self.addSizer("box", orient="v",
pnl=pnl, slots=0)
- if outBorder:
- if sz.ControllingSizer:
- sz.ControllingSizer.setItemProp(sz,
"DefaultBorder", outBorder)
- # We need to first detach the sizer without
destroying it.
- if useGrid:
- sz.VGap = spacing
- sz.HGap = colSpacing
-
+ # No sizers. Lay them out from the context menu
position.
+ (xpos, ypos) = (xorig, yorig) = self._srcPos
+ if outBorder:
+ xpos += outBorder
+ ypos += outBorder
+ xorig += outBorder
+ yorig += outBorder
+
lblClass = self.getControlClass(dui.dLabel)
for fld in flds:
fldData = layoutInfo["fldInfo"][fld]
lbl = lblClass(pnl)
+ lbls.append(lbl)
# Need to add this after the fact, so that when
the form is saved,
# the caption is different than the original
value.
lbl.Caption = fldData["caption"]
ctlClass =
self.getControlClass(fldData["class"])
ctl = ctlClass(pnl, DataSource=table,
DataField=fld)
- sz.append(lbl, halign=lblAlign)
+ ctls.append(ctl)
+ if self.UseSizers:
+ sz.append(lbl, halign=lblAlign)
+ if useGrid:
+ sz.append(ctl, "x",
halign="left")
+ else:
+ # Add a border to the bottom of
the control
+ sz.append(ctl, "x",
halign="left", border=spacing, borderSides="Bottom")
+ else:
+ lbl.Position = (xpos, ypos)
+ if useGrid:
+ xpos += lbl.Width + colSpacing
+ else:
+ ypos += lbl.Height
+ ctl.Position = (xpos, ypos)
+ if useGrid:
+ xpos = xorig
+ ypos += ctl.Height + spacing
+
+ if self.UseSizers:
if useGrid:
- sz.append(ctl, "x", halign="left")
+ sz.Rows = len(flds)
+ sz.Columns = 2
+ sz.setColExpand(True, 1)
+ pnl.layout()
+ else:
+ # Right-align all the controls to the rightmost
position
+ rpos = max([ctl.Right for ctl in ctls])
+ for ctl in ctls:
+ ctl.Right = rpos
+ lblAlign = layoutInfo["labelAlignment"]
+ if lblAlign == "Center":
+ wd = max([lbl.Width for lbl in lbls])
+ for lbl in lbls:
+ lbl.Left += 0.5 * (wd -
lbl.Width)
+ elif lblAlign == "Right":
+ rpos = max([lbl.Right for lbl in lbls])
+ for lbl in lbls:
+ lbl.Right = rpos
else:
- # Add a border to the bottom of the
control
- sz.append(ctl, "x", halign="left",
border=spacing, borderSides="Bottom")
- if useGrid:
- sz.Rows = len(flds)
- sz.Columns = 2
- sz.setColExpand(True, 1)
- pnl.layout()
+ lpos = max([lbl.Left for lbl in lbls])
+ for lbl in lbls:
+ lbl.Left = lpos
+
self._selection = [self.currentForm]
self.updateLayout()
Modified: trunk/ClassDesignerComponents.py
===================================================================
--- trunk/ClassDesignerComponents.py 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/ClassDesignerComponents.py 2006-10-10 01:06:52 UTC (rev 647)
@@ -485,6 +485,9 @@
# Add the Sizer editing option
pop.appendSeparator()
pop.append(_("Edit Sizer Settings"), bindfunc=self.onEditSizer)
+ pop.appendSeparator()
+ pop.append(_("Add Controls from Data Environment"),
+ self.Form.onRunLayoutWiz)
return pop
@@ -1688,6 +1691,9 @@
if self.Form.app.Clipboard:
pop.prependSeparator()
pop.prepend(_("Paste"), bindfunc=self.onPaste)
+ pop.appendSeparator()
+ pop.append(_("Add Controls from Data Environment"),
+ self.Form.onRunLayoutWiz)
return pop
Modified: trunk/ClassDesignerFormMixin.py
===================================================================
--- trunk/ClassDesignerFormMixin.py 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/ClassDesignerFormMixin.py 2006-10-10 01:06:52 UTC (rev 647)
@@ -32,8 +32,6 @@
self.Caption = _("Dabo Class Designer")
self._controls = []
self._namedConnection = ""
-# self._cxnFile = None
-# self._cxnName = None
self._selection = [self]
self._classFile = ""
self.redrawOutlines = False
@@ -585,20 +583,19 @@
"""Run the QuickLayoutWizard, using the form's named
connection. If none exists, ask the user to select one.
"""
- sel = self.app.Selection
- if len(sel) > 1:
- dabo.ui.stop(_("Please select a single target slot
before running the wizard"),
- _("Multiple Selection"))
- return
- elif not isinstance(sel[0], LayoutPanel):
- dabo.ui.stop(_("Please select a target slot before
running the wizard"),
- _("No Slot Selected"))
- return
+ if self.UseSizers:
+ pnl = self.app.getActivePanel()
+ if pnl is None:
+ dabo.ui.stop(_("Please right-click on the
target slot"),
+ _("No target"))
+ return
+ elif not isinstance(pnl, LayoutPanel):
+ dabo.ui.stop(_("Please select a target slot
before running the wizard"),
+ _("No Slot Selected"))
+ return
wiz = QuickLayoutWizard(self)
- res = wiz.setConnectionName(self._namedConnection)
- if res is False:
- # No connection was established
- return
+ wiz.ConnectionFile = self.CxnFile
+ wiz.ConnectionName = self.CxnName
wiz.callback = self.addQuickLayout
wiz.start()
if wiz:
Modified: trunk/ClassDesignerMenu.py
===================================================================
--- trunk/ClassDesignerMenu.py 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/ClassDesignerMenu.py 2006-10-10 01:06:52 UTC (rev 647)
@@ -110,8 +110,4 @@
for ctl in ctlList:
itm = cm.append(ctl[1], parent.onAddControl)
itm.DynamicEnabled = app.shouldEnableAddControl
-
- # Add the DE menuitem
- fm.prepend(_("Quick Layout Wizard"),
bindfunc=target.onRunLayoutWiz,
- help=_("Quickly create a page layout
for a table"))
Modified: trunk/sample.cnxml
===================================================================
--- trunk/sample.cnxml 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/sample.cnxml 2006-10-10 01:06:52 UTC (rev 647)
@@ -5,6 +5,7 @@
xsi:noNamespaceSchemaLocation = "http://dabodev.com/schema/conn.xsd">
<connection dbtype="MySQL">
+ <name>sample</name>
<host>dabodev.com</host>
<database>webtest</database>
<user>webuser</user>
Modified: trunk/wizards/QuickLayoutWizard.py
===================================================================
--- trunk/wizards/QuickLayoutWizard.py 2006-10-09 19:02:47 UTC (rev 646)
+++ trunk/wizards/QuickLayoutWizard.py 2006-10-10 01:06:52 UTC (rev 647)
@@ -143,8 +143,8 @@
flds = fldDict.keys()
flds.sort()
pktext={True:"X", False:""}
- typeText = {"C" : "char", "I": "int", "M" : "text", "D" :
"date",
- "T" : "datetime", "B" : "bool", "N" : "float",
"E" : "enum"}
+ typeText = {"C": "char", "I": "int", "M": "text", "D": "date",
"L": "blob",
+ "T": "datetime", "B": "bool", "N": "float",
"E": "enum"}
fldInfo = [ (pktext[fldDict[p]["pk"]],
typeText[fldDict[p]["type"]], p ) for p in flds]
self.lstFields.appendRows(fldInfo)
@@ -298,8 +298,15 @@
self.lastStyle = layType
# Create the new controls
- sp = self.samplePanel = dabo.ui.dScrollPanel(self,
BackColor="papayawhip")
- self.Sizer.append1x(sp, border=30, borderSides="top")
+ lbl = dabo.ui.dLabel(self, Caption=_("Double-click a caption to
edit"),
+ FontSize=8, FontItalic=True)
+ self.Sizer.append(lbl, halign="center", border=30,
borderSides="top")
+ lbl = dabo.ui.dLabel(self, Caption=_("Right-click a control to
change its type"),
+ FontSize=8, FontItalic=True)
+ self.Sizer.append(lbl, halign="center", border=3,
borderSides="top")
+ sp = self.samplePanel = dabo.ui.dScrollPanel(self,
BackColor="papayawhip",
+ HorizontalScroll=False)
+ itm = self.Sizer.append1x(sp, border=3, borderSides="top")
sp.Sizer = LayoutSizer("v")
if layType.lower() == "grid":
self.makeGrid()
@@ -321,6 +328,7 @@
self._labels.append(lbl)
cls = dabo.ui.dTextBox
ctl = cls(sp)
+ ctl.bindEvent(dEvents.ContextMenu, self.onCtlRightClick)
cs.append(lbl, halign=self.LabelAlignment)
if style == "above":
@@ -333,7 +341,6 @@
fdc["control"] = ctl
fdc["controlClass"] = cls
fdc["width"] = None
-
if (style == "above") and not fld == flds[-1]:
# We're not on the last field, so add a spacer
cs.appendSpacer(self.BetweenSpacing)
@@ -388,8 +395,60 @@
self.Sizer.append(gs, 0, halign="center")
self.refresh()
self.layout()
+
+ def onCtlRightClick(self, evt):
+ self._editedControl = evt.EventObject
+ pop = dabo.ui.dMenu()
+ currclass = self._editedControl.__class__
+ if not currclass is dabo.ui.dTextBox:
+ pop.append(_("Plain Textbox"),
bindfunc=self.onChangeControl)
+ if not currclass is dabo.ui.dDateTextBox:
+ pop.append(_("Date Textbox"),
bindfunc=self.onChangeControl)
+ if not currclass is dabo.ui.dEditBox:
+ pop.append(_("Edit Box"), bindfunc=self.onChangeControl)
+ if not currclass is dabo.ui.dCheckBox:
+ pop.append(_("Check Box"),
bindfunc=self.onChangeControl)
+ if not currclass is dabo.ui.dSpinner:
+ pop.append(_("Spinner"), bindfunc=self.onChangeControl)
+# pop.append(_(""), bindfunc=self.onChangeControl)
+ dabo.ui.callAfter(self.showContextMenu, pop)
+ evt.stop()
+
+
+ def onChangeControl(self, evt):
+ #### ALSO: need to update the wizard's fields
+# self.editLabel.Caption = tx
+# self.controls[self.editLabel.origCap]["caption"] = tx
+ chc = evt.prompt
+ classes = {_("Plain Textbox"): dabo.ui.dTextBox,
+ _("Date Textbox"): dabo.ui.dDateTextBox,
+ _("Edit Box"): dabo.ui.dEditBox,
+ _("Check Box"): dabo.ui.dCheckBox,
+ _("Spinner"): dabo.ui.dSpinner}
+ cls = classes[chc]
+ obj = self._editedControl
+ self._editedControl = None
+ sz = obj.ControllingSizer
+ row, col = sz.getGridPos(obj)
+ newobj = cls(obj.Parent)
+ newobj.unbindEvent(dEvents.ContextMenu)
+ newobj.unbindEvent(dEvents.MouseRightClick)
+ newobj.bindEvent(dEvents.ContextMenu, self.onCtlRightClick)
+ # Update the wizard's field dict
+ key = [kk for kk in self.controls.keys()
+ if self.controls[kk]["control"] is obj][0]
+ self.controls[key]["control"] = newobj
+ self.controls[key]["controlClass"] = cls
+ sz.remove(obj, destroy=True)
+ if "above" in self.Wizard.layoutType.lower():
+ sz.append(newobj, "expand", row=row, col=col,
borderSides="bottom")
+ else:
+ sz.append(newobj, "expand", row=row, col=col)
+ self.layout()
+
+
def onLblEdit(self, evt):
lbl = self.editLabel = evt.EventObject
oldCap = lbl.Caption
@@ -504,8 +563,8 @@
inf = {}
for col in self.grid.Columns:
fld = col.Field
- inf[fld] = {"caption" : col.Caption,
"controlClass" : None,
- "width" : col.Width}
+ inf[fld] = {"caption": col.Caption,
"controlClass": None,
+ "width": col.Width}
self.Wizard.controlInfo = inf
else:
self.Wizard.controlInfo = self.controls
@@ -553,7 +612,9 @@
def _setOutsideBorder(self, val):
self._outsideBorder = val
- self.samplePanel.Sizer.Border = val
+ sps = self.samplePanel.Sizer
+ cs = sps.Children[0]
+ sps.setItemProp(cs, "Border", val)
self.samplePanel.layout()
@@ -587,17 +648,31 @@
self.tbl = ""
self.availableLayouts = ["Column; labels on Left", "Column;
labels above", "Grid"]
self.layoutType = ""
+
+
+ def start(self):
pgs = [PgConnectionSelect, PgSelect, PgOrdering, PgLayout,
PgSample]
+ cxn = False
+ if self.ConnectionName:
+ cxn = self.makeConnection(showAlert=False)
+ if cxn:
+ # We don't need the connection selector page
+ pgs.pop(0)
self.append(pgs)
-
+ super(QuickLayoutWizard, self).start()
+
- def makeConnection(self):
+ def makeConnection(self, showAlert=True):
+ if self.ConnectionFile:
+ self.Application.addConnectFile(self.ConnectionFile)
try:
conn =
self.Application.getConnectionByName(self.ConnectionName)
crs = conn.getDaboCursor()
+ self.ConnectionFile =
self.Application.dbConnectionNameToFiles[self.ConnectionName]
except StandardError, e:
- dabo.ui.stop(_("Could not make connection to '%s'") %
- self.ConnectionName)
+ if showAlert:
+ dabo.ui.stop(_("Could not make connection to
'%s'") %
+ self.ConnectionName)
return False
tbls = crs.getTables()
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev