| 1 |
<?xml version="1.0" encoding="utf-8" standalone="no"?> |
|---|
| 2 |
<dForm Name="dForm" Caption="Dabo Preference Editor" SaveRestorePosition="False" Top="130" Height="658" Width="707" designerClass="DesForm" Left="366"> |
|---|
| 3 |
<code> |
|---|
| 4 |
<expandAll><![CDATA[ |
|---|
| 5 |
def expandAll(self): |
|---|
| 6 |
self.tree.expandAll() |
|---|
| 7 |
]]> |
|---|
| 8 |
</expandAll> |
|---|
| 9 |
<savePref><![CDATA[ |
|---|
| 10 |
def savePref(self): |
|---|
| 11 |
nd = self.tree.Selection |
|---|
| 12 |
key = self.tree.getKeyPathForNode(nd) |
|---|
| 13 |
val = self.txtPrefValue.Value |
|---|
| 14 |
self.pref.setValue(key, val) |
|---|
| 15 |
]]> |
|---|
| 16 |
</savePref> |
|---|
| 17 |
<syncTree><![CDATA[ |
|---|
| 18 |
def syncTree(self, key): |
|---|
| 19 |
nodes = self.tree.nodes |
|---|
| 20 |
ret = [n for n in nodes |
|---|
| 21 |
if n.FullCaption.endswith(key) ] |
|---|
| 22 |
if ret: |
|---|
| 23 |
self.tree.Selection = ret[0] |
|---|
| 24 |
]]> |
|---|
| 25 |
</syncTree> |
|---|
| 26 |
<collapseAll><![CDATA[ |
|---|
| 27 |
def collapseAll(self): |
|---|
| 28 |
self.tree.collapseAll() |
|---|
| 29 |
]]> |
|---|
| 30 |
</collapseAll> |
|---|
| 31 |
<deletePref><![CDATA[ |
|---|
| 32 |
def deletePref(self, key): |
|---|
| 33 |
self.pref.deletePref(key, nested=True) |
|---|
| 34 |
]]> |
|---|
| 35 |
</deletePref> |
|---|
| 36 |
<afterInit><![CDATA[ |
|---|
| 37 |
def afterInit(self): |
|---|
| 38 |
self.pth = "" |
|---|
| 39 |
self.BasePrefKey = "dabo.ide.PrefEditor" |
|---|
| 40 |
]]> |
|---|
| 41 |
</afterInit> |
|---|
| 42 |
<afterInitAll><![CDATA[ |
|---|
| 43 |
def afterInitAll(self): |
|---|
| 44 |
self.pref = dabo.dPref("") |
|---|
| 45 |
self.pref.AutoPersist = False |
|---|
| 46 |
self.pref._persistAll = True |
|---|
| 47 |
stru = self.pref.getPrefTree() |
|---|
| 48 |
root = self.tree.getRootNode() |
|---|
| 49 |
if root: |
|---|
| 50 |
root.Caption = "" |
|---|
| 51 |
self.tree.treeFromStructure(stru, topNode=root) |
|---|
| 52 |
basenode = self.tree.nodes[1] |
|---|
| 53 |
[sib.expand() for sib in basenode.Siblings] |
|---|
| 54 |
self.tree.ShowRootNode = False |
|---|
| 55 |
]]> |
|---|
| 56 |
</afterInitAll> |
|---|
| 57 |
<getNodeValue><![CDATA[ |
|---|
| 58 |
def getNodeValue(self, nd): |
|---|
| 59 |
pth = self.tree.getKeyPathForNode(nd) |
|---|
| 60 |
ret = self.pref.getValue(pth) |
|---|
| 61 |
]]> |
|---|
| 62 |
</getNodeValue> |
|---|
| 63 |
<exit><![CDATA[ |
|---|
| 64 |
def exit(self, saving): |
|---|
| 65 |
if saving: |
|---|
| 66 |
self.pref.persist() |
|---|
| 67 |
self.release() |
|---|
| 68 |
]]> |
|---|
| 69 |
</exit> |
|---|
| 70 |
<filterPrefs><![CDATA[ |
|---|
| 71 |
def filterPrefs(self): |
|---|
| 72 |
filt = "%%" + self.txtFilter.Value.strip() |
|---|
| 73 |
ds = [] |
|---|
| 74 |
ds0 = self.pref.getPrefs(returnNested=True, key=filt, asDataSet=True) |
|---|
| 75 |
if ds0: |
|---|
| 76 |
ds = ds0.execute("select *,lower(ckey) as lowkey from dataset order by lowkey") |
|---|
| 77 |
grd = self.grdFilteredPrefs |
|---|
| 78 |
grd.DataSet = ds |
|---|
| 79 |
#grd.autoSizeCol("all") |
|---|
| 80 |
numMatch = len(ds) |
|---|
| 81 |
if numMatch == 1: |
|---|
| 82 |
suffix = "" |
|---|
| 83 |
else: |
|---|
| 84 |
suffix = "es" |
|---|
| 85 |
self.lblResults.Caption = "%(numMatch)s Match%(suffix)s" % locals() |
|---|
| 86 |
]]> |
|---|
| 87 |
</filterPrefs> |
|---|
| 88 |
<addPref><![CDATA[ |
|---|
| 89 |
def addPref(self, base, key, typ): |
|---|
| 90 |
if base: |
|---|
| 91 |
newkey = "%s.%s" % (base, key) |
|---|
| 92 |
else: |
|---|
| 93 |
newkey = key |
|---|
| 94 |
if typ == "Node": |
|---|
| 95 |
# Just set the node |
|---|
| 96 |
eval("self.pref.%s" % newkey) |
|---|
| 97 |
else: |
|---|
| 98 |
typDict = {"String": str, "Unicode": unicode, "Integer": int, "Float": float, |
|---|
| 99 |
"Boolean": bool, "List": list, "Tuple": tuple, "Dict": dict, |
|---|
| 100 |
"Datetime": datetime.datetime, "Date": datetime.date} |
|---|
| 101 |
self.pref.addKey(newkey, typDict[typ], typDict[typ]()) |
|---|
| 102 |
]]> |
|---|
| 103 |
</addPref> |
|---|
| 104 |
<updatePref><![CDATA[ |
|---|
| 105 |
def updatePref(self): |
|---|
| 106 |
if not self or not self.tree: |
|---|
| 107 |
return |
|---|
| 108 |
nd = self.tree.Selection |
|---|
| 109 |
self.pth = self.tree.getKeyPathForNode(nd) |
|---|
| 110 |
val = self.pref.getValue(self.pth) |
|---|
| 111 |
self.txtPrefName.Value = nd.Caption |
|---|
| 112 |
if val is not None: |
|---|
| 113 |
self.txtPrefValue.Value = val |
|---|
| 114 |
else: |
|---|
| 115 |
self.txtPrefValue.Value = "" |
|---|
| 116 |
self.txtPrefValue.Enabled = (val is not None) |
|---|
| 117 |
self.ddType.Value = type(val) |
|---|
| 118 |
self.update() |
|---|
| 119 |
]]> |
|---|
| 120 |
</updatePref> |
|---|
| 121 |
<importStatements><![CDATA[ |
|---|
| 122 |
import datetime |
|---|
| 123 |
from dabo.dLocalize import _ |
|---|
| 124 |
]]> |
|---|
| 125 |
</importStatements> |
|---|
| 126 |
</code> |
|---|
| 127 |
|
|---|
| 128 |
<dSizer SlotCount="1" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 129 |
<dPanel sizerInfo="{'VAlign': 'Middle'}" designerClass="controlMix"> |
|---|
| 130 |
<dSizer SlotCount="3" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 131 |
<dTextBox sizerInfo="{}" ReadOnly="True" FontSize="10.5" DataField="pth" designerClass="controlMix" Alignment="Center" DataSource="None"></dTextBox> |
|---|
| 132 |
<dSizer SlotCount="1" sizerInfo="{'BorderSides': ['All'], 'Proportion': 1, 'HAlign': 'Left', 'VAlign': 'Top', 'Border': 0, 'Expand': True}" designerClass="LayoutSizer" Orientation="Horizontal"> |
|---|
| 133 |
<dPageFrame RegID="mainPageFrame" sizerInfo="{'HAlign': 'Center'}" designerClass="controlMix" PageCount="2"> |
|---|
| 134 |
<dPage Caption="Tree" designerClass="controlMix"> |
|---|
| 135 |
<dSizer SlotCount="2" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 136 |
<dSplitter sizerInfo="{'VAlign': 'Middle'}" SashPosition="260" Orientation="Vertical" MinimumPanelSize="80" ShowPanelSplitMenu="True" designerClass="controlMix" Split="True"> |
|---|
| 137 |
<dPanel Width="258" designerClass="MixedSplitterPanel" Name="dPanel2" Height="456"> |
|---|
| 138 |
<dSizer SlotCount="1" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 139 |
<dTreeView RegID="tree" sizerInfo="{'Proportion': 2, 'VAlign': 'Middle'}" designerClass="controlMix" Name="treePrefs" ShowRootNode="False"> |
|---|
| 140 |
<code> |
|---|
| 141 |
<getKeyPathForNode><![CDATA[ |
|---|
| 142 |
def getKeyPathForNode(self, node): |
|---|
| 143 |
nds = [node.Caption] |
|---|
| 144 |
prnt = node.parent |
|---|
| 145 |
while prnt: |
|---|
| 146 |
if prnt.Caption: |
|---|
| 147 |
nds.insert(0, prnt.Caption) |
|---|
| 148 |
prnt = prnt.parent |
|---|
| 149 |
return ".".join(nds) |
|---|
| 150 |
]]> |
|---|
| 151 |
</getKeyPathForNode> |
|---|
| 152 |
<onAddChild><![CDATA[ |
|---|
| 153 |
def onAddChild(self, evt): |
|---|
| 154 |
nd = self.Selection |
|---|
| 155 |
basekey = self.getKeyPathForNode(nd) |
|---|
| 156 |
ctls = ((_("Preference Name?"), unicode, "prefname"), |
|---|
| 157 |
(_("Type:"), ["String", "Unicode", "Integer", |
|---|
| 158 |
"Float", "Boolean", "List", "Tuple", "Dict", "Datetime", "Date"], "typ") ) |
|---|
| 159 |
dlg = dabo.ui.dOkCancelDialog(self, Caption=_("Add Child Key")) |
|---|
| 160 |
dlg.addControlSequence(ctls) |
|---|
| 161 |
dlg.typ.Value = "Unicode" |
|---|
| 162 |
dlg.show() |
|---|
| 163 |
if dlg.Accepted: |
|---|
| 164 |
prf = dlg.prefname.Value |
|---|
| 165 |
typ = dlg.typ.Value |
|---|
| 166 |
self.Form.addPref(basekey, prf, typ) |
|---|
| 167 |
for kid in prf.split("."): |
|---|
| 168 |
nd = nd.appendChild(kid) |
|---|
| 169 |
]]> |
|---|
| 170 |
</onAddChild> |
|---|
| 171 |
<onDeleteNode><![CDATA[ |
|---|
| 172 |
def onDeleteNode(self, evt): |
|---|
| 173 |
nd = self.Selection |
|---|
| 174 |
key = self.getKeyPathForNode(nd) |
|---|
| 175 |
self.Form.deletePref(key) |
|---|
| 176 |
self.removeNode(nd) |
|---|
| 177 |
]]> |
|---|
| 178 |
</onDeleteNode> |
|---|
| 179 |
<onTreeSelection><![CDATA[ |
|---|
| 180 |
def onTreeSelection(self, evt): |
|---|
| 181 |
dabo.ui.callAfter(self.Form.updatePref) |
|---|
| 182 |
]]> |
|---|
| 183 |
</onTreeSelection> |
|---|
| 184 |
<onContextMenu><![CDATA[ |
|---|
| 185 |
def onContextMenu(self, evt): |
|---|
| 186 |
node = self.Selection |
|---|
| 187 |
pop = dabo.ui.dMenu() |
|---|
| 188 |
pop.append(_("Delete"), OnHit=self.onDeleteNode) |
|---|
| 189 |
currVal = self.Form.getNodeValue(node) |
|---|
| 190 |
if currVal is None: |
|---|
| 191 |
# This is branch, not a value node |
|---|
| 192 |
pop.append(_("Add Child"), OnHit=self.onAddChild) |
|---|
| 193 |
self.showContextMenu(pop) |
|---|
| 194 |
]]> |
|---|
| 195 |
</onContextMenu> |
|---|
| 196 |
</code> |
|---|
| 197 |
</dTreeView> |
|---|
| 198 |
</dSizer> |
|---|
| 199 |
</dPanel> |
|---|
| 200 |
<dPanel Width="432" designerClass="MixedSplitterPanel" Name="dPanel1" Height="456"> |
|---|
| 201 |
<dSizer SlotCount="1" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 202 |
<dGridSizer HGap="3" sizerInfo="{'BorderSides': ['All'], 'Proportion': 1, 'HAlign': 'Left', 'VAlign': 'Top', 'Border': 30, 'Expand': True}" Rows="3" designerClass="LayoutGridSizer" VGap="10" Columns="2"> |
|---|
| 203 |
<dTextBox RegID="txtPrefName" ReadOnly="True" designerClass="controlMix" sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'Proportion': 0}" rowColPos="(0, 1)"></dTextBox> |
|---|
| 204 |
<dTextBox RegID="txtPrefValue" sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'Proportion': 0}" designerClass="controlMix" Name="dTextBox1" rowColPos="(1, 1)"> |
|---|
| 205 |
<code> |
|---|
| 206 |
<onKeyUp><![CDATA[ |
|---|
| 207 |
def onKeyUp(self, evt): |
|---|
| 208 |
dabo.ui.callAfterInterval(250, self.Form.savePref()) |
|---|
| 209 |
]]> |
|---|
| 210 |
</onKeyUp> |
|---|
| 211 |
</code> |
|---|
| 212 |
</dTextBox> |
|---|
| 213 |
<dDropdownList sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'HAlign': 'Left', 'ColExpand': True}" rowColPos="(2, 1)" Choices="[u'-None-', u'String', u'Unicode', u'Integer', u'Float', u'Boolean', u'List', u'Tuple', u'Dict', u'Datetime', u'Date']" Width="105" designerClass="controlMix" RegID="ddType"> |
|---|
| 214 |
<code> |
|---|
| 215 |
<afterInit><![CDATA[ |
|---|
| 216 |
def afterInit(self): |
|---|
| 217 |
self.Keys = [type(None), str, unicode, int, float, bool, list, tuple, dict, datetime.datetime, datetime.date] |
|---|
| 218 |
self.ValueMode = "Key" |
|---|
| 219 |
]]> |
|---|
| 220 |
</afterInit> |
|---|
| 221 |
</code> |
|---|
| 222 |
</dDropdownList> |
|---|
| 223 |
<dLabel Caption="Pref Name:" sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'HAlign': 'Right'}" designerClass="controlMix" rowColPos="(0, 0)"></dLabel> |
|---|
| 224 |
<dLabel Caption="Value:" sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'HAlign': 'Right'}" designerClass="controlMix" Name="dLabel1" rowColPos="(1, 0)"></dLabel> |
|---|
| 225 |
<dLabel Caption="Type:" sizerInfo="{'RowSpan': 1, 'ColSpan': 1, 'HAlign': 'Right'}" designerClass="controlMix" Name="dLabel2" rowColPos="(2, 0)"></dLabel> |
|---|
| 226 |
</dGridSizer> |
|---|
| 227 |
</dSizer> |
|---|
| 228 |
</dPanel> |
|---|
| 229 |
</dSplitter> |
|---|
| 230 |
<dSizer SlotCount="2" DefaultBorder="4" sizerInfo="{'BorderSides': ['All'], 'Proportion': 0, 'HAlign': 'Center', 'VAlign': 'Top', 'Border': 0, 'Expand': False}" designerClass="LayoutSizer" Orientation="Horizontal"> |
|---|
| 231 |
<dButton Width="92" sizerInfo="{}" designerClass="controlMix" Caption="Expand All"> |
|---|
| 232 |
<code> |
|---|
| 233 |
<onHit><![CDATA[ |
|---|
| 234 |
def onHit(self, evt): |
|---|
| 235 |
self.Form.expandAll() |
|---|
| 236 |
]]> |
|---|
| 237 |
</onHit> |
|---|
| 238 |
</code> |
|---|
| 239 |
</dButton> |
|---|
| 240 |
<dButton Width="99" sizerInfo="{}" designerClass="controlMix" Name="dButton1" Caption="Collapse All"> |
|---|
| 241 |
<code> |
|---|
| 242 |
<onHit><![CDATA[ |
|---|
| 243 |
def onHit(self, evt): |
|---|
| 244 |
self.Form.collapseAll() |
|---|
| 245 |
]]> |
|---|
| 246 |
</onHit> |
|---|
| 247 |
</code> |
|---|
| 248 |
</dButton> |
|---|
| 249 |
</dSizer> |
|---|
| 250 |
</dSizer> |
|---|
| 251 |
</dPage> |
|---|
| 252 |
<dPage Caption="Filter" designerClass="controlMix" Name="dPage1"> |
|---|
| 253 |
<code> |
|---|
| 254 |
<onPageEnter><![CDATA[ |
|---|
| 255 |
def onPageEnter(self, evt): |
|---|
| 256 |
self.txtFilter.SetFocus() |
|---|
| 257 |
]]> |
|---|
| 258 |
</onPageEnter> |
|---|
| 259 |
</code> |
|---|
| 260 |
|
|---|
| 261 |
<dSizer SlotCount="4" designerClass="LayoutSizer" Orientation="Vertical"> |
|---|
| 262 |
<dBorderSizer SlotCount="1" Caption="Filter Expression" sizerInfo="{'BorderSides': ['Right'], 'Proportion': 0, 'HAlign': 'Left', 'VAlign': 'Top', 'Border': 200, 'Expand': True}" designerClass="LayoutBorderSizer" Orientation="Horizontal"> |
|---|
| 263 |
<dTextBox RegID="txtFilter" Width="479" sizerInfo="{}" designerClass="controlMix" Name="txtFilter"> |
|---|
| 264 |
<code> |
|---|
| 265 |
<onKeyChar><![CDATA[ |
|---|
| 266 |
def onKeyChar(self, evt): |
|---|
| 267 |
dabo.ui.callAfter(self.Form.filterPrefs) |
|---|
| 268 |
]]> |
|---|
| 269 |
</onKeyChar> |
|---|
| 270 |
</code> |
|---|
| 271 |
</dTextBox> |
|---|
| 272 |
</dBorderSizer> |
|---|
| 273 |
<dGrid ColumnCount="2" sizerInfo="{}" Name="grdFilteredPrefs" designerClass="controlMix" RegID="grdFilteredPrefs" SelectionMode="Row"> |
|---|
| 274 |
<code> |
|---|
| 275 |
<rowChanged><![CDATA[ |
|---|
| 276 |
def rowChanged(self): |
|---|
| 277 |
try: |
|---|
| 278 |
key = self.DataSet[self.CurrentRow]["ckey"] |
|---|
| 279 |
self.Form.syncTree(key) |
|---|
| 280 |
except: |
|---|
| 281 |
# Data set has not yet been set |
|---|
| 282 |
pass |
|---|
| 283 |
]]> |
|---|
| 284 |
</rowChanged> |
|---|
| 285 |
<onGridMouseLeftDoubleClick><![CDATA[ |
|---|
| 286 |
def onGridMouseLeftDoubleClick(self, evt): |
|---|
| 287 |
self.Form.mainPageFrame.SelectedPageNumber = 0 |
|---|
| 288 |
]]> |
|---|
| 289 |
</onGridMouseLeftDoubleClick> |
|---|
| 290 |
<onGridCellSelected><![CDATA[ |
|---|
| 291 |
def onGridCellSelected(self, evt): |
|---|
| 292 |
if evt.row != self.CurrentRow: |
|---|
| 293 |
dabo.ui.callAfter(self.rowChanged) |
|---|
| 294 |
]]> |
|---|
| 295 |
</onGridCellSelected> |
|---|
| 296 |
</code> |
|---|
| 297 |
|
|---|
| 298 |
<dColumn FontSize="9" HeaderFontFace="Arial" Caption="Preference" Width="497" designerClass="controlMix" HorizontalAlignment="Left" FontFace="Arial" HeaderFontSize="9" Order="0" DataField="ckey"></dColumn> |
|---|
| 299 |
<dColumn FontSize="9" HeaderFontFace="Arial" Caption="Value" Width="123" designerClass="controlMix" HorizontalAlignment="Left" FontFace="Arial" HeaderFontSize="9" Order="10" DataField="cvalue"></dColumn> |
|---|
| 300 |
</dGrid> |
|---|
| 301 |
<dLabel RegID="lblResults" Caption="-" sizerInfo="{}" designerClass="controlMix"></dLabel> |
|---|
| 302 |
<dPanel sizerInfo="{'BorderSides': ['All'], 'HAlign': 'Left', 'VAlign': 'Top', 'Border': 10}" designerClass="LayoutPanel"></dPanel> |
|---|
| 303 |
</dSizer> |
|---|
| 304 |
</dPage> |
|---|
| 305 |
</dPageFrame> |
|---|
| 306 |
</dSizer> |
|---|
| 307 |
<dSizer SlotCount="3" sizerInfo="{'BorderSides': ['All'], 'Proportion': 0, 'HAlign': 'Right', 'VAlign': 'Bottom', 'Border': 20, 'Expand': False}" designerClass="LayoutSizer" Orientation="Horizontal"> |
|---|
| 308 |
<dButton Width="104" sizerInfo="{}" designerClass="controlMix" Name="dButton21" Caption="Exit, no save"> |
|---|
| 309 |
<code> |
|---|
| 310 |
<onHit><![CDATA[ |
|---|
| 311 |
def onHit(self, evt): |
|---|
| 312 |
self.Form.exit(False) |
|---|
| 313 |
]]> |
|---|
| 314 |
</onHit> |
|---|
| 315 |
</code> |
|---|
| 316 |
</dButton> |
|---|
| 317 |
<dPanel Spacing="10" sizerInfo="{'BorderSides': ['All'], 'Proportion': 0, 'HAlign': 'Left', 'VAlign': 'Top', 'Border': 0, 'Expand': False}" designerClass="LayoutSpacerPanel"></dPanel> |
|---|
| 318 |
<dButton Width="108" sizerInfo="{}" designerClass="controlMix" Name="dButton11" Caption="Save and Exit"> |
|---|
| 319 |
<code> |
|---|
| 320 |
<onHit><![CDATA[ |
|---|
| 321 |
def onHit(self, evt): |
|---|
| 322 |
self.Form.exit(True) |
|---|
| 323 |
]]> |
|---|
| 324 |
</onHit> |
|---|
| 325 |
</code> |
|---|
| 326 |
</dButton> |
|---|
| 327 |
</dSizer> |
|---|
| 328 |
</dSizer> |
|---|
| 329 |
</dPanel> |
|---|
| 330 |
</dSizer> |
|---|
| 331 |
</dForm> |
|---|