Total Complexity | 112 |
Total Lines | 512 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like osci.dialog.ProblemsDlg often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # |
||
2 | # Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/] |
||
3 | # |
||
4 | # This file is part of Outer Space. |
||
5 | # |
||
6 | # Outer Space is free software; you can redistribute it and/or modify |
||
7 | # it under the terms of the GNU General Public License as published by |
||
8 | # the Free Software Foundation; either version 2 of the License, or |
||
9 | # (at your option) any later version. |
||
10 | # |
||
11 | # Outer Space is distributed in the hope that it will be useful, |
||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | # GNU General Public License for more details. |
||
15 | # |
||
16 | # You should have received a copy of the GNU General Public License |
||
17 | # along with Outer Space; if not, write to the Free Software |
||
18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||
19 | # |
||
20 | import bisect |
||
21 | import copy |
||
22 | import math |
||
23 | import re |
||
24 | import string |
||
25 | |||
26 | import pygameui as ui |
||
27 | from osci import gdata, client, res |
||
28 | import ige.ospace.Const as Const |
||
29 | from ige.ospace import Utils, Rules |
||
30 | |||
31 | class ProblemsDlg: |
||
32 | """Displays 'Problem locator' dialog. |
||
33 | |||
34 | """ |
||
35 | def __init__(self, app): |
||
36 | self.app = app |
||
37 | self.createUI() |
||
38 | |||
39 | def display(self): |
||
40 | self.show() |
||
41 | self.win.show() |
||
42 | # register for updates |
||
43 | if self not in gdata.updateDlgs: |
||
44 | gdata.updateDlgs.append(self) |
||
45 | |||
46 | def hide(self): |
||
47 | self.win.setStatus(_("Ready.")) |
||
48 | self.win.hide() |
||
49 | # unregister updates |
||
50 | if self in gdata.updateDlgs: |
||
51 | gdata.updateDlgs.remove(self) |
||
52 | |||
53 | def update(self): |
||
54 | self.show() |
||
55 | |||
56 | class Problems: |
||
57 | def __init__(self, win): |
||
58 | self.items = [] |
||
59 | self.checkboxes = {gdata.CRI: win.vCritical.checked, |
||
60 | gdata.MAJ: win.vMajor.checked, |
||
61 | gdata.MIN: win.vMinor.checked, |
||
62 | gdata.INFO: win.vInfo.checked} |
||
63 | |||
64 | def append(self, severity, item): |
||
65 | if self.checkboxes[severity]: |
||
66 | item.foreground = gdata.sevColors[severity] |
||
67 | self.items.append(item) |
||
68 | |||
69 | def _addProblemsStructStatus(self, problems, struct, planet): |
||
70 | player = client.getPlayer() |
||
71 | status = struct[Const.STRUCT_IDX_STATUS] |
||
72 | tech = client.getFullTechInfo(struct[Const.STRUCT_IDX_TECHID]) |
||
73 | |||
74 | if hasattr(player, 'techs'): |
||
75 | techEff = Rules.techImprEff[player.techs.get(struct[Const.STRUCT_IDX_TECHID], Rules.techBaseImprovement)] |
||
76 | else: |
||
77 | techEff = Rules.techImprEff[Rules.techBaseImprovement] |
||
78 | |||
79 | HPturn = max(1, int(0.02 * tech.maxHP * techEff)) |
||
80 | turnsToDestroy = math.ceil(struct[Const.STRUCT_IDX_HP] / HPturn) |
||
81 | |||
82 | if turnsToDestroy < Rules.turnsPerDay * 2: |
||
83 | severity = gdata.MAJ |
||
84 | if turnsToDestroy < Rules.turnsPerDay: |
||
85 | severity = gdata.CRI |
||
86 | else: |
||
87 | severity = gdata.MIN |
||
88 | |||
89 | if not status & Const.STRUCT_STATUS_ON: |
||
90 | # structure is off |
||
91 | problems.append(severity, |
||
92 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
93 | vDescription=_('Structure (%s) is off and will be destroyed in %s turns.') % (tech.name, res.formatTime(turnsToDestroy)))) |
||
94 | |||
95 | if status & Const.STRUCT_STATUS_DETER: |
||
96 | problems.append(gdata.MAJ, |
||
97 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
98 | vDescription=_('Structure (%s) is deteriorating.') % (tech.name,))) |
||
99 | if status & Const.STRUCT_STATUS_NOBIO: |
||
100 | problems.append(gdata.INFO, |
||
101 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
102 | vDescription=_('Structure (%s) has insufficient supply of biomatter.') % (tech.name,))) |
||
103 | if status & Const.STRUCT_STATUS_NOEN: |
||
104 | problems.append(gdata.INFO, |
||
105 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
106 | vDescription=_('Structure (%s) has insufficient supply of energy.') % (tech.name,))) |
||
107 | if status & Const.STRUCT_STATUS_NOPOP: |
||
108 | problems.append(gdata.INFO, |
||
109 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
110 | vDescription=_('Structure (%s) has insufficient supply of workers.') % (tech.name,))) |
||
111 | if status & Const.STRUCT_STATUS_REPAIRING: |
||
112 | problems.append(gdata.INFO, |
||
113 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
114 | vDescription=_('Structure (%s) is repairing.') % (tech.name,))) |
||
115 | |||
116 | def _getSystemRefuel(self, system): |
||
117 | player = client.getPlayer() |
||
118 | maxRefuelMax = 0 |
||
119 | hasRefuel = False |
||
120 | for planetID in system.planets: |
||
121 | planet = client.get(planetID, noUpdate=1) |
||
122 | if hasattr(planet, 'owner'): |
||
123 | if hasattr(planet, 'hasRefuel'): |
||
124 | hasRefuel = hasRefuel or planet.hasRefuel |
||
125 | if hasattr(planet, 'refuelMax'): |
||
126 | if planet.owner == player.oid: |
||
127 | maxRefuelMax = max(maxRefuelMax, planet.refuelMax) |
||
128 | elif planet.owner in player.diplomacyRels: |
||
129 | dipl = client.getDiplomacyWith(planet.owner) |
||
130 | if Const.PACT_ALLOW_TANKING in dipl.pacts and dipl.pacts[Const.PACT_ALLOW_TANKING][0] == Const.PACT_ACTIVE: |
||
131 | maxRefuelMax = max(maxRefuelMax, planet.refuelMax) |
||
132 | elif hasattr(planet, 'hasRefuel'): |
||
133 | maxRefuelMax |
||
134 | return hasRefuel, maxRefuelMax |
||
135 | |||
136 | def _addProblemsFleets(self, problems, fleet): |
||
137 | if not fleet.orbiting: |
||
138 | # we do not report fleets in flight |
||
139 | return |
||
140 | fleetName = fleet.customname if fleet.customname else fleet.name |
||
141 | energyReserve = fleet.storEn * 100 / fleet.maxEn |
||
142 | system = client.get(fleet.orbiting, noUpdate=1) |
||
143 | systemName = getattr(system, "name", res.getUnknownName()) |
||
144 | hasRefuel, maxRefuelMax = self._getSystemRefuel(system) |
||
145 | |||
146 | if energyReserve == 100: |
||
147 | problems.append(gdata.INFO, |
||
148 | ui.Item(systemName, tOID=fleet.oid, tType=Const.T_FLEET, |
||
149 | vDescription=_('Fleet "%s" has full fuel tanks.') % (fleetName))) |
||
150 | return |
||
151 | |||
152 | if 0 < maxRefuelMax <= energyReserve: |
||
153 | severity = gdata.INFO |
||
154 | if maxRefuelMax <= energyReserve: |
||
155 | note = _(' and CAN refuel, but reached planet maximum refuel amount') |
||
156 | else: |
||
157 | note = _(' and IS refueling') |
||
158 | elif hasRefuel: |
||
159 | severity = gdata.INFO |
||
160 | note = _(' and utilizes unknown refueling capacities') |
||
161 | else: |
||
162 | note = _(' and is NOT refueling') |
||
163 | severity = [gdata.CRI, gdata.MAJ, gdata.MIN][bisect.bisect([25, 50], energyReserve)] |
||
164 | problems.append(severity, |
||
165 | ui.Item(systemName, tOID=fleet.oid, tType=Const.T_FLEET, |
||
166 | vDescription=_('Fleet "%s" is low on fuel [%d %%]%s.') % (fleetName, energyReserve, note))) |
||
167 | |||
168 | def _addProblemsMaterial(self, problems, system, mat, totalMat, material): |
||
169 | if mat >= 0: |
||
170 | return |
||
171 | surplusTurns = totalMat / (-mat) |
||
172 | if surplusTurns < Rules.turnsPerDay * 7: |
||
173 | severity = gdata.MAJ |
||
174 | elif surplusTurns < Rules.turnsPerDay * 2: |
||
175 | severity = gdata.CRI |
||
176 | else: |
||
177 | severity = gdata.MIN |
||
178 | |||
179 | if totalMat > 0: |
||
180 | note = _(' surplus %d (%s)' % (totalMat, res.formatTime(surplusTurns))) |
||
181 | else: |
||
182 | note = _(' with no surplus left!') |
||
183 | problems.append(severity, |
||
184 | ui.Item(system.name, tOID=system.oid, tType=Const.T_SYSTEM, |
||
185 | vDescription=_('%s decreasing - last turn change %d, %s.') % (material, mat, note))) |
||
186 | |||
187 | def _getTaskSciValue(self, task): |
||
188 | player = client.getPlayer() |
||
189 | fulltech = client.getFullTechInfo(task.techID) |
||
190 | researchSci = Utils.getTechRCost(player, task.techID, task.improvement) |
||
191 | maxImprovement = min(Rules.techMaxImprovement, fulltech.maxImprovement) |
||
192 | |||
193 | if task.improveToMax: |
||
194 | # account next levels |
||
195 | for impr in range(task.improvement + 1, maxImprovement + 1): |
||
196 | researchSci += Utils.getTechRCost(player, task.techID, impr) |
||
197 | return researchSci - task.currSci |
||
198 | |||
199 | def _addProblemsResearch(self, problems): |
||
200 | player = client.getPlayer() |
||
201 | sciProd = max(sum(task.changeSci for task in player.rsrchQueue), |
||
202 | player.effSciPoints) |
||
203 | if sciProd < 0: |
||
204 | problems.append(gdata.CRI, |
||
205 | ui.Item(_('Research'), tType=Const.T_TECHNOLOGY, |
||
206 | vDescription=_('We are losing our researched knowledge by %d pts per turn!') % (sciProd,))) |
||
207 | return |
||
208 | elif sciProd == 0: |
||
209 | return |
||
210 | elif len(player.rsrchQueue) == 0: |
||
211 | problems.append(gdata.CRI, |
||
212 | ui.Item(_('Research'), tType=Const.T_TECHNOLOGY, |
||
213 | vDescription=_('Research queue is empty.'))) |
||
214 | |||
215 | queueValue = sum(self._getTaskSciValue(task) for task in player.rsrchQueue) |
||
216 | totalEtc = math.ceil(float(queueValue) / sciProd) |
||
217 | |||
218 | # check short reseach queue |
||
219 | if totalEtc < Rules.turnsPerDay * 2: |
||
220 | severity = gdata.MIN |
||
221 | if totalEtc < Rules.turnsPerDay: |
||
222 | severity = gdata.MAJ |
||
223 | problems.append(severity, |
||
224 | ui.Item(_('Research'), tType=Const.T_TECHNOLOGY, |
||
225 | vDescription=_('Research queue ends in %s turns, %d item(s) on list.') % (res.formatTime(totalEtc), len(player.rsrchQueue)))) |
||
226 | |||
227 | def _addProblemsGlobalQueues(self, problems): |
||
228 | # go through all planets to understand the state of global queues |
||
229 | player = client.getPlayer() |
||
230 | # holder for (number , eff production) of planets set to each queue |
||
231 | globalQueueStats = [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)] |
||
232 | queConstValues = [0, 0, 0, 0, 0] |
||
233 | queEtc = [0, 0, 0, 0, 0] |
||
234 | |||
235 | for planetID in player.planets: |
||
236 | planet = client.get(planetID, noUpdate=1) |
||
237 | globalQueueStats[planet.globalQueue] = tuple([sum(x) for x in zip(globalQueueStats[planet.globalQueue], (1, planet.effProdProd))]) |
||
238 | |||
239 | # evaluate depletion rate of the global queue |
||
240 | for queue in range(5): |
||
241 | quePlanets, queEffProd = globalQueueStats[queue] |
||
242 | for task in player.prodQueues[queue]: |
||
243 | if task.isShip: |
||
244 | tech = player.shipDesigns[task.techID] |
||
245 | else: |
||
246 | tech = client.getFullTechInfo(task.techID) |
||
247 | queConstValues[queue] += task.quantity * tech.buildProd |
||
248 | if queEffProd > 0: |
||
249 | queEtc[queue] = math.ceil(float(queConstValues[queue])/queEffProd) |
||
250 | else: |
||
251 | queEtc[queue] = 99999 |
||
252 | |||
253 | # creation of items with global queue problems |
||
254 | for queue in range(1, 5): |
||
255 | queName = res.globalQueueName(queue) |
||
256 | quePlanets = globalQueueStats[queue][0] |
||
257 | # check empty global production queue with at least one planet [so its relevant] |
||
258 | if queConstValues[queue] == 0 and quePlanets > 0: |
||
259 | problems.append(gdata.CRI, |
||
260 | ui.Item(_('Global queue ' + queName), tType=Const.T_QUEUE, |
||
261 | vDescription=_('Global production queue {0} used by {1} planet(s) is empty.'.format(queName, quePlanets)))) |
||
262 | # check end of global production queue |
||
263 | elif queEtc[queue] < Rules.turnsPerDay * 2: |
||
264 | severity = gdata.MIN |
||
265 | if queEtc[queue] < Rules.turnsPerDay: |
||
266 | severity = gdata.MAJ |
||
267 | problems.append(severity, |
||
268 | ui.Item(_('Global queue ' + queName), tType=Const.T_QUEUE, |
||
269 | vDescription=_('Global production queue {0} used by {1} planet(s) runs out in {2} turns.'.format(queName, quePlanets, res.formatTime(queEtc[queue]))))) |
||
270 | return queEtc[0] # time of depletion of the default queue will be reused later |
||
271 | |||
272 | def _getTargetSlotDict(self, planetID): |
||
273 | assert planetID in client.getPlayer().planets |
||
274 | targets = {} |
||
275 | planet = client.get(planetID, noUpdate=1) |
||
276 | if planet.effProdProd <= 0: |
||
277 | return targets |
||
278 | |||
279 | nonShipTasks = (task for task in planet.prodQueue if not task.isShip) |
||
1 ignored issue
–
show
|
|||
280 | for task in nonShipTasks: |
||
281 | tech = client.getFullTechInfo(task.techID) |
||
282 | if tech.isStructure and task.demolishStruct == 0: |
||
283 | quantity = task.quantity |
||
284 | elif tech.isProject and tech.id == 3802: |
||
285 | # we are constructing Habitable Surface Expansion |
||
286 | # so after construction we will have new slot on the planet |
||
287 | quantity = -1 |
||
288 | else: |
||
289 | continue |
||
290 | assert quantity != 0 |
||
291 | |||
292 | try: |
||
293 | targets[task.targetID] += task.quantity |
||
294 | except KeyError: |
||
295 | targets[task.targetID] = task.quantity |
||
296 | return targets |
||
297 | |||
298 | def _addProblemsSlots(self, problems, system): |
||
299 | player = client.getPlayer() |
||
300 | playerPlanets = set(system.planets) & set(player.planets) |
||
301 | freeSlots = {} |
||
302 | structSources = dict.fromkeys(system.planets) |
||
303 | for planetID in system.planets: |
||
304 | planet = client.get(planetID, noUpdate=1) |
||
305 | freeSlots[planetID] = planet.plSlots - len(planet.slots) |
||
306 | |||
307 | for planetID in playerPlanets: |
||
308 | for targetID, quantity in self._getTargetSlotDict(planetID).items(): |
||
309 | freeSlots[targetID] -= quantity |
||
310 | if quantity > 0: |
||
311 | try: |
||
312 | structSources[targetID].add(planetID) |
||
313 | except AttributeError: |
||
314 | structSources[targetID] = set([planetID]) |
||
315 | |||
316 | for planetID, free in freeSlots.items(): |
||
317 | if free < 0: |
||
318 | # not enough space, report for every planet that builds on this one |
||
319 | planet = client.get(planetID, noUpdate=1) |
||
320 | for sourceID in structSources[planetID]: |
||
321 | source = client.get(sourceID, noUpdate=1) |
||
322 | problems.append(gdata.MAJ, |
||
323 | ui.Item(source.name, tOID=sourceID, tType=Const.T_PLANET, |
||
324 | vDescription=_('There is no space for all constructed buildings on %s.') % (planet.name))) |
||
325 | |||
326 | def _addProblemsDefaultQueue(self, problems, planet, defaultQueueEtc): |
||
327 | player = client.getPlayer() |
||
328 | if not planet.effProdProd > 0: |
||
329 | return |
||
330 | planetEtc = 0 |
||
331 | # compute length of production queue |
||
332 | for task in planet.prodQueue: |
||
333 | if task.isShip: |
||
334 | tech = player.shipDesigns[task.techID] |
||
335 | else: |
||
336 | tech = client.getFullTechInfo(task.techID) |
||
337 | modifier = Rules.buildOnAnotherPlanetMod if task.targetID != planet.oid else 1 |
||
338 | planetEtc += math.ceil(float(task.quantity * tech.buildProd * modifier - task.currProd) / planet.effProdProd) |
||
339 | |||
340 | etc = planetEtc + defaultQueueEtc |
||
341 | # check empty production queue |
||
342 | if not etc: |
||
343 | problems.append(gdata.CRI, |
||
344 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
345 | vDescription=_('Production queue is empty.'))) |
||
346 | return |
||
347 | if etc < Rules.turnsPerDay: |
||
348 | severity = gdata.MAJ |
||
349 | elif etc < Rules.turnsPerDay * 2: |
||
350 | severity = gdata.MIN |
||
351 | else: |
||
352 | severity = gdata.INFO |
||
353 | |||
354 | problems.append(severity, |
||
355 | ui.Item(planet.name, tOID=planet.oid, tType=Const.T_PLANET, |
||
356 | vDescription=_('Production queue may end in {0} turns ({1} directly in planet queue).'.format(res.formatTime(etc), res.formatTime(planetEtc))))) |
||
357 | |||
358 | def show(self): |
||
359 | critical = self.win.vCritical.checked |
||
360 | major = self.win.vMajor.checked |
||
361 | minor = self.win.vMinor.checked |
||
362 | info = self.win.vInfo.checked |
||
363 | |||
364 | disp = 1 |
||
365 | |||
366 | player = client.getPlayer() |
||
367 | problems = self.Problems(self.win) |
||
368 | systems = set([]) |
||
369 | for planetID in player.planets: |
||
370 | planet = client.get(planetID, noUpdate=1) |
||
371 | systems.add(planet.compOf) |
||
372 | |||
373 | defaultQueueEtc = self._addProblemsGlobalQueues(problems) |
||
374 | |||
375 | for systemID in systems: |
||
376 | system = client.get(systemID, noUpdate=1) |
||
377 | bio = 0 |
||
378 | totalBio = 0 |
||
379 | en = 0 |
||
380 | totalEn = 0 |
||
381 | # holds modified planets |
||
382 | planetCopies = {} |
||
383 | |||
384 | for planetID in system.planets: |
||
385 | planet = client.get(planetID, noUpdate=1) |
||
386 | # copy of planet to change plSlots count |
||
387 | if hasattr(planet, 'owner') and planet.owner == player.oid: |
||
388 | # add planet to the global queue stats |
||
389 | # compute bio and en for system |
||
390 | bio += planet.changeBio |
||
391 | totalBio += max(0, planet.storBio - planet.minBio) |
||
392 | en += planet.changeEn |
||
393 | totalEn += max(0, planet.storEn - planet.minEn) |
||
394 | # the planet needs to have global queue 0 - the default one - to have its queue reported |
||
395 | if self.win.vPlanets.checked: |
||
396 | if not planet.globalQueue: |
||
397 | self._addProblemsDefaultQueue(problems, planet, defaultQueueEtc) |
||
398 | for struct in planet.slots: |
||
399 | self._addProblemsStructStatus(problems, struct, planet) |
||
400 | |||
401 | # free slots within the system |
||
402 | self._addProblemsSlots(problems, system) |
||
403 | # check bio for system |
||
404 | if self.win.vSystems.checked: |
||
405 | self._addProblemsMaterial(problems, system, bio, totalBio, 'Bio') |
||
406 | self._addProblemsMaterial(problems, system, en, totalEn, 'En') |
||
407 | |||
408 | # check fleets |
||
409 | if self.win.vFleets.checked: |
||
410 | for fleetID in player.fleets: |
||
411 | fleet = client.get(fleetID, noUpdate=1) |
||
412 | self._addProblemsFleets(problems, fleet) |
||
413 | |||
414 | # check research queue |
||
415 | if self.win.vResearch.checked: |
||
416 | self._addProblemsResearch(problems) |
||
417 | |||
418 | self.win.vProblems.items = problems.items |
||
419 | self.win.vProblems.itemsChanged() |
||
420 | |||
421 | def onClose(self, widget, action, data): |
||
422 | self.hide() |
||
423 | |||
424 | def onShowSource(self, widget, action, data): |
||
425 | item = self.win.vProblems.selection[0] |
||
426 | if item.tType == Const.T_FLEET: |
||
427 | object = client.get(item.tOID, noUpdate=1) |
||
428 | # center on map |
||
429 | if hasattr(object, "x"): |
||
430 | gdata.mainGameDlg.win.vStarMap.highlightPos = (object.x, object.y) |
||
431 | gdata.mainGameDlg.win.vStarMap.setPos(object.x, object.y) |
||
432 | self.hide() |
||
433 | return |
||
434 | elif item.tType in (Const.T_SYSTEM, Const.T_PLANET): |
||
435 | if item.tOID != Const.OID_NONE: |
||
436 | gdata.mainGameDlg.onSelectMapObj(None, None, item.tOID) |
||
437 | return |
||
438 | elif item.tType == Const.T_TECHNOLOGY: |
||
439 | gdata.mainGameDlg.researchDlg.display() |
||
440 | return |
||
441 | elif item.tType == Const.T_QUEUE: |
||
442 | gdata.mainGameDlg.globalQueuesDlg.display() |
||
443 | self.win.setStatus(_("Cannot show location.")) |
||
444 | |||
445 | def onShowLocation(self, widget, action, data): |
||
446 | item = self.win.vProblems.selection[0] |
||
447 | if item.tType in (Const.T_SYSTEM, Const.T_PLANET, Const.T_FLEET): |
||
448 | object = client.get(item.tOID, noUpdate=1) |
||
449 | # center on map |
||
450 | if hasattr(object, "x"): |
||
451 | gdata.mainGameDlg.win.vStarMap.highlightPos = (object.x, object.y) |
||
452 | gdata.mainGameDlg.win.vStarMap.setPos(object.x, object.y) |
||
453 | self.hide() |
||
454 | return |
||
455 | self.win.setStatus(_("Cannot show location.")) |
||
456 | |||
457 | def onToggleCondition(self, widget, action, data): |
||
458 | self.update() |
||
459 | |||
460 | def createUI(self): |
||
461 | screenWidth, screenHeight = gdata.scrnSize |
||
462 | # size of dialog in layout metrics (for SimpleGridLM) |
||
463 | cols = 40 |
||
464 | rows = 29 |
||
465 | # dialog width and height in pixels |
||
466 | isSmallWin = screenHeight == 600 and screenWidth == 800 |
||
467 | width = cols * 20 + 4 * (not isSmallWin) |
||
468 | height = rows * 20 + 4 * (not isSmallWin) |
||
469 | #creating dialog window |
||
470 | self.win = ui.Window(self.app, |
||
471 | modal=1, |
||
472 | escKeyClose=1, |
||
473 | movable=0, |
||
474 | title=_("Problems Locator"), |
||
475 | titleOnly=isSmallWin, |
||
476 | rect=ui.Rect((screenWidth - 800 - 4 * (not isSmallWin)) / 2, |
||
477 | (screenHeight - 600 - 4 * (not isSmallWin)) / 2, |
||
478 | width, |
||
479 | height), |
||
480 | layoutManager=ui.SimpleGridLM()) |
||
481 | self.win.subscribeAction('*', self) |
||
482 | # first row is window title |
||
483 | rows -= 1 |
||
484 | |||
485 | ui.Listbox(self.win, layout=(0, 0, cols, rows - 2), id='vProblems', |
||
486 | columns=[(_('Location'), 'text', 10, ui.ALIGN_W), |
||
487 | (_('Problem description'), 'vDescription', 30, ui.ALIGN_W)], |
||
488 | columnLabels=1, action='onShowSource', rmbAction='onShowLocation') |
||
489 | |||
490 | btnWidth = 4 |
||
491 | ui.Check(self.win, layout=(btnWidth * 0, rows - 2, btnWidth, 1), id='vSystems', |
||
492 | text=_('Systems'), action='onToggleCondition', checked=1) |
||
493 | ui.Check(self.win, layout=(btnWidth * 1, rows - 2, btnWidth, 1), id='vPlanets', |
||
494 | text=_('Planets'), action='onToggleCondition', checked=1) |
||
495 | ui.Check(self.win, layout=(btnWidth * 2, rows - 2, btnWidth, 1), id='vFleets', |
||
496 | text=_('Fleets'), action='onToggleCondition', checked=1) |
||
497 | ui.Check(self.win, layout=(btnWidth * 3, rows - 2, btnWidth, 1), id='vResearch', |
||
498 | text=_('Research'), action='onToggleCondition', checked=1) |
||
499 | |||
500 | ui.Check(self.win, layout=(btnWidth * 6, rows - 2, btnWidth, 1), id='vCritical', |
||
501 | text=_('Critical'), action='onToggleCondition', checked=1) |
||
502 | ui.Check(self.win, layout=(btnWidth * 7, rows - 2, btnWidth, 1), id='vMajor', |
||
503 | text=_('Major'), action='onToggleCondition', checked=1) |
||
504 | ui.Check(self.win, layout=(btnWidth * 8, rows - 2, btnWidth, 1), id='vMinor', |
||
505 | text=_('Minor'), action='onToggleCondition', checked=1) |
||
506 | ui.Check(self.win, layout=(btnWidth * 9, rows - 2, btnWidth, 1), id='vInfo', |
||
507 | text=_('Info'), action='onToggleCondition', checked=0) |
||
508 | |||
509 | # dialog bottom line |
||
510 | ui.Title(self.win, layout=(0, rows - 1, cols - 5, 1)) |
||
511 | ui.TitleButton(self.win, layout=(cols - 5, rows - 1, 5, 1), text=_("Close"), action='onClose') |
||
512 |