osci.dialog.GlobalQueuesDlg   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 235
dl 0
loc 300
rs 8.5599
c 0
b 0
f 0
wmc 48

16 Methods

Rating   Name   Duplication   Size   Complexity  
A GlobalQueuesDlg.onAbortTask() 0 3 1
A GlobalQueuesDlg.onClose() 0 2 1
A GlobalQueuesDlg.showProdQueue() 0 25 4
A GlobalQueuesDlg.__init__() 0 13 1
A GlobalQueuesDlg.hide() 0 10 3
A GlobalQueuesDlg.onTaskInfo() 0 10 4
B GlobalQueuesDlg.createUI() 0 65 1
A GlobalQueuesDlg.display() 0 7 2
A GlobalQueuesDlg.onChangeQtyConfirmed() 0 12 3
A GlobalQueuesDlg.onQtyTask() 0 5 3
A GlobalQueuesDlg.update() 0 8 3
B GlobalQueuesDlg.onAbortTaskConfirmed() 0 23 7
A GlobalQueuesDlg.onMoveTask() 0 12 4
A GlobalQueuesDlg.show() 0 6 2
A GlobalQueuesDlg.onMoveTaskFirstLast() 0 21 5
A GlobalQueuesDlg.onQueueItemSelected() 0 22 4

How to fix   Complexity   

Complexity

Complex classes like osci.dialog.GlobalQueuesDlg 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
21
# TODO rewrite it to support general number of queues, not just 5 and to make
22
# the code nicer
23
24
import pygameui as ui
25
from ChangeQtyDlg import ChangeQtyDlg
26
from NewGlobalTaskDlg import NewGlobalTaskDlg
27
from ConstructionDlg import ConstructionDlg
28
from TechInfoDlg import TechInfoDlg
29
from ConfirmDlg import ConfirmDlg
30
from osci.StarMapWidget import StarMapWidget
31
from osci import gdata, res, client, sequip
32
import ige.ospace.Const as Const
33
from ige.ospace import ShipUtils, Rules
34
from ige import GameException
35
from ige import log
36
import math
37
38
class GlobalQueuesDlg:
39
40
    def __init__(self, app):
41
        self.app = app
42
        self.player = None
43
        self.vPQueues = None
44
        self.queueNo = 5
45
        self.activeQueue = 0
46
        self.activeIndex = None
47
        self.changeQtyDlg = ChangeQtyDlg(app)
48
        self.newGlobalTaskDlg = NewGlobalTaskDlg(self.app)
49
        self.constructionDlg = ConstructionDlg(app)
50
        self.techInfoDlg = TechInfoDlg(app)
51
        self.confirmDlg = ConfirmDlg(app)
52
        self.createUI()
53
54
    def display(self):
55
        self.playerID = client.getPlayerID()
56
        self.show()
57
        self.win.show()
58
        # register for updates
59
        if self not in gdata.updateDlgs:
60
            gdata.updateDlgs.append(self)
61
62
    def hide(self):
63
        self.win.setStatus(_("Ready."))
64
        self.win.hide()
65
        if self.activeQueue is not None:
66
            # we don't want current selection to be visible next time we open the dialog
67
            self.vPQueues[self.activeQueue].selectItem(None)
68
            self.win.setTagAttr('data', 'visible', False)
69
        # unregister updates
70
        if self in gdata.updateDlgs:
71
            gdata.updateDlgs.remove(self)
72
73
    def update(self):
74
        self.show()
75
        if self.activeQueue is not None:
76
            if self.activeIndex is not None:
77
                # restore selection, as the items are recreated in show routine
78
                self.vPQueues[self.activeQueue].selectItem(self.vPQueues[self.activeQueue].items[self.activeIndex])
79
            else:
80
                self.vPQueues[self.activeQueue].selectItem(None)
81
82
    def show(self):
83
        self.player = client.getPlayer()
84
        self.vPQueues = [self.win.vPQueue0, self.win.vPQueue1, self.win.vPQueue2, self.win.vPQueue3, self.win.vPQueue4]
85
        #
86
        for queueNo in xrange(self.queueNo):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable xrange does not seem to be defined.
Loading history...
87
            self.showProdQueue(queueNo)
88
89
    def showProdQueue(self, id):
90
        # construction queue
91
        prodQueue = self.player.prodQueues[id]
92
        items = []
93
94
        index = 0
95
        for task in prodQueue:
96
            if task.isShip:
97
                tech = self.player.shipDesigns[task.techID]
98
                icons = ((res.getShipImg(tech.combatClass, tech.isMilitary), ui.ALIGN_NONE),)
99
            else:
100
                tech = client.getFullTechInfo(task.techID)
101
                icons = ((res.getTechImg(task.techID), ui.ALIGN_NONE),)
102
            item = ui.Item(text = str(task.quantity), font = 'small', align = ui.ALIGN_NE, icons = icons, tooltipTitle = "", tooltip = tech.name, statustip = tech.name, index = index, const = tech.buildProd*task.quantity)
103
            if task.isShip:
104
                item.background = None
105
            else:
106
                item.background = (0x44, 0x44, 0x44)
107
            items.append(item)
108
            index += 1
109
        icons = ((res.getTechImg(1), ui.ALIGN_NONE),)
110
        item = ui.Item(_('New'), font = 'small-bold', align = ui.ALIGN_SW, icons = icons, index = None)
111
        items.append(item)
112
        self.vPQueues[id].items = items
113
        self.vPQueues[id].itemsChanged()
114
115
    def onQueueItemSelected(self, widget, action, data):
116
        if widget.orderNo != self.activeQueue:
117
            self.vPQueues[self.activeQueue].selectItem(None)
118
        self.activeQueue = widget.orderNo
119
        if not data:
120
            # unselected
121
            self.activeIndex = None
122
            self.win.setTagAttr('data', 'visible', False)
123
        elif data.index == None:
124
            # new task
125
            self.win.setTagAttr('data', 'visible', False)
126
            self.activeIndex = None
127
            self.newGlobalTaskDlg.display(self, self.activeQueue)
128
            self.vPQueues[self.activeQueue].selectItem(None)
129
        else:
130
            # info about task
131
            task = self.vPQueues[self.activeQueue].items[data.index]
132
            self.activeIndex = data.index
133
            self.win.setTagAttr('data', 'visible', True)
134
            self.win.vTaskName.text = task.tooltip
135
            self.win.vTaskQuantity.text = task.text
136
            self.win.vTaskConstPoints.text = task.const
137
138
    def onMoveTaskFirstLast(self, widget, action, data):
139
        if self.activeQueue == None or self.activeIndex == None:
140
            return
141
142
        if widget.data == -1:
143
            rel = -1 * self.activeIndex
144
            pos = 0
145
        else:
146
            rel = len(self.player.prodQueues[self.activeQueue]) - self.activeIndex - 1
147
            pos = len(self.player.prodQueues[self.activeQueue]) - 1
148
149
        try:
150
            self.win.setStatus(_('Executing MOVE TASK command...'))
151
            self.player.prodQueues[self.activeQueue] = client.cmdProxy.moveGlobalConstrItem(self.playerID, self.activeQueue, self.activeIndex, rel)
152
            self.win.setStatus(_('Command has been executed.'))
153
        except GameException, e:
154
            self.win.setStatus(e.args[0])
155
            return
156
157
        self.activeIndex = pos
158
        self.update()
159
160
    def onMoveTask(self, widget, action, data):
161
        if self.activeQueue == None or self.activeIndex == None:
162
            return
163
        try:
164
            self.win.setStatus(_('Executing MOVE TASK command...'))
165
            self.player.prodQueues[self.activeQueue] = client.cmdProxy.moveGlobalConstrItem(self.playerID, self.activeQueue, self.activeIndex, widget.data)
166
            self.win.setStatus(_('Command has been executed.'))
167
        except GameException, e:
168
            self.win.setStatus(e.args[0])
169
            return
170
        self.activeIndex += widget.data
171
        self.update()
172
173
    def onQtyTask(self, widget, action, data):
174
        if self.activeQueue == None or self.activeIndex == None:
175
            return
176
        task = self.player.prodQueues[self.activeQueue][self.activeIndex]
177
        self.changeQtyDlg.display(task.quantity, self.onChangeQtyConfirmed)
178
179
    def onChangeQtyConfirmed(self):
180
        if self.changeQtyDlg.quantity != None:
181
            try:
182
                self.win.setStatus(_('Executing CHANGE TASK command...'))
183
                self.player.prodQueues[self.activeQueue], self.player.stratRes = client.cmdProxy.changeGlobalConstruction(self.playerID, self.activeQueue, self.activeIndex, self.changeQtyDlg.quantity)
184
                self.win.setStatus(_('Command has been executed.'))
185
            except GameException, e:
186
                self.win.setStatus(e.args[0])
187
                return
188
        self.win.vTaskQuantity.text = self.player.prodQueues[self.activeQueue][self.activeIndex].quantity
189
        self.win.vTaskConstPoints.text = self.player.prodQueues[self.activeQueue][self.activeIndex].const
190
        self.update()
191
192
    def onTaskInfo(self, widget, action, data):
193
        if self.activeQueue == None or self.activeIndex == None:
194
            return
195
        task = self.player.prodQueues[self.activeQueue][self.activeIndex]
196
        if not task.isShip:
197
            self.techInfoDlg.display(task.techID)
198
        else:
199
            log.debug("Show ship info")
200
            self.constructionDlg.selectedDesignID = task.techID;
201
            self.constructionDlg.display()
202
203
    def onAbortTask(self, widget, action, data):
204
        self.confirmDlg.display(_("Abort this construction task?"),
205
            _("Yes"), _("No"), self.onAbortTaskConfirmed)
206
207
    def onAbortTaskConfirmed(self):
208
        if self.activeQueue is not None and self.activeIndex is not None:
209
            try:
210
                self.win.setStatus(_('Executing ABORT CONSTRUCTION command...'))
211
                self.player.prodQueues[self.activeQueue], self.player.stratRes = client.cmdProxy.abortGlobalConstruction(self.playerID, self.activeQueue, self.activeIndex)
212
                self.win.setStatus(_('Command has been executed.'))
213
            except GameException, e:
214
                self.win.setStatus(e.args[0])
215
                return
216
            if len(self.player.prodQueues[self.activeQueue]) == self.activeIndex:
217
                if self.activeIndex == 0:
218
                    self.activeIndex = None
219
                else:
220
                    self.activeIndex -= 1
221
222
        self.update()
223
        if self.activeIndex is not None:
224
            task = self.vPQueues[self.activeQueue].items[self.activeIndex]
225
            self.win.vTaskName.text = task.tooltip
226
            self.win.vTaskQuantity.text = task.text
227
            self.win.vTaskConstPoints.text = task.const
228
        else:
229
            self.win.setTagAttr('data', 'visible', False)
230
231
232
    def onClose(self, widget, action, data):
233
        self.hide()
234
235
    def createUI(self):
236
        w, h = gdata.scrnSize
237
        self.win = ui.Window(self.app,
238
            modal = 1,
239
            escKeyClose = 1,
240
            movable = 0,
241
            title = _('Global production queues'),
242
            rect = ui.Rect((w - 400 - 4 ) / 2, (h - 440 - 4 ) / 2, 400 + 4 , 420 + 4 ),
243
            layoutManager = ui.SimpleGridLM(),
244
        )
245
        self.win.subscribeAction('*', self)
246
        ui.Title(self.win, layout = (0, 0, 20, 1), text = _('Default global queue'),
247
            align = ui.ALIGN_W, font = 'normal-bold')
248
        ui.ButtonArray(self.win, layout = (0, 1, 20, 2), id = 'vPQueue0',
249
            buttonSize = (2, 2), showSlider = 0, tags = ['pl'], action = 'onQueueItemSelected', orderNo = 0)
250
        ui.Title(self.win, layout = (0, 3, 20, 1), text = _('Queue \"{0}\"'.format(res.globalQueueName(1))),
251
            align = ui.ALIGN_W, font = 'normal-bold')
252
        ui.ButtonArray(self.win, layout = (0, 4, 20, 2), id = 'vPQueue1',
253
            buttonSize = (2, 2), showSlider = 0, tags = ['pl'], action = 'onQueueItemSelected', orderNo = 1)
254
        ui.Title(self.win, layout = (0, 6, 20, 1), text = _('Queue \"{0}\"'.format(res.globalQueueName(2))),
255
            align = ui.ALIGN_W, font = 'normal-bold')
256
        ui.ButtonArray(self.win, layout = (0, 7, 20, 2), id = 'vPQueue2',
257
            buttonSize = (2, 2), showSlider = 0, tags = ['pl'], action = 'onQueueItemSelected', orderNo = 2)
258
        ui.Title(self.win, layout = (0, 9, 20, 1), text = _('Queue \"{0}\"'.format(res.globalQueueName(3))),
259
            align = ui.ALIGN_W, font = 'normal-bold')
260
        ui.ButtonArray(self.win, layout = (0, 10, 20, 2), id = 'vPQueue3',
261
            buttonSize = (2, 2), showSlider = 0, tags = ['pl'], action = 'onQueueItemSelected', orderNo = 3)
262
        ui.Title(self.win, layout = (0, 12, 20, 1), text = _('Queue \"{0}\"'.format(res.globalQueueName(4))),
263
            align = ui.ALIGN_W, font = 'normal-bold')
264
        ui.ButtonArray(self.win, layout = (0, 13, 20, 2), id = 'vPQueue4',
265
            buttonSize = (2, 2), showSlider = 0, tags = ['pl'], action = 'onQueueItemSelected', orderNo = 4)
266
        ui.Label(self.win, layout = (0, 16, 20, 1), id = 'vTaskName', align = ui.ALIGN_W,
267
            font = 'normal-bold', tags = ['queue', 'data'])
268
        ui.Label(self.win, layout = (9, 17, 7, 1), text = _('Construction pts'),
269
            align = ui.ALIGN_W, tags = ['queue'])
270
        ui.Label(self.win, layout = (16, 17, 4, 1), id = 'vTaskConstPoints', align = ui.ALIGN_E,
271
            tags = ['queue', 'data'])
272
        ui.Label(self.win, layout = (0, 17, 5, 1), text = _('Quantity'),
273
            align = ui.ALIGN_W, tags = ['queue'])
274
        ui.Label(self.win, layout = (5, 17, 3, 1), id = 'vTaskQuantity', align = ui.ALIGN_E,
275
            tags = ['queue', 'data'])
276
        ui.Button(self.win, layout = (0, 18, 2, 1), id = 'vITFirst', text = _('<<'),
277
            tags = ['queue'], action = 'onMoveTaskFirstLast',
278
            tooltipTitle = _('Move task to first position in queue'), data = -1)
279
        ui.Button(self.win, layout = (2, 18, 2, 1), id = 'vITPrev', text = _('<'),
280
            tags = ['queue'], action = 'onMoveTask', data = -1,
281
            tooltipTitle = _('Move task to previous position in queue'))
282
        ui.Button(self.win, layout = (4, 18, 2, 1), id = 'vITNext', text = _('>'),
283
            tags = ['queue'], action = 'onMoveTask', data = 1,
284
            tooltipTitle = _('Move task to next position in queue'))
285
        ui.Button(self.win, layout = (6, 18, 2, 1), id = 'vITLast', text = _('>>'),
286
            tags = ['queue'], action = 'onMoveTaskFirstLast',
287
            tooltipTitle = _('Move task to last position in queue'), data = 1)
288
        ui.Button(self.win, layout = (8, 18, 4, 1), text = _('Quantity'),
289
            tags = ['queue'], action = 'onQtyTask',
290
            tooltipTitle = _('Change task quantity'))
291
        ui.Button(self.win, layout = (12, 18, 4, 1), text = _('Info'), id = "vITInfo",
292
            tags = ['queue'], action = 'onTaskInfo',
293
            tooltipTitle = _('Show task informations'))
294
        ui.Button(self.win, layout = (16, 18, 4, 1), text = _('Abort'),
295
            tags = ['queue'], action = 'onAbortTask',
296
            tooltipTitle = _('Abort task construction'))
297
        # status bar + submit/cancel
298
        ui.TitleButton(self.win, layout = (15, 19, 5, 1), text = _('Close'), action = 'onClose')
299
        ui.Title(self.win, id = 'vStatusBar', layout = (0, 19, 15, 1), align = ui.ALIGN_W)
300
        #self.win.statusBar = self.win.vStatusBar
301
302