python-msilib 0.1.1__cp314-cp314t-win_amd64.whl → 0.3.0__cp314-cp314t-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of python-msilib might be problematic. Click here for more details.
- msilib/__init__.py +281 -109
- msilib/_msi.c +333 -358
- msilib/_msi.cp314t-win_amd64.pyd +0 -0
- msilib/include/_msi.h +334 -331
- msilib/include/pythoncapi_compat.h +40 -1
- msilib/schema.py +5752 -1002
- msilib/sequence.py +117 -111
- msilib/text.py +285 -122
- python_msilib-0.3.0.dist-info/METADATA +91 -0
- python_msilib-0.3.0.dist-info/RECORD +13 -0
- python_msilib-0.1.1.dist-info/METADATA +0 -39
- python_msilib-0.1.1.dist-info/RECORD +0 -13
- {python_msilib-0.1.1.dist-info → python_msilib-0.3.0.dist-info}/WHEEL +0 -0
- {python_msilib-0.1.1.dist-info → python_msilib-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {python_msilib-0.1.1.dist-info → python_msilib-0.3.0.dist-info}/top_level.txt +0 -0
msilib/__init__.py
CHANGED
|
@@ -7,28 +7,35 @@ import re
|
|
|
7
7
|
import string
|
|
8
8
|
import sys
|
|
9
9
|
|
|
10
|
-
__version__ = "0.
|
|
10
|
+
__version__ = "0.3.0"
|
|
11
11
|
|
|
12
12
|
AMD64 = "AMD64" in sys.version
|
|
13
13
|
# Keep msilib.Win64 around to preserve backwards compatibility.
|
|
14
14
|
Win64 = AMD64
|
|
15
15
|
|
|
16
16
|
# Partially taken from Wine
|
|
17
|
-
datasizemask=
|
|
18
|
-
type_valid=
|
|
19
|
-
type_localizable=
|
|
20
|
-
|
|
21
|
-
typemask=
|
|
22
|
-
type_long=
|
|
23
|
-
type_short=
|
|
24
|
-
type_string=
|
|
25
|
-
type_binary=
|
|
26
|
-
|
|
27
|
-
type_nullable=
|
|
28
|
-
type_key=
|
|
17
|
+
datasizemask = 0x00FF
|
|
18
|
+
type_valid = 0x0100
|
|
19
|
+
type_localizable = 0x0200
|
|
20
|
+
|
|
21
|
+
typemask = 0x0C00
|
|
22
|
+
type_long = 0x0000
|
|
23
|
+
type_short = 0x0400
|
|
24
|
+
type_string = 0x0C00
|
|
25
|
+
type_binary = 0x0800
|
|
26
|
+
|
|
27
|
+
type_nullable = 0x1000
|
|
28
|
+
type_key = 0x2000
|
|
29
29
|
# XXX temporary, localizable?
|
|
30
|
-
knownbits =
|
|
31
|
-
|
|
30
|
+
knownbits = (
|
|
31
|
+
datasizemask
|
|
32
|
+
| type_valid
|
|
33
|
+
| type_localizable
|
|
34
|
+
| typemask
|
|
35
|
+
| type_nullable
|
|
36
|
+
| type_key
|
|
37
|
+
)
|
|
38
|
+
|
|
32
39
|
|
|
33
40
|
class Table:
|
|
34
41
|
def __init__(self, name):
|
|
@@ -36,13 +43,13 @@ class Table:
|
|
|
36
43
|
self.fields = []
|
|
37
44
|
|
|
38
45
|
def add_field(self, index, name, type):
|
|
39
|
-
self.fields.append((index,name,type))
|
|
46
|
+
self.fields.append((index, name, type))
|
|
40
47
|
|
|
41
48
|
def sql(self):
|
|
42
49
|
fields = []
|
|
43
50
|
keys = []
|
|
44
51
|
self.fields.sort()
|
|
45
|
-
fields = [None]*len(self.fields)
|
|
52
|
+
fields = [None] * len(self.fields)
|
|
46
53
|
for index, name, type in self.fields:
|
|
47
54
|
index -= 1
|
|
48
55
|
unk = type & ~knownbits
|
|
@@ -52,20 +59,20 @@ class Table:
|
|
|
52
59
|
dtype = type & typemask
|
|
53
60
|
if dtype == type_string:
|
|
54
61
|
if size:
|
|
55
|
-
tname="CHAR(%d)" % size
|
|
62
|
+
tname = "CHAR(%d)" % size
|
|
56
63
|
else:
|
|
57
|
-
tname="CHAR"
|
|
64
|
+
tname = "CHAR"
|
|
58
65
|
elif dtype == type_short:
|
|
59
|
-
assert size==2
|
|
66
|
+
assert size == 2
|
|
60
67
|
tname = "SHORT"
|
|
61
68
|
elif dtype == type_long:
|
|
62
|
-
assert size==4
|
|
63
|
-
tname="LONG"
|
|
69
|
+
assert size == 4
|
|
70
|
+
tname = "LONG"
|
|
64
71
|
elif dtype == type_binary:
|
|
65
|
-
assert size==0
|
|
66
|
-
tname="OBJECT"
|
|
72
|
+
assert size == 0
|
|
73
|
+
tname = "OBJECT"
|
|
67
74
|
else:
|
|
68
|
-
tname="unknown"
|
|
75
|
+
tname = "unknown"
|
|
69
76
|
print("%s.%sunknown integer type %d" % (self.name, name, size))
|
|
70
77
|
if type & type_nullable:
|
|
71
78
|
flags = ""
|
|
@@ -78,15 +85,23 @@ class Table:
|
|
|
78
85
|
keys.append("`%s`" % name)
|
|
79
86
|
fields = ", ".join(fields)
|
|
80
87
|
keys = ", ".join(keys)
|
|
81
|
-
return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (
|
|
88
|
+
return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (
|
|
89
|
+
self.name,
|
|
90
|
+
fields,
|
|
91
|
+
keys,
|
|
92
|
+
)
|
|
82
93
|
|
|
83
94
|
def create(self, db):
|
|
84
95
|
v = db.OpenView(self.sql())
|
|
85
96
|
v.Execute(None)
|
|
86
97
|
v.Close()
|
|
87
98
|
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
|
|
100
|
+
class _Unspecified:
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def change_sequence(seq, action, seqno=_Unspecified, cond=_Unspecified):
|
|
90
105
|
"Change the sequence number of an action in a sequence list"
|
|
91
106
|
for i in range(len(seq)):
|
|
92
107
|
if seq[i][0] == action:
|
|
@@ -98,6 +113,7 @@ def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
|
|
|
98
113
|
return
|
|
99
114
|
raise ValueError("Action not found in sequence")
|
|
100
115
|
|
|
116
|
+
|
|
101
117
|
def add_data(db, table, values):
|
|
102
118
|
v = db.OpenView("SELECT * FROM `%s`" % table)
|
|
103
119
|
count = v.GetColumnInfo(MSICOLINFO_NAMES).GetFieldCount()
|
|
@@ -107,34 +123,41 @@ def add_data(db, table, values):
|
|
|
107
123
|
for i in range(count):
|
|
108
124
|
field = value[i]
|
|
109
125
|
if isinstance(field, int):
|
|
110
|
-
r.SetInteger(i+1,field)
|
|
126
|
+
r.SetInteger(i + 1, field)
|
|
111
127
|
elif isinstance(field, str):
|
|
112
|
-
r.SetString(i+1,field)
|
|
128
|
+
r.SetString(i + 1, field)
|
|
113
129
|
elif field is None:
|
|
114
130
|
pass
|
|
115
131
|
elif isinstance(field, Binary):
|
|
116
|
-
r.SetStream(i+1, field.name)
|
|
132
|
+
r.SetStream(i + 1, field.name)
|
|
117
133
|
else:
|
|
118
|
-
raise TypeError(
|
|
134
|
+
raise TypeError(
|
|
135
|
+
"Unsupported type %s" % field.__class__.__name__
|
|
136
|
+
)
|
|
119
137
|
try:
|
|
120
138
|
v.Modify(MSIMODIFY_INSERT, r)
|
|
121
139
|
except Exception:
|
|
122
|
-
raise MSIError(
|
|
140
|
+
raise MSIError(
|
|
141
|
+
"Could not insert " + repr(values) + " into " + table
|
|
142
|
+
)
|
|
123
143
|
|
|
124
144
|
r.ClearData()
|
|
125
145
|
v.Close()
|
|
126
146
|
|
|
127
147
|
|
|
128
148
|
def add_stream(db, name, path):
|
|
129
|
-
v = db.OpenView(
|
|
149
|
+
v = db.OpenView(
|
|
150
|
+
"INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name
|
|
151
|
+
)
|
|
130
152
|
r = CreateRecord(1)
|
|
131
153
|
r.SetStream(1, path)
|
|
132
154
|
v.Execute(r)
|
|
133
155
|
v.Close()
|
|
134
156
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
157
|
+
|
|
158
|
+
def init_database(
|
|
159
|
+
name, schema, ProductName, ProductCode, ProductVersion, Manufacturer
|
|
160
|
+
):
|
|
138
161
|
try:
|
|
139
162
|
os.unlink(name)
|
|
140
163
|
except OSError:
|
|
@@ -147,7 +170,7 @@ def init_database(name, schema,
|
|
|
147
170
|
t.create(db)
|
|
148
171
|
# Fill the validation table
|
|
149
172
|
add_data(db, "_Validation", schema._Validation_records)
|
|
150
|
-
# Initialize the summary information, allowing
|
|
173
|
+
# Initialize the summary information, allowing at most 20 properties
|
|
151
174
|
si = db.GetSummaryInformation(20)
|
|
152
175
|
si.SetProperty(PID_TITLE, "Installation Database")
|
|
153
176
|
si.SetProperty(PID_SUBJECT, ProductName)
|
|
@@ -157,34 +180,45 @@ def init_database(name, schema,
|
|
|
157
180
|
else:
|
|
158
181
|
si.SetProperty(PID_TEMPLATE, "Intel;1033")
|
|
159
182
|
si.SetProperty(PID_REVNUMBER, gen_uuid())
|
|
160
|
-
si.SetProperty(
|
|
183
|
+
si.SetProperty(
|
|
184
|
+
PID_WORDCOUNT, 2
|
|
185
|
+
) # long file names, compressed, original media
|
|
161
186
|
si.SetProperty(PID_PAGECOUNT, 200)
|
|
162
187
|
si.SetProperty(PID_APPNAME, "Python MSI Library")
|
|
163
188
|
# XXX more properties
|
|
164
189
|
si.Persist()
|
|
165
|
-
add_data(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
190
|
+
add_data(
|
|
191
|
+
db,
|
|
192
|
+
"Property",
|
|
193
|
+
[
|
|
194
|
+
("ProductName", ProductName),
|
|
195
|
+
("ProductCode", ProductCode),
|
|
196
|
+
("ProductVersion", ProductVersion),
|
|
197
|
+
("Manufacturer", Manufacturer),
|
|
198
|
+
("ProductLanguage", "1033"),
|
|
199
|
+
],
|
|
200
|
+
)
|
|
171
201
|
db.Commit()
|
|
172
202
|
return db
|
|
173
203
|
|
|
204
|
+
|
|
174
205
|
def add_tables(db, module):
|
|
175
206
|
for table in module.tables:
|
|
176
207
|
add_data(db, table, getattr(module, table))
|
|
177
208
|
|
|
209
|
+
|
|
178
210
|
def make_id(str):
|
|
179
211
|
identifier_chars = string.ascii_letters + string.digits + "._"
|
|
180
212
|
str = "".join([c if c in identifier_chars else "_" for c in str])
|
|
181
213
|
if str[0] in (string.digits + "."):
|
|
182
214
|
str = "_" + str
|
|
183
|
-
assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
|
|
215
|
+
assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE" + str
|
|
184
216
|
return str
|
|
185
217
|
|
|
218
|
+
|
|
186
219
|
def gen_uuid():
|
|
187
|
-
return "{"+UuidCreate().upper()+"}"
|
|
220
|
+
return "{" + UuidCreate().upper() + "}"
|
|
221
|
+
|
|
188
222
|
|
|
189
223
|
class CAB:
|
|
190
224
|
def __init__(self, name):
|
|
@@ -213,17 +247,31 @@ class CAB:
|
|
|
213
247
|
|
|
214
248
|
def commit(self, db):
|
|
215
249
|
from tempfile import mktemp
|
|
250
|
+
|
|
216
251
|
filename = mktemp()
|
|
217
252
|
FCICreate(filename, self.files)
|
|
218
|
-
add_data(
|
|
219
|
-
|
|
253
|
+
add_data(
|
|
254
|
+
db, "Media", [(1, self.index, None, "#" + self.name, None, None)]
|
|
255
|
+
)
|
|
220
256
|
add_stream(db, self.name, filename)
|
|
221
257
|
os.unlink(filename)
|
|
222
258
|
db.Commit()
|
|
223
259
|
|
|
260
|
+
|
|
224
261
|
_directories = set()
|
|
262
|
+
|
|
263
|
+
|
|
225
264
|
class Directory:
|
|
226
|
-
def __init__(
|
|
265
|
+
def __init__(
|
|
266
|
+
self,
|
|
267
|
+
db,
|
|
268
|
+
cab,
|
|
269
|
+
basedir,
|
|
270
|
+
physical,
|
|
271
|
+
_logical,
|
|
272
|
+
default,
|
|
273
|
+
componentflags=None,
|
|
274
|
+
):
|
|
227
275
|
"""Create a new directory in the Directory table. There is a current component
|
|
228
276
|
at each point in time for the directory, which is either explicitly created
|
|
229
277
|
through start_component, or implicitly when files are added for the first
|
|
@@ -257,7 +305,9 @@ class Directory:
|
|
|
257
305
|
blogical = None
|
|
258
306
|
add_data(db, "Directory", [(logical, blogical, default)])
|
|
259
307
|
|
|
260
|
-
def start_component(
|
|
308
|
+
def start_component(
|
|
309
|
+
self, component=None, feature=None, flags=None, keyfile=None, uuid=None
|
|
310
|
+
):
|
|
261
311
|
"""Add an entry to the Component table, and make this component the current for this
|
|
262
312
|
directory. If no component name is given, the directory name is used. If no feature
|
|
263
313
|
is given, the current feature is used. If no flags are given, the directory's default
|
|
@@ -279,17 +329,19 @@ class Directory:
|
|
|
279
329
|
self.keyfiles[keyfile] = keyid
|
|
280
330
|
else:
|
|
281
331
|
keyid = None
|
|
282
|
-
add_data(
|
|
283
|
-
|
|
332
|
+
add_data(
|
|
333
|
+
self.db,
|
|
334
|
+
"Component",
|
|
335
|
+
[(component, uuid, self.logical, flags, None, keyid)],
|
|
336
|
+
)
|
|
284
337
|
if feature is None:
|
|
285
338
|
feature = current_feature
|
|
286
|
-
add_data(self.db, "FeatureComponents",
|
|
287
|
-
[(feature.id, component)])
|
|
339
|
+
add_data(self.db, "FeatureComponents", [(feature.id, component)])
|
|
288
340
|
|
|
289
341
|
def make_short(self, file):
|
|
290
342
|
oldfile = file
|
|
291
|
-
file = file.replace(
|
|
292
|
-
file =
|
|
343
|
+
file = file.replace("+", "_")
|
|
344
|
+
file = "".join(c for c in file if not c in r' "/\[]:;=,')
|
|
293
345
|
parts = file.split(".")
|
|
294
346
|
if len(parts) > 1:
|
|
295
347
|
prefix = "".join(parts[:-1]).upper()
|
|
@@ -300,10 +352,14 @@ class Directory:
|
|
|
300
352
|
else:
|
|
301
353
|
prefix = file.upper()
|
|
302
354
|
suffix = None
|
|
303
|
-
if
|
|
304
|
-
|
|
355
|
+
if (
|
|
356
|
+
len(parts) < 3
|
|
357
|
+
and len(prefix) <= 8
|
|
358
|
+
and file == oldfile
|
|
359
|
+
and (not suffix or len(suffix) <= 3)
|
|
360
|
+
):
|
|
305
361
|
if suffix:
|
|
306
|
-
file = prefix+"."+suffix
|
|
362
|
+
file = prefix + "." + suffix
|
|
307
363
|
else:
|
|
308
364
|
file = prefix
|
|
309
365
|
else:
|
|
@@ -318,13 +374,16 @@ class Directory:
|
|
|
318
374
|
file = "%s~%d.%s" % (prefix, pos, suffix)
|
|
319
375
|
else:
|
|
320
376
|
file = "%s~%d" % (prefix, pos)
|
|
321
|
-
if file not in self.short_names:
|
|
377
|
+
if file not in self.short_names:
|
|
378
|
+
break
|
|
322
379
|
pos += 1
|
|
323
380
|
assert pos < 10000
|
|
324
381
|
if pos in (10, 100, 1000):
|
|
325
382
|
prefix = prefix[:-1]
|
|
326
383
|
self.short_names.add(file)
|
|
327
|
-
assert not re.search(
|
|
384
|
+
assert not re.search(
|
|
385
|
+
r'[\?|><:/*"+,;=\[\]]', file
|
|
386
|
+
) # restrictions on short names
|
|
328
387
|
return file
|
|
329
388
|
|
|
330
389
|
def add_file(self, file, src=None, version=None, language=None):
|
|
@@ -340,7 +399,9 @@ class Directory:
|
|
|
340
399
|
src = file
|
|
341
400
|
file = os.path.basename(file)
|
|
342
401
|
absolute = os.path.join(self.absolute, src)
|
|
343
|
-
assert not re.search(
|
|
402
|
+
assert not re.search(
|
|
403
|
+
r'[\?|><:/*]"', file
|
|
404
|
+
) # restrictions on long names
|
|
344
405
|
if file in self.keyfiles:
|
|
345
406
|
logical = self.keyfiles[file]
|
|
346
407
|
else:
|
|
@@ -355,10 +416,23 @@ class Directory:
|
|
|
355
416
|
# Compressed omitted, since it is the database default
|
|
356
417
|
# could add r/o, system, hidden
|
|
357
418
|
attributes = 512
|
|
358
|
-
add_data(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
419
|
+
add_data(
|
|
420
|
+
self.db,
|
|
421
|
+
"File",
|
|
422
|
+
[
|
|
423
|
+
(
|
|
424
|
+
logical,
|
|
425
|
+
self.component,
|
|
426
|
+
full,
|
|
427
|
+
filesize,
|
|
428
|
+
version,
|
|
429
|
+
language,
|
|
430
|
+
attributes,
|
|
431
|
+
sequence,
|
|
432
|
+
)
|
|
433
|
+
],
|
|
434
|
+
)
|
|
435
|
+
# if not version:
|
|
362
436
|
# # Add hash if the file is not versioned
|
|
363
437
|
# filehash = FileHash(absolute, 0)
|
|
364
438
|
# add_data(self.db, "MsiFileHash",
|
|
@@ -369,69 +443,114 @@ class Directory:
|
|
|
369
443
|
# XXX: adding so many RemoveFile entries makes installer unbelievably
|
|
370
444
|
# slow. So instead, we have to use wildcard remove entries
|
|
371
445
|
if file.endswith(".py"):
|
|
372
|
-
add_data(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
446
|
+
add_data(
|
|
447
|
+
self.db,
|
|
448
|
+
"RemoveFile",
|
|
449
|
+
[
|
|
450
|
+
(
|
|
451
|
+
logical + "c",
|
|
452
|
+
self.component,
|
|
453
|
+
"%sC|%sc" % (short, file),
|
|
454
|
+
self.logical,
|
|
455
|
+
2,
|
|
456
|
+
),
|
|
457
|
+
(
|
|
458
|
+
logical + "o",
|
|
459
|
+
self.component,
|
|
460
|
+
"%sO|%so" % (short, file),
|
|
461
|
+
self.logical,
|
|
462
|
+
2,
|
|
463
|
+
),
|
|
464
|
+
],
|
|
465
|
+
)
|
|
377
466
|
return logical
|
|
378
467
|
|
|
379
|
-
def glob(self, pattern, exclude
|
|
468
|
+
def glob(self, pattern, exclude=None):
|
|
380
469
|
"""Add a list of files to the current component as specified in the
|
|
381
470
|
glob pattern. Individual files can be excluded in the exclude list."""
|
|
382
471
|
try:
|
|
383
472
|
files = os.listdir(self.absolute)
|
|
384
473
|
except OSError:
|
|
385
474
|
return []
|
|
386
|
-
if pattern[:1] !=
|
|
387
|
-
files = (f for f in files if f[0] !=
|
|
475
|
+
if pattern[:1] != ".":
|
|
476
|
+
files = (f for f in files if f[0] != ".")
|
|
388
477
|
files = fnmatch.filter(files, pattern)
|
|
389
478
|
for f in files:
|
|
390
|
-
if exclude and f in exclude:
|
|
479
|
+
if exclude and f in exclude:
|
|
480
|
+
continue
|
|
391
481
|
self.add_file(f)
|
|
392
482
|
return files
|
|
393
483
|
|
|
394
484
|
def remove_pyc(self):
|
|
395
485
|
"Remove .pyc files on uninstall"
|
|
396
|
-
add_data(
|
|
397
|
-
|
|
486
|
+
add_data(
|
|
487
|
+
self.db,
|
|
488
|
+
"RemoveFile",
|
|
489
|
+
[(self.component + "c", self.component, "*.pyc", self.logical, 2)],
|
|
490
|
+
)
|
|
491
|
+
|
|
398
492
|
|
|
399
493
|
class Binary:
|
|
400
494
|
def __init__(self, fname):
|
|
401
495
|
self.name = fname
|
|
496
|
+
|
|
402
497
|
def __repr__(self):
|
|
403
498
|
return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name
|
|
404
499
|
|
|
500
|
+
|
|
405
501
|
class Feature:
|
|
406
|
-
def __init__(
|
|
407
|
-
|
|
502
|
+
def __init__(
|
|
503
|
+
self,
|
|
504
|
+
db,
|
|
505
|
+
id,
|
|
506
|
+
title,
|
|
507
|
+
desc,
|
|
508
|
+
display,
|
|
509
|
+
level=1,
|
|
510
|
+
parent=None,
|
|
511
|
+
directory=None,
|
|
512
|
+
attributes=0,
|
|
513
|
+
):
|
|
408
514
|
self.id = id
|
|
409
515
|
if parent:
|
|
410
516
|
parent = parent.id
|
|
411
|
-
add_data(
|
|
412
|
-
|
|
413
|
-
|
|
517
|
+
add_data(
|
|
518
|
+
db,
|
|
519
|
+
"Feature",
|
|
520
|
+
[(id, parent, title, desc, display, level, directory, attributes)],
|
|
521
|
+
)
|
|
522
|
+
|
|
414
523
|
def set_current(self):
|
|
415
524
|
global current_feature
|
|
416
525
|
current_feature = self
|
|
417
526
|
|
|
527
|
+
|
|
418
528
|
class Control:
|
|
419
529
|
def __init__(self, dlg, name):
|
|
420
530
|
self.dlg = dlg
|
|
421
531
|
self.name = name
|
|
422
532
|
|
|
423
|
-
def event(self, event, argument, condition
|
|
424
|
-
add_data(
|
|
425
|
-
|
|
426
|
-
|
|
533
|
+
def event(self, event, argument, condition="1", ordering=None):
|
|
534
|
+
add_data(
|
|
535
|
+
self.dlg.db,
|
|
536
|
+
"ControlEvent",
|
|
537
|
+
[(self.dlg.name, self.name, event, argument, condition, ordering)],
|
|
538
|
+
)
|
|
427
539
|
|
|
428
540
|
def mapping(self, event, attribute):
|
|
429
|
-
add_data(
|
|
430
|
-
|
|
541
|
+
add_data(
|
|
542
|
+
self.dlg.db,
|
|
543
|
+
"EventMapping",
|
|
544
|
+
[(self.dlg.name, self.name, event, attribute)],
|
|
545
|
+
)
|
|
431
546
|
|
|
432
547
|
def condition(self, action, condition):
|
|
433
|
-
add_data(
|
|
434
|
-
|
|
548
|
+
add_data(
|
|
549
|
+
self.dlg.db,
|
|
550
|
+
"ControlCondition",
|
|
551
|
+
[(self.dlg.name, self.name, action, condition)],
|
|
552
|
+
)
|
|
553
|
+
|
|
435
554
|
|
|
436
555
|
class RadioButtonGroup(Control):
|
|
437
556
|
def __init__(self, dlg, name, property):
|
|
@@ -440,44 +559,97 @@ class RadioButtonGroup(Control):
|
|
|
440
559
|
self.property = property
|
|
441
560
|
self.index = 1
|
|
442
561
|
|
|
443
|
-
def add(self, name, x, y, w, h, text, value
|
|
562
|
+
def add(self, name, x, y, w, h, text, value=None):
|
|
444
563
|
if value is None:
|
|
445
564
|
value = name
|
|
446
|
-
add_data(
|
|
447
|
-
|
|
448
|
-
|
|
565
|
+
add_data(
|
|
566
|
+
self.dlg.db,
|
|
567
|
+
"RadioButton",
|
|
568
|
+
[(self.property, self.index, value, x, y, w, h, text, None)],
|
|
569
|
+
)
|
|
449
570
|
self.index += 1
|
|
450
571
|
|
|
572
|
+
|
|
451
573
|
class Dialog:
|
|
452
|
-
def __init__(
|
|
574
|
+
def __init__(
|
|
575
|
+
self, db, name, x, y, w, h, attr, title, first, default, cancel
|
|
576
|
+
):
|
|
453
577
|
self.db = db
|
|
454
578
|
self.name = name
|
|
455
|
-
self.x, self.y, self.w, self.h = x,y,w,h
|
|
456
|
-
add_data(
|
|
579
|
+
self.x, self.y, self.w, self.h = x, y, w, h
|
|
580
|
+
add_data(
|
|
581
|
+
db,
|
|
582
|
+
"Dialog",
|
|
583
|
+
[(name, x, y, w, h, attr, title, first, default, cancel)],
|
|
584
|
+
)
|
|
457
585
|
|
|
458
586
|
def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
|
|
459
|
-
add_data(
|
|
460
|
-
|
|
587
|
+
add_data(
|
|
588
|
+
self.db,
|
|
589
|
+
"Control",
|
|
590
|
+
[
|
|
591
|
+
(
|
|
592
|
+
self.name,
|
|
593
|
+
name,
|
|
594
|
+
type,
|
|
595
|
+
x,
|
|
596
|
+
y,
|
|
597
|
+
w,
|
|
598
|
+
h,
|
|
599
|
+
attr,
|
|
600
|
+
prop,
|
|
601
|
+
text,
|
|
602
|
+
next,
|
|
603
|
+
help,
|
|
604
|
+
)
|
|
605
|
+
],
|
|
606
|
+
)
|
|
461
607
|
return Control(self, name)
|
|
462
608
|
|
|
463
609
|
def text(self, name, x, y, w, h, attr, text):
|
|
464
|
-
return self.control(
|
|
465
|
-
|
|
610
|
+
return self.control(
|
|
611
|
+
name, "Text", x, y, w, h, attr, None, text, None, None
|
|
612
|
+
)
|
|
466
613
|
|
|
467
614
|
def bitmap(self, name, x, y, w, h, text):
|
|
468
|
-
return self.control(
|
|
615
|
+
return self.control(
|
|
616
|
+
name, "Bitmap", x, y, w, h, 1, None, text, None, None
|
|
617
|
+
)
|
|
469
618
|
|
|
470
619
|
def line(self, name, x, y, w, h):
|
|
471
|
-
return self.control(
|
|
620
|
+
return self.control(
|
|
621
|
+
name, "Line", x, y, w, h, 1, None, None, None, None
|
|
622
|
+
)
|
|
472
623
|
|
|
473
624
|
def pushbutton(self, name, x, y, w, h, attr, text, next):
|
|
474
|
-
return self.control(
|
|
625
|
+
return self.control(
|
|
626
|
+
name, "PushButton", x, y, w, h, attr, None, text, next, None
|
|
627
|
+
)
|
|
475
628
|
|
|
476
629
|
def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
|
|
477
|
-
add_data(
|
|
478
|
-
|
|
479
|
-
|
|
630
|
+
add_data(
|
|
631
|
+
self.db,
|
|
632
|
+
"Control",
|
|
633
|
+
[
|
|
634
|
+
(
|
|
635
|
+
self.name,
|
|
636
|
+
name,
|
|
637
|
+
"RadioButtonGroup",
|
|
638
|
+
x,
|
|
639
|
+
y,
|
|
640
|
+
w,
|
|
641
|
+
h,
|
|
642
|
+
attr,
|
|
643
|
+
prop,
|
|
644
|
+
text,
|
|
645
|
+
next,
|
|
646
|
+
None,
|
|
647
|
+
)
|
|
648
|
+
],
|
|
649
|
+
)
|
|
480
650
|
return RadioButtonGroup(self, name, prop)
|
|
481
651
|
|
|
482
652
|
def checkbox(self, name, x, y, w, h, attr, prop, text, next):
|
|
483
|
-
return self.control(
|
|
653
|
+
return self.control(
|
|
654
|
+
name, "CheckBox", x, y, w, h, attr, prop, text, next, None
|
|
655
|
+
)
|