~toolpart/+junk/pythoncard

« back to all changes in this revision

Viewing changes to helpful.py

  • Committer: Bazaar Package Importer
  • Author(s): Sandro Tosi
  • Date: 2010-03-04 23:55:10 UTC
  • mfrom: (3.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20100304235510-3v6lbhzwrgm0pcca
Tags: 0.8.2-1
* QA upload.
* New upstream release
* debian/control
  - set maintainer to QA group
  - set Homepage field, removing the URL from packages description
  - bump versioned b-d-i on python-support, to properly support Python module
  - replace b-d on python-all-dev with python-all, since building only
    arch:all packages
  - replace Source-Version substvar with source:Version
  - add ${misc:Depends} to binary packages Depends
* debian/watch
  - updated to use the SourceForge redirector; thanks to Raphael Geissert for
    the report and to Dario Minnucci for the patch; Closes: #449904
* debian/{pythoncard-doc, python-pythoncard}.install
  - use wildcards instead of site-packages to fix build with python 2.6;
    thanks to Ilya Barygin for the report and patch; Closes: #572332
* debian/pythoncard-doc.doc-base
  - set section to Programmin/Python
* debian/pythoncard-tools.menu
  - set menu main section to Applications
* debian/pythoncard-tools.postinst
  - removed, needed only to update the menu, but it's now created by debhelper

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
__version__ = "$Revision: 1.5 $"
 
3
__date__ = "$Date: 2006/01/14 12:11:49 $"
 
4
"""
 
5
 
 
6
# Assorted helpful wrappers.
 
7
 
 
8
from PythonCard import model
 
9
 
 
10
import wx
 
11
import string, copy
 
12
import types
 
13
 
 
14
 
 
15
# AGT This could probably be generalized some more - but it handles current
 
16
#   needs within this wrapper collection of cloning buttons and checkboxes.
 
17
 
 
18
# utility functions to manipulate controls at run time
 
19
class copyControl:
 
20
    def __init__(self, aBg, Name, newname, Text=""):
 
21
        Flds = ['position', 'size', 'backgroundColor', 'foregroundColor', 'command', 'font']
 
22
        aWidget = aBg.components[Name]
 
23
        d = {}
 
24
        d['type'] = aWidget.__class__.__name__
 
25
        for key in Flds: # attributes
 
26
            # I'm not exactly sure why I have to special-case these tuples
 
27
            if key == 'bitmap':
 
28
                # this should get recreated from the file attribute
 
29
                pass
 
30
            elif key in ['position', 'size']:
 
31
                d[key] = getattr(aWidget, key)
 
32
            elif getattr(aWidget, key) is not None:
 
33
                d[key] = getattr(aWidget, key)
 
34
        if Text == "": Text = newname
 
35
        d['label'] = Text
 
36
        d['name'] = newname
 
37
        aBg.components[newname] = d
 
38
        self.name = newname 
 
39
       
 
40
       
 
41
# dialog to present a block of text and a number of alternative buttons
 
42
class MultiButtonDialog(model.CustomDialog):
 
43
    
 
44
    def __init__(self, parent, txt, buttons, rsrc):
 
45
        model.CustomDialog.__init__(self, parent, rsrc)
 
46
        self.components.Text.text = txt
 
47
        self.components.Button.visible = False
 
48
        self.components.Button.enabled = False
 
49
        if len(buttons) == 0: buttons = ["OK"]
 
50
        bx, by = self.components.Button.size
 
51
        for b in buttons:
 
52
            if isinstance(b, types.StringTypes):
 
53
                self.components.Button.label = b
 
54
            else:
 
55
                self.components.Button.label = b[0]
 
56
            
 
57
            newx, newy = self.components.Button.GetBestSize()
 
58
            bx = max(bx, newx)
 
59
            by = max(by, newy)
 
60
        self.components.Button.size = (bx, newy)
 
61
        dx = bx + 20
 
62
        # check if all buttons will fit in window
 
63
        owx, owy = self.size
 
64
        startx, starty = self.components.Button.position
 
65
        if len(buttons)*dx + bx + 40 > owx:
 
66
            wx = len(buttons)*dx + bx + 40
 
67
            self.size = (wx, owy)
 
68
            startx, starty = (wx-bx-20, owy-by-30)   # AGT - why 30 ??
 
69
            tsx, tsy = self.components.Text.size
 
70
            self.components.Text.size = (wx-20, tsy)
 
71
        localbuttons = buttons
 
72
        localbuttons.reverse()
 
73
        count = 0
 
74
        for b in localbuttons:
 
75
            if isinstance(b, types.StringTypes):
 
76
                theName = b
 
77
                theToolTip = ''
 
78
            else:
 
79
                theName = b[0]
 
80
                theToolTip = b[1]
 
81
            n = copyControl(self, "Button", "Button"+str(count), theName)
 
82
            self.components[n.name].position = startx-count*dx, starty
 
83
            self.components[n.name].visible = True
 
84
            self.components[n.name].enabled = True
 
85
            self.components[n.name].toolTip = theToolTip
 
86
            count += 1
 
87
        self.accepted = False
 
88
        self.text = ""
 
89
   
 
90
    def on_mouseClick(self, event):
 
91
        self.text = event.target.label
 
92
        if self.text == "Cancel":
 
93
            self.accepted = False
 
94
        else:
 
95
            self.accepted = True
 
96
        self.Close()
 
97
 
 
98
def multiButtonDialog(parent, txt, buttons, title=""):
 
99
    rsrc = {'type':'CustomDialog',
 
100
        'name':'Template',
 
101
        'title':'Template',
 
102
        'position':(176, 176),
 
103
        'size':(367, 230),
 
104
        'components': [
 
105
 
 
106
        {'type':'StaticText',
 
107
            'name':'Text',
 
108
            'position':(10, 10),
 
109
            'size':(341, 123),
 
110
            'actionBindings':{},
 
111
            },
 
112
 
 
113
        {'type':'Button',
 
114
           'name':'Button',
 
115
           'position':(269, 145),
 
116
           'actionBindings':{},
 
117
           'label':'template',
 
118
           },
 
119
 
 
120
        ] # end components
 
121
    } # end CustomDialog
 
122
    rsrc["title"] = title
 
123
    dlg = MultiButtonDialog(parent, txt, buttons, rsrc)
 
124
    result = dlg.showModal()
 
125
    result.accepted = dlg.accepted
 
126
    result.text = dlg.text
 
127
    dlg.destroy()
 
128
    return result
 
129
 
 
130
 
 
131
# dialog to present a number of on/off checkboxes
 
132
class MultiCheckBoxDialog(model.CustomDialog):
 
133
    
 
134
    # boxes is a list of (name, value) pairs, not a dictionary
 
135
    # because a dictionary didn't allow the caller to control the order of presentation
 
136
    def __init__(self, parent, boxes, rsrc):
 
137
        model.CustomDialog.__init__(self, parent, rsrc)
 
138
        self.components.box.visible = False
 
139
        self.components.box.enabled = False
 
140
        self.components.box.checked = False
 
141
        # check if all buttons will fit in window
 
142
        owx, owy = self.size
 
143
        startx, starty = self.components.box.position
 
144
        sx,sy = self.components.box.GetBestSize()
 
145
        #rint starty, len(boxes), sy, (len(boxes)-1) * (sy+20), owy
 
146
        wy = (len(boxes)+1) * (sy+20) + 30
 
147
        self.size = (owx, wy)
 
148
            
 
149
        count = 0
 
150
        self.boxes = {}
 
151
        for b in boxes:
 
152
            val = False
 
153
            toolTip = ''
 
154
            if isinstance(b, types.StringTypes):
 
155
                key = b
 
156
            else:
 
157
                key = b[0]
 
158
                if len(b) > 1: val = b[1]
 
159
                if len(b) > 2: toolTip = b[2]
 
160
            n = copyControl(self, "box", "Box"+str(count), key)
 
161
            self.components[n.name].position = startx, starty+count*(sy+20)
 
162
            self.components[n.name].visible = True
 
163
            self.components[n.name].enabled = True
 
164
            self.components[n.name].checked = val
 
165
            self.components[n.name].toolTip = toolTip
 
166
            self.boxes[key] = val
 
167
            count += 1
 
168
        self.components.btnOK.position = (150, starty+count*(sy+20))
 
169
        self.components.btnCancel.position = (250, starty+count*(sy+20))
 
170
        self.accepted = False
 
171
   
 
172
    def on_btnOK_mouseClick(self, event):
 
173
        self.accepted = True
 
174
 
 
175
        for count in range(len(self.boxes)):
 
176
            name = "Box"+str(count)
 
177
            self.boxes[self.components[name].label] = self.components[name].checked
 
178
        
 
179
        self.Close()
 
180
 
 
181
    def on_btnCancel_mouseClick(self, event):
 
182
        self.accepted = False
 
183
        self.Close()
 
184
 
 
185
def multiCheckBoxDialog(parent, boxes, title=""):
 
186
    rsrc = {'type':'CustomDialog',
 
187
        'name':'Template',
 
188
        'title':'Template',
 
189
        'position':(176, 176),
 
190
        'size':(340, 230),
 
191
        'components': [
 
192
 
 
193
        {'type':'CheckBox',
 
194
           'name':'box',
 
195
           'position':(50, 15),
 
196
           'size':(250,20),
 
197
           'actionBindings':{},
 
198
           'label':'template',
 
199
           },
 
200
 
 
201
        {'type':'Button',
 
202
           'name':'btnOK',
 
203
           'position':(250, 0),
 
204
           'actionBindings':{},
 
205
           'label':'OK',
 
206
           },
 
207
 
 
208
        {'type':'Button',
 
209
           'name':'btnCancel',
 
210
           'position':(320, 0),
 
211
           'actionBindings':{},
 
212
           'label':'Cancel',
 
213
           },
 
214
 
 
215
        ] # end components
 
216
    } # end CustomDialog
 
217
    rsrc["title"] = title
 
218
    dlg = MultiCheckBoxDialog(parent, boxes, rsrc)
 
219
    result = dlg.showModal()
 
220
    result.accepted = dlg.accepted
 
221
    result.boxes = dlg.boxes
 
222
    dlg.destroy()
 
223
    return result
 
224
 
 
225
# wrapper to help with pop up menus
 
226
 
 
227
class PopUpMenu:
 
228
    def __init__(self, aBg, items, pos):
 
229
        # Yet another alternate way to do IDs. Some prefer them up top to
 
230
        # avoid clutter, some prefer them close to the object of interest
 
231
        # for clarity. 
 
232
        self.popup = {}
 
233
        self.reverse = {}
 
234
        self.selected = None
 
235
        # make a menu
 
236
        self.menu = wx.Menu()
 
237
        # add the items
 
238
        for it in items:
 
239
            if isinstance(it, types.StringTypes):
 
240
                Id = wx.NewId()
 
241
                self.popup[it] = Id
 
242
                self.reverse[Id] = it
 
243
                aBg.Bind(wx.EVT_MENU, self.OnPopup, id=self.popup[it])
 
244
                self.menu.Append(self.popup[it], it)
 
245
            else:
 
246
                # make a menu
 
247
                submenu = wx.Menu()
 
248
                Id = wx.NewId()
 
249
                aBg.Bind(wx.EVT_MENU, self.OnPopup, id=Id)
 
250
                for that in it:
 
251
                    if isinstance(that, types.StringTypes):
 
252
                        Id = wx.NewId()
 
253
                        self.popup[that] = Id
 
254
                        self.reverse[Id] = that
 
255
                        aBg.Bind(wx.EVT_MENU, self.OnPopup, id=self.popup[that])
 
256
                        submenu.Append(self.popup[that], that)
 
257
                        
 
258
                self.menu.AppendMenu(Id, "Test Submenu", submenu)
 
259
 
 
260
        # Popup the menu.  If an item is selected then its handler
 
261
        # will be called before PopupMenu returns.
 
262
        aBg.PopupMenu(self.menu, pos)
 
263
        self.menu.Destroy()
 
264
               
 
265
    def OnPopup(self, event):
 
266
        self.selected = self.reverse[event.GetId()]
 
267
 
 
268
def popUpMenu(aBg, items, pos):
 
269
    menu = PopUpMenu(aBg, items, pos)
 
270
    
 
271
    return menu.selected
 
272