Mercurial > cpython-lru_cache-weakref
annotate Lib/msilib/__init__.py @ 79675:c0a2294de787 2.7
Issue #16199: Backport 2to3 typo fix from 3.2.
| author | Chris Jerdonek <chris.jerdonek@gmail.com> |
|---|---|
| date | Thu, 11 Oct 2012 16:15:46 -0700 |
| parents | ec84bd4c5ac4 |
| children | cd0191a9b5c9 |
| rev | line source |
|---|---|
| 36845 | 1 # -*- coding: iso-8859-1 -*- |
| 2 # Copyright (C) 2005 Martin v. Löwis | |
| 3 # Licensed to PSF under a Contributor Agreement. | |
| 4 from _msi import * | |
|
54729
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
5 import os, string, re, sys |
| 36845 | 6 |
|
54729
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
7 AMD64 = "AMD64" in sys.version |
|
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
8 Itanium = "Itanium" in sys.version |
|
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
9 Win64 = AMD64 or Itanium |
| 36845 | 10 |
| 11 # Partially taken from Wine | |
| 12 datasizemask= 0x00ff | |
| 13 type_valid= 0x0100 | |
| 14 type_localizable= 0x0200 | |
| 15 | |
| 16 typemask= 0x0c00 | |
| 17 type_long= 0x0000 | |
| 18 type_short= 0x0400 | |
| 19 type_string= 0x0c00 | |
| 20 type_binary= 0x0800 | |
| 21 | |
| 22 type_nullable= 0x1000 | |
| 23 type_key= 0x2000 | |
| 24 # XXX temporary, localizable? | |
| 25 knownbits = datasizemask | type_valid | type_localizable | \ | |
| 26 typemask | type_nullable | type_key | |
| 27 | |
| 28 class Table: | |
| 29 def __init__(self, name): | |
| 30 self.name = name | |
| 31 self.fields = [] | |
| 32 | |
| 33 def add_field(self, index, name, type): | |
| 34 self.fields.append((index,name,type)) | |
| 35 | |
| 36 def sql(self): | |
| 37 fields = [] | |
| 38 keys = [] | |
| 39 self.fields.sort() | |
| 40 fields = [None]*len(self.fields) | |
| 41 for index, name, type in self.fields: | |
| 42 index -= 1 | |
| 43 unk = type & ~knownbits | |
| 44 if unk: | |
| 45 print "%s.%s unknown bits %x" % (self.name, name, unk) | |
| 46 size = type & datasizemask | |
| 47 dtype = type & typemask | |
| 48 if dtype == type_string: | |
| 49 if size: | |
| 50 tname="CHAR(%d)" % size | |
| 51 else: | |
| 52 tname="CHAR" | |
| 53 elif dtype == type_short: | |
| 54 assert size==2 | |
| 55 tname = "SHORT" | |
| 56 elif dtype == type_long: | |
| 57 assert size==4 | |
| 58 tname="LONG" | |
| 59 elif dtype == type_binary: | |
| 60 assert size==0 | |
| 61 tname="OBJECT" | |
| 62 else: | |
| 63 tname="unknown" | |
| 64 print "%s.%sunknown integer type %d" % (self.name, name, size) | |
| 65 if type & type_nullable: | |
| 66 flags = "" | |
| 67 else: | |
| 68 flags = " NOT NULL" | |
| 69 if type & type_localizable: | |
| 70 flags += " LOCALIZABLE" | |
| 71 fields[index] = "`%s` %s%s" % (name, tname, flags) | |
| 72 if type & type_key: | |
| 73 keys.append("`%s`" % name) | |
| 74 fields = ", ".join(fields) | |
| 75 keys = ", ".join(keys) | |
| 76 return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys) | |
| 77 | |
| 78 def create(self, db): | |
| 79 v = db.OpenView(self.sql()) | |
| 80 v.Execute(None) | |
| 81 v.Close() | |
| 82 | |
| 83 class _Unspecified:pass | |
| 84 def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified): | |
| 85 "Change the sequence number of an action in a sequence list" | |
| 86 for i in range(len(seq)): | |
| 87 if seq[i][0] == action: | |
| 88 if cond is _Unspecified: | |
| 89 cond = seq[i][1] | |
| 90 if seqno is _Unspecified: | |
| 91 seqno = seq[i][2] | |
| 92 seq[i] = (action, cond, seqno) | |
| 93 return | |
| 94 raise ValueError, "Action not found in sequence" | |
| 95 | |
| 96 def add_data(db, table, values): | |
| 97 v = db.OpenView("SELECT * FROM `%s`" % table) | |
| 98 count = v.GetColumnInfo(MSICOLINFO_NAMES).GetFieldCount() | |
| 99 r = CreateRecord(count) | |
| 100 for value in values: | |
| 101 assert len(value) == count, value | |
| 102 for i in range(count): | |
| 103 field = value[i] | |
| 104 if isinstance(field, (int, long)): | |
| 105 r.SetInteger(i+1,field) | |
| 106 elif isinstance(field, basestring): | |
| 107 r.SetString(i+1,field) | |
| 108 elif field is None: | |
| 109 pass | |
| 110 elif isinstance(field, Binary): | |
| 111 r.SetStream(i+1, field.name) | |
| 112 else: | |
| 113 raise TypeError, "Unsupported type %s" % field.__class__.__name__ | |
| 114 try: | |
| 115 v.Modify(MSIMODIFY_INSERT, r) | |
| 116 except Exception, e: | |
| 117 raise MSIError("Could not insert "+repr(values)+" into "+table) | |
| 118 | |
| 119 r.ClearData() | |
| 120 v.Close() | |
| 121 | |
| 122 | |
| 123 def add_stream(db, name, path): | |
| 124 v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name) | |
| 125 r = CreateRecord(1) | |
| 126 r.SetStream(1, path) | |
| 127 v.Execute(r) | |
| 128 v.Close() | |
| 129 | |
| 130 def init_database(name, schema, | |
| 131 ProductName, ProductCode, ProductVersion, | |
| 132 Manufacturer): | |
| 133 try: | |
| 134 os.unlink(name) | |
| 135 except OSError: | |
| 136 pass | |
| 137 ProductCode = ProductCode.upper() | |
| 138 # Create the database | |
| 139 db = OpenDatabase(name, MSIDBOPEN_CREATE) | |
| 140 # Create the tables | |
| 141 for t in schema.tables: | |
| 142 t.create(db) | |
| 143 # Fill the validation table | |
| 144 add_data(db, "_Validation", schema._Validation_records) | |
| 145 # Initialize the summary information, allowing atmost 20 properties | |
| 146 si = db.GetSummaryInformation(20) | |
| 147 si.SetProperty(PID_TITLE, "Installation Database") | |
| 148 si.SetProperty(PID_SUBJECT, ProductName) | |
| 149 si.SetProperty(PID_AUTHOR, Manufacturer) | |
|
54729
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
150 if Itanium: |
| 36845 | 151 si.SetProperty(PID_TEMPLATE, "Intel64;1033") |
|
54729
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
152 elif AMD64: |
|
b43398ea549d
Merged revisions 73390 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents:
48921
diff
changeset
|
153 si.SetProperty(PID_TEMPLATE, "x64;1033") |
| 36845 | 154 else: |
| 155 si.SetProperty(PID_TEMPLATE, "Intel;1033") | |
| 156 si.SetProperty(PID_REVNUMBER, gen_uuid()) | |
| 157 si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media | |
| 158 si.SetProperty(PID_PAGECOUNT, 200) | |
| 159 si.SetProperty(PID_APPNAME, "Python MSI Library") | |
| 160 # XXX more properties | |
| 161 si.Persist() | |
| 162 add_data(db, "Property", [ | |
| 163 ("ProductName", ProductName), | |
| 164 ("ProductCode", ProductCode), | |
| 165 ("ProductVersion", ProductVersion), | |
| 166 ("Manufacturer", Manufacturer), | |
| 167 ("ProductLanguage", "1033")]) | |
| 168 db.Commit() | |
| 169 return db | |
| 170 | |
| 171 def add_tables(db, module): | |
| 172 for table in module.tables: | |
| 173 add_data(db, table, getattr(module, table)) | |
| 174 | |
| 175 def make_id(str): | |
|
69016
ec84bd4c5ac4
Closes #11696: Fix ID generation in msilib.
Martin v. Löwis <martin@v.loewis.de>
parents:
68999
diff
changeset
|
176 identifier_chars = string.ascii_letters + string.digits + "._" |
|
ec84bd4c5ac4
Closes #11696: Fix ID generation in msilib.
Martin v. Löwis <martin@v.loewis.de>
parents:
68999
diff
changeset
|
177 str = "".join([c if c in identifier_chars else "_" for c in str]) |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
178 if str[0] in (string.digits + "."): |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
179 str = "_" + str |
| 36845 | 180 assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str |
| 181 return str | |
| 182 | |
| 183 def gen_uuid(): | |
| 184 return "{"+UuidCreate().upper()+"}" | |
| 185 | |
| 186 class CAB: | |
| 187 def __init__(self, name): | |
| 188 self.name = name | |
| 189 self.files = [] | |
|
48921
8cda615ef22b
Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents:
39031
diff
changeset
|
190 self.filenames = set() |
| 36845 | 191 self.index = 0 |
| 192 | |
|
39031
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
193 def gen_id(self, file): |
| 36845 | 194 logical = _logical = make_id(file) |
| 195 pos = 1 | |
| 196 while logical in self.filenames: | |
| 197 logical = "%s.%d" % (_logical, pos) | |
| 198 pos += 1 | |
| 199 self.filenames.add(logical) | |
| 200 return logical | |
| 201 | |
|
39031
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
202 def append(self, full, file, logical): |
| 36845 | 203 if os.path.isdir(full): |
| 204 return | |
|
39031
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
205 if not logical: |
|
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
206 logical = self.gen_id(file) |
| 36845 | 207 self.index += 1 |
| 208 self.files.append((full, logical)) | |
| 209 return self.index, logical | |
| 210 | |
| 211 def commit(self, db): | |
| 212 from tempfile import mktemp | |
| 213 filename = mktemp() | |
| 214 FCICreate(filename, self.files) | |
| 215 add_data(db, "Media", | |
| 216 [(1, self.index, None, "#"+self.name, None, None)]) | |
| 217 add_stream(db, self.name, filename) | |
| 218 os.unlink(filename) | |
| 219 db.Commit() | |
| 220 | |
|
48921
8cda615ef22b
Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents:
39031
diff
changeset
|
221 _directories = set() |
| 36845 | 222 class Directory: |
| 223 def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None): | |
| 224 """Create a new directory in the Directory table. There is a current component | |
| 225 at each point in time for the directory, which is either explicitly created | |
| 226 through start_component, or implicitly when files are added for the first | |
| 227 time. Files are added into the current component, and into the cab file. | |
| 228 To create a directory, a base directory object needs to be specified (can be | |
| 229 None), the path to the physical directory, and a logical directory name. | |
| 230 Default specifies the DefaultDir slot in the directory table. componentflags | |
| 231 specifies the default flags that new components get.""" | |
| 232 index = 1 | |
| 233 _logical = make_id(_logical) | |
| 234 logical = _logical | |
| 235 while logical in _directories: | |
| 236 logical = "%s%d" % (_logical, index) | |
| 237 index += 1 | |
| 238 _directories.add(logical) | |
| 239 self.db = db | |
| 240 self.cab = cab | |
| 241 self.basedir = basedir | |
| 242 self.physical = physical | |
| 243 self.logical = logical | |
| 244 self.component = None | |
|
48921
8cda615ef22b
Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents:
39031
diff
changeset
|
245 self.short_names = set() |
|
8cda615ef22b
Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents:
39031
diff
changeset
|
246 self.ids = set() |
| 36845 | 247 self.keyfiles = {} |
| 248 self.componentflags = componentflags | |
| 249 if basedir: | |
| 250 self.absolute = os.path.join(basedir.absolute, physical) | |
| 251 blogical = basedir.logical | |
| 252 else: | |
| 253 self.absolute = physical | |
| 254 blogical = None | |
| 255 add_data(db, "Directory", [(logical, blogical, default)]) | |
| 256 | |
| 257 def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None): | |
| 258 """Add an entry to the Component table, and make this component the current for this | |
| 259 directory. If no component name is given, the directory name is used. If no feature | |
| 260 is given, the current feature is used. If no flags are given, the directory's default | |
| 261 flags are used. If no keyfile is given, the KeyPath is left null in the Component | |
| 262 table.""" | |
| 263 if flags is None: | |
| 264 flags = self.componentflags | |
| 265 if uuid is None: | |
| 266 uuid = gen_uuid() | |
| 267 else: | |
| 268 uuid = uuid.upper() | |
| 269 if component is None: | |
| 270 component = self.logical | |
| 271 self.component = component | |
| 272 if Win64: | |
| 273 flags |= 256 | |
| 274 if keyfile: | |
| 275 keyid = self.cab.gen_id(self.absolute, keyfile) | |
| 276 self.keyfiles[keyfile] = keyid | |
| 277 else: | |
| 278 keyid = None | |
| 279 add_data(self.db, "Component", | |
| 280 [(component, uuid, self.logical, flags, None, keyid)]) | |
| 281 if feature is None: | |
| 282 feature = current_feature | |
| 283 add_data(self.db, "FeatureComponents", | |
| 284 [(feature.id, component)]) | |
| 285 | |
| 286 def make_short(self, file): | |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
287 oldfile = file |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
288 file = file.replace('+', '_') |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
289 file = ''.join(c for c in file if not c in ' "/\[]:;=,') |
| 36845 | 290 parts = file.split(".") |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
291 if len(parts) > 1: |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
292 prefix = "".join(parts[:-1]).upper() |
| 36845 | 293 suffix = parts[-1].upper() |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
294 if not prefix: |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
295 prefix = suffix |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
296 suffix = None |
| 36845 | 297 else: |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
298 prefix = file.upper() |
| 36845 | 299 suffix = None |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
300 if len(parts) < 3 and len(prefix) <= 8 and file == oldfile and ( |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
301 not suffix or len(suffix) <= 3): |
| 36845 | 302 if suffix: |
| 303 file = prefix+"."+suffix | |
| 304 else: | |
| 305 file = prefix | |
| 306 else: | |
|
68999
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
307 file = None |
|
e51366a05b84
Fix short file name generation in bdist_msi.
Martin v. Löwis <martin@v.loewis.de>
parents:
56436
diff
changeset
|
308 if file is None or file in self.short_names: |
| 36845 | 309 prefix = prefix[:6] |
| 310 if suffix: | |
| 311 suffix = suffix[:3] | |
| 312 pos = 1 | |
| 313 while 1: | |
| 314 if suffix: | |
| 315 file = "%s~%d.%s" % (prefix, pos, suffix) | |
| 316 else: | |
| 317 file = "%s~%d" % (prefix, pos) | |
| 318 if file not in self.short_names: break | |
| 319 pos += 1 | |
| 320 assert pos < 10000 | |
| 321 if pos in (10, 100, 1000): | |
| 322 prefix = prefix[:-1] | |
| 323 self.short_names.add(file) | |
| 324 assert not re.search(r'[\?|><:/*"+,;=\[\]]', file) # restrictions on short names | |
| 325 return file | |
| 326 | |
| 327 def add_file(self, file, src=None, version=None, language=None): | |
| 328 """Add a file to the current component of the directory, starting a new one | |
| 329 one if there is no current component. By default, the file name in the source | |
| 330 and the file table will be identical. If the src file is specified, it is | |
| 331 interpreted relative to the current directory. Optionally, a version and a | |
| 332 language can be specified for the entry in the File table.""" | |
| 333 if not self.component: | |
| 334 self.start_component(self.logical, current_feature, 0) | |
| 335 if not src: | |
| 336 # Allow relative paths for file if src is not specified | |
| 337 src = file | |
| 338 file = os.path.basename(file) | |
| 339 absolute = os.path.join(self.absolute, src) | |
| 340 assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names | |
|
56436
684960fb1cbf
replace has_key with 'in' operator
Benjamin Peterson <benjamin@python.org>
parents:
54729
diff
changeset
|
341 if file in self.keyfiles: |
| 36845 | 342 logical = self.keyfiles[file] |
| 343 else: | |
| 344 logical = None | |
|
39031
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
345 sequence, logical = self.cab.append(absolute, file, logical) |
| 36845 | 346 assert logical not in self.ids |
| 347 self.ids.add(logical) | |
| 348 short = self.make_short(file) | |
| 349 full = "%s|%s" % (short, file) | |
| 350 filesize = os.stat(absolute).st_size | |
| 351 # constants.msidbFileAttributesVital | |
| 352 # Compressed omitted, since it is the database default | |
| 353 # could add r/o, system, hidden | |
| 354 attributes = 512 | |
| 355 add_data(self.db, "File", | |
| 356 [(logical, self.component, full, filesize, version, | |
| 357 language, attributes, sequence)]) | |
| 358 #if not version: | |
| 359 # # Add hash if the file is not versioned | |
| 360 # filehash = FileHash(absolute, 0) | |
| 361 # add_data(self.db, "MsiFileHash", | |
| 362 # [(logical, 0, filehash.IntegerData(1), | |
| 363 # filehash.IntegerData(2), filehash.IntegerData(3), | |
| 364 # filehash.IntegerData(4))]) | |
| 365 # Automatically remove .pyc/.pyo files on uninstall (2) | |
| 366 # XXX: adding so many RemoveFile entries makes installer unbelievably | |
| 367 # slow. So instead, we have to use wildcard remove entries | |
| 368 if file.endswith(".py"): | |
| 369 add_data(self.db, "RemoveFile", | |
| 370 [(logical+"c", self.component, "%sC|%sc" % (short, file), | |
| 371 self.logical, 2), | |
| 372 (logical+"o", self.component, "%sO|%so" % (short, file), | |
| 373 self.logical, 2)]) | |
| 374 return logical | |
| 375 | |
| 376 def glob(self, pattern, exclude = None): | |
| 377 """Add a list of files to the current component as specified in the | |
| 378 glob pattern. Individual files can be excluded in the exclude list.""" | |
| 379 files = glob.glob1(self.absolute, pattern) | |
| 380 for f in files: | |
| 381 if exclude and f in exclude: continue | |
| 382 self.add_file(f) | |
| 383 return files | |
| 384 | |
| 385 def remove_pyc(self): | |
| 386 "Remove .pyc/.pyo files on uninstall" | |
| 387 add_data(self.db, "RemoveFile", | |
| 388 [(self.component+"c", self.component, "*.pyc", self.logical, 2), | |
| 389 (self.component+"o", self.component, "*.pyo", self.logical, 2)]) | |
| 390 | |
| 391 class Binary: | |
| 392 def __init__(self, fname): | |
| 393 self.name = fname | |
| 394 def __repr__(self): | |
| 395 return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name | |
| 396 | |
| 397 class Feature: | |
| 398 def __init__(self, db, id, title, desc, display, level = 1, | |
| 399 parent=None, directory = None, attributes=0): | |
| 400 self.id = id | |
| 401 if parent: | |
| 402 parent = parent.id | |
| 403 add_data(db, "Feature", | |
| 404 [(id, parent, title, desc, display, | |
| 405 level, directory, attributes)]) | |
| 406 def set_current(self): | |
| 407 global current_feature | |
| 408 current_feature = self | |
| 409 | |
| 410 class Control: | |
| 411 def __init__(self, dlg, name): | |
| 412 self.dlg = dlg | |
| 413 self.name = name | |
| 414 | |
|
38072
ee98ecf05773
Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents:
36845
diff
changeset
|
415 def event(self, event, argument, condition = "1", ordering = None): |
| 36845 | 416 add_data(self.dlg.db, "ControlEvent", |
|
38072
ee98ecf05773
Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents:
36845
diff
changeset
|
417 [(self.dlg.name, self.name, event, argument, |
|
ee98ecf05773
Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents:
36845
diff
changeset
|
418 condition, ordering)]) |
| 36845 | 419 |
|
39031
8fefa99e87c0
Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents:
38072
diff
changeset
|
420 def mapping(self, event, attribute): |
| 36845 | 421 add_data(self.dlg.db, "EventMapping", |
|
38072
ee98ecf05773
Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents:
36845
diff
changeset
|
422 [(self.dlg.name, self.name, event, attribute)]) |
| 36845 | 423 |
| 424 def condition(self, action, condition): | |
| 425 add_data(self.dlg.db, "ControlCondition", | |
| 426 [(self.dlg.name, self.name, action, condition)]) | |
| 427 | |
| 428 class RadioButtonGroup(Control): | |
| 429 def __init__(self, dlg, name, property): | |
| 430 self.dlg = dlg | |
| 431 self.name = name | |
| 432 self.property = property | |
| 433 self.index = 1 | |
| 434 | |
| 435 def add(self, name, x, y, w, h, text, value = None): | |
| 436 if value is None: | |
| 437 value = name | |
| 438 add_data(self.dlg.db, "RadioButton", | |
| 439 [(self.property, self.index, value, | |
| 440 x, y, w, h, text, None)]) | |
| 441 self.index += 1 | |
| 442 | |
| 443 class Dialog: | |
| 444 def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel): | |
| 445 self.db = db | |
| 446 self.name = name | |
| 447 self.x, self.y, self.w, self.h = x,y,w,h | |
| 448 add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)]) | |
| 449 | |
| 450 def control(self, name, type, x, y, w, h, attr, prop, text, next, help): | |
| 451 add_data(self.db, "Control", | |
| 452 [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)]) | |
| 453 return Control(self, name) | |
| 454 | |
| 455 def text(self, name, x, y, w, h, attr, text): | |
| 456 return self.control(name, "Text", x, y, w, h, attr, None, | |
| 457 text, None, None) | |
| 458 | |
| 459 def bitmap(self, name, x, y, w, h, text): | |
| 460 return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None) | |
| 461 | |
| 462 def line(self, name, x, y, w, h): | |
| 463 return self.control(name, "Line", x, y, w, h, 1, None, None, None, None) | |
| 464 | |
| 465 def pushbutton(self, name, x, y, w, h, attr, text, next): | |
| 466 return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None) | |
| 467 | |
| 468 def radiogroup(self, name, x, y, w, h, attr, prop, text, next): | |
| 469 add_data(self.db, "Control", | |
| 470 [(self.name, name, "RadioButtonGroup", | |
| 471 x, y, w, h, attr, prop, text, next, None)]) | |
| 472 return RadioButtonGroup(self, name, prop) | |
| 473 | |
| 474 def checkbox(self, name, x, y, w, h, attr, prop, text, next): | |
| 475 return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None) |
