Passed
Pull Request — master (#291)
by Marek
02:19
created

osci.dialog.MessagesDlg.MessagesDlg.onShowLoc()   A

Complexity

Conditions 5

Size

Total Lines 13
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 13
nop 4
dl 0
loc 13
rs 9.2833
c 0
b 0
f 0
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
import pygameui as ui
22
from osci.StarMapWidget import StarMapWidget
23
from osci import gdata, res, client
24
import osci.messages
25
import ige.ospace.Const as Const
26
from NewMessageDlg import NewMessageDlg
27
from ConfirmDlg import ConfirmDlg
28
import time
29
from ige import log
30
import re
31
32
class MessagesDlg:
33
34
    def __init__(self, app):
35
        self.app = app
36
        self.createUI()
37
        #
38
        self.selectedObjID = None
39
        self.selectedForum = None
40
        self.selectedTopic = None
41
        self.selectedType = None
42
        self.newMessageDlg = NewMessageDlg(app)
43
        self.newMsgs = 0
44
        self.confirmDlg = ConfirmDlg(app)
45
        self.uignore = gdata.config.ignore.universe.split(',') if gdata.config.ignore.universe else []
46
        self.gignore = gdata.config.ignore.galaxy.split(',') if gdata.config.ignore.galaxy else []
47
        self.lignore = gdata.config.ignore.local.split(',') if gdata.config.ignore.local else []
48
49
    def display(self):
50
        self.show()
51
        self.win.show()
52
        # register for updates
53
        if self not in gdata.updateDlgs:
54
            gdata.updateDlgs.append(self)
55
56
    def hide(self):
57
        self.win.setStatus(_("Ready."))
58
        self.win.hide()
59
        # unregister updates
60
        if self in gdata.updateDlgs:
61
            gdata.updateDlgs.remove(self)
62
63
    def update(self):
64
        self.show()
65
66
    def show(self, updateForum = 1):
67
        self.newMsgs = 0
68
        #
69
        player = client.getPlayer()
70
        objList = [player.oid]
71
        objList.append(player.galaxy)
72
        objList.append(Const.OID_UNIVERSE)
73
        # show forums
74
        items = []
75
        colors = [gdata.sevColors[gdata.INFO], gdata.sevColors[gdata.MIN]]
76
        ## Inbox
77
        msgs, new = self.getMsgsNumber(player.oid, "INBOX",'local')
78
        self.newMsgs += new
79
        spec = gdata.mailboxSpec[Const.T_PLAYER, "INBOX"]
80
        item = ui.Item(_(spec[0]), tObjID=player.oid, tForum="INBOX",
81
                       tType=Const.T_PLAYER, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
82
        items.append(item)
83
        # Events
84
        msgs, new = self.getMsgsNumber(player.oid, "EVENTS")
85
        self.newMsgs += new
86
        spec = gdata.mailboxSpec[Const.T_PLAYER, "EVENTS"]
87
        eventsItem = ui.Item(_(spec[0]), tObjID=player.oid, tForum="EVENTS",
88
                             tType=Const.T_PLAYER, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
89
        items.append(eventsItem)
90
        # Outbox
91
        msgs, new = self.getMsgsNumber(player.oid, "OUTBOX")
92
        self.newMsgs += new
93
        spec = gdata.mailboxSpec[Const.T_PLAYER, "OUTBOX"]
94
        item = ui.Item(_(spec[0]), tObjID=player.oid, tForum="OUTBOX",
95
                       tType=Const.T_PLAYER, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
96
        items.append(item)
97
        ## galaxy
98
        galaxyID = player.galaxy
99
        galaxy = client.get(galaxyID)
100
        # folder
101
        item = ui.Item(_("Galaxy %s") % galaxy.name, tObjID=Const.OID_NONE, tForum="", tMsgs="", foreground=colors[0])
102
        items.append(item)
103
        # news
104
        msgs, new = self.getMsgsNumber(galaxyID, "NEWS")
105
        self.newMsgs += new
106
        spec = gdata.mailboxSpec[Const.T_GALAXY, "NEWS"]
107
        item = ui.Item("   %s" % _(spec[0]), tObjID=galaxyID, tForum="NEWS",
108
                       tType=Const.T_GALAXY, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
109
        items.append(item)
110
        # public
111
        msgs, new = self.getMsgsNumber(galaxyID, "PUBLIC",'galaxy')
112
        self.newMsgs += new
113
        spec = gdata.mailboxSpec[Const.T_GALAXY, "PUBLIC"]
114
        item = ui.Item("   %s" % _(spec[0]), tObjID=galaxyID, tForum="PUBLIC",
115
                       tType=Const.T_GALAXY, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
116
        items.append(item)
117
        ## universe
118
        item = ui.Item(_("Outer Space"), tObjID=Const.OID_NONE, tForum="", tMsgs="", foreground=colors[0])
119
        items.append(item)
120
        # news
121
        msgs, new = self.getMsgsNumber(Const.OID_UNIVERSE, "NEWS")
122
        self.newMsgs += new
123
        spec = gdata.mailboxSpec[Const.T_UNIVERSE, "NEWS"]
124
        item = ui.Item("   %s" % _(spec[0]), tObjID=Const.OID_UNIVERSE, tForum="NEWS",
125
                       tType=Const.T_UNIVERSE, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
126
        items.append(item)
127
        # public
128
        msgs, new = self.getMsgsNumber(Const.OID_UNIVERSE, "PUBLIC",'universe')
129
        self.newMsgs += new
130
        spec = gdata.mailboxSpec[Const.T_UNIVERSE, "PUBLIC"]
131
        item = ui.Item("   %s" % _(spec[0]), tObjID=Const.OID_UNIVERSE, tForum="PUBLIC",
132
                       tType=Const.T_UNIVERSE, tMsgs=_("%d / %d") % (new, msgs), foreground=colors[new > 0])
133
        items.append(item)
134
        #
135
        self.win.vForums.items = items
136
        self.win.vForums.itemsChanged()
137
        # find item to select
138
        found = 0
139
        for item in items:
140
            if item.tObjID == self.selectedObjID and item.tForum == self.selectedForum:
141
                self.win.vForums.selectItem(item)
142
                found = 1
143
                break
144
        if not found:
145
            self.win.vForums.selectItem(eventsItem)
146
        # display forum
147
        if updateForum:
148
            self.onForumSelected(None, None, None)
149
        # update mgs button
150
        gdata.mainGameDlg.updateMsgButton()
151
152
    def getMsgsNumber(self, objID, forum, forumtype='none'):
153
        try:
154
            messages = client.get(objID)._messages
155
        except AttributeError:
156
            log.debug("Suplying default messages for object", objID, forum)
157
            messages = {}
158
        new = 0
159
        msgs = 0
160
        for messageID in messages:
161
            message = messages[messageID]
162
            if ((forumtype == 'universe' and message["sender"] in self.uignore)
163
               or (forumtype == 'galaxy' and message["sender"] in self.gignore)
164
               or (forumtype == 'local' and message["sender"] in self.lignore)):
165
                continue
166
            if message["forum"] == forum:
167
                if message["readed"] == 0:
168
                    new += 1
169
                msgs += 1
170
        return msgs, new
171
172
    def _processMessage(self, message):
173
        # the old code had this to "regenerate topic from data". IDK what that means
174
        if "data" in message and message["topic"] == "EVENT":
175
            sourceID, msgID, locationID, turn, data = message["data"]
176
            message["topic"] = osci.messages.getMsgText(msgID, data).split("\n")[0]
177
        item = ui.Item(message["topic"])
178
        if "data" in message:
179
            sourceID, msgID, locationID, turn, data = message["data"]
180
            item.tLocationID = locationID
181
            item.tSourceID = sourceID
182
            obj = client.get(sourceID, noUpdate=1, publicOnly=1)  # Custom name in "sender"
183
            item.tSender = _('"%s"') % obj.customname if getattr(obj, 'customname', None) else message["sender"]
184
            foreground = gdata.sevColors[osci.messages.getMsgSeverity(msgID)]
185
            state = _(" ") if message["readed"] else _("N")
186
        else:
187
            item.tSender = message["sender"]
188
            if message["readed"]:
189
                foreground = gdata.sevColors[gdata.NONE]
190
                state = _("R") if message["replied"] else _(" ")
191
            else:
192
                foreground = gdata.sevColors[gdata.MIN]
193
                state = _("N")
194
        date = time.strftime(_("%m-%d %H:%M"), time.localtime(message["time"]))
195
        item.foreground = foreground
196
        item.tState = state
197
        item.tDate = date
198
        item.tDate_raw = message["time"]
199
        return item
200
201
    def onForumSelected(self, widget, action, data):
202
        selItem = self.win.vForums.selection[0]
203
        if selItem.tObjID == Const.OID_NONE:
204
            # select last valid
205
            for item in self.win.vForums.items:
206
                if item.tObjID == self.selectedObjID and item.tForum == self.selectedForum:
207
                    self.win.vForums.selectItem(item)
208
                    break
209
            return
210
        self.selectedObjID = selItem.tObjID
211
        self.selectedForum = selItem.tForum
212
        self.selectedType = selItem.tType
213
        self.win.vNewTopic.enabled = 1
214
        self.win.vAllReaded.enabled = 1
215
        self.win.vDeleteAll.enabled = 1
216
        player = client.getPlayer()
217
        playerid = player.oid
218
        objMessages = client.get(selItem.tObjID)._messages
219
        ids = objMessages.keys()
220
        ids.sort()
221
        ids.reverse()
222
        items = []
223
        for messageID in ids:
224
            message = objMessages[messageID]
225
            if message["forum"] == selItem.tForum:
226
                # ignore by universe, local (private messages), or galaxy
227
                if ((selItem.tObjID == Const.OID_UNIVERSE and message["sender"] in self.uignore)
228
                   or (selItem.tObjID == playerid and message["sender"] in self.lignore)
229
                   or (message["sender"] in self.gignore)):
230
                    continue
231
232
                item = self._processMessage(message)
233
                item.tMsgID = messageID
234
                item.tObjID = selItem.tObjID
235
                item.tForum = selItem.tForum
236
                item.tType = selItem.tType
237
                items.append(item)
238
        self.win.vMessages.items = items
239
        self.win.vMessages.itemsChanged()
240
        if self.selectedForum != "EVENTS":
241
            # reset messages scrollbar position
242
            self.win.vMessages.bar.slider.position = 0
243
        self.win.vMessages.itemsChanged()
244
        self.win.vMessage.text = [""]
245
        self.win.vReply.enabled = 0
246
        self.win.vNewTopic.enabled = gdata.mailboxSpec[selItem.tType, gdata.mailboxStripLang(selItem.tForum)][1] != None
247
        self.win.vDelete.enabled = len(self.win.vMessages.selection) > 0
248
249
    def onMessageSelected(self, widget, action, data):
250
        selItem = self.win.vMessages.selection[0]
251
        selItem.tState = " "
252
        message = client.get(selItem.tObjID)._messages[selItem.tMsgID]
253
        if "data" not in message:
254
            selItem.foreground = gdata.sevColors[gdata.NONE]
255
        self.win.vMessages.itemsChanged()
256
        message["readed"] = 1
257
        text = []
258
        if "data" in message:
259
            text = osci.messages.getFullMessageText(message).split("\n")
260
261
        if "text" in message:
262
            text.extend(message["text"].split("\n"))
263
264
        self.win.vMessage.text = text
265
        self.win.vMessage.offsetRow = 0
266
        self.win.vMessage.vertScrollbar.slider.position = 0
267
        self.win.vReply.enabled = gdata.mailboxSpec[selItem.tType, gdata.mailboxStripLang(selItem.tForum)][1] != None
268
        self.win.vDelete.enabled = 1
269
        self.show(updateForum = 0)
270
271
    def onNewTopic(self, widget, action, data):
272
        self.newMessageDlg.display(self, self.selectedObjID, self.selectedType, self.selectedForum)
273
274
    def onReply(self, widget, action, data):
275
        selItem = self.win.vMessages.selection[0]
276
        topic = client.get(selItem.tObjID)._messages[selItem.tMsgID]["topic"]
277
        self.newMessageDlg.display(self, self.selectedObjID, self.selectedType, self.selectedForum, selItem.tMsgID)
278
279
    def onRefresh(self, widget, action, data):
280
        client.getMessages()
281
        self.update()
282
283
    def onDelete(self, widget, action, data):
284
        selItem = self.win.vMessages.selection[0]
285
        del client.get(selItem.tObjID)._messages[selItem.tMsgID]
286
        self.update()
287
288
    def onDeleteAll(self, widget, action, data):
289
        self.confirmDlg.display(_("Delete all messages in this mailbox?"),
290
            _("Yes"), _("No"), self.onDeleteAllConfirmed)
291
292
    def onDeleteAllConfirmed(self):
293
        obj = client.get(self.selectedObjID)
294
        # must make list (changing directory)
295
        for messageID in obj._messages.keys():
296
            message = obj._messages[messageID]
297
            if message["forum"] == self.selectedForum:
298
                del obj._messages[messageID]
299
        self.update()
300
301
    def onAllReaded(self, widget, action, data):
302
        obj = client.get(self.selectedObjID)
303
        for messageID in obj._messages:
304
            message = obj._messages[messageID]
305
            if message["forum"] == self.selectedForum:
306
                message["readed"] = 1
307
        self.update()
308
309
    def onPostMenu(self, widget, action, data):
310
        selItem = self.win.vMessages.selection[0]
311
        if hasattr(selItem, "tLocationID"):
312
            self.eventPopup.show()
313
314
    def onShowLoc(self, widget, action, data):
315
        item = self.win.vMessages.selection[0]
316
        if item.tLocationID != Const.OID_NONE:
317
            obj = client.get(item.tLocationID, noUpdate=1)
318
            if hasattr(obj, "x"):
319
                gdata.mainGameDlg.win.vStarMap.highlightPos = (obj.x, obj.y)
320
                gdata.mainGameDlg.win.vStarMap.setPos(obj.x, obj.y)
321
                self.hide()
322
                return
323
        if item.tForum == "EVENTS" and re.match(('^%s(.*)')%(_('Research completed:')),item.text):
324
            gdata.mainGameDlg.researchDlg.display()
325
            return
326
        self.win.setStatus(_("Cannot show location"))
327
328
    def onShowLocDel(self, widget, action, data):
329
        self.onShowLoc(widget, action, data)
330
        self.onDelete(widget, action, data)
331
332
    def onShowSource(self, widget, action, data):
333
        item = self.win.vMessages.selection[0]
334
        if item.tForum == "EVENTS" and re.match(('^%s(.*)')%(_('Research completed:')),item.text):
335
            gdata.mainGameDlg.researchDlg.display()
336
            return
337
        if item.tSourceID != Const.OID_NONE:
338
            gdata.mainGameDlg.onSelectMapObj(None, None, item.tSourceID)
339
            #self.hide()
340
            return
341
        self.win.setStatus(_("Cannot show location"))
342
343
    def onShowSourceDel(self, widget, action, data):
344
        self.onShowSource(widget, action, data)
345
        self.onDelete(widget, action, data)
346
347
    def onClose(self, widget, action, data):
348
        self.hide()
349
350
    def createUI(self):
351
        w, h = gdata.scrnSize
352
        self.win = ui.Window(self.app,
353
                             modal=1,
354
                             escKeyClose=1,
355
                             titleOnly=w == 800 and h == 600,
356
                             movable=0,
357
                             title=_("Messages and events"),
358
                             rect=ui.Rect((w - 800 - 4 * (w != 800)) / 2, (h - 600 - 4 * (h != 600)) / 2, 800 + 4 * (w != 800), 580 + 4 * (h != 600)),
359
                             layoutManager=ui.SimpleGridLM())
360
        self.win.subscribeAction('*', self)
361
        # forums
362
        ui.Listbox(self.win, layout=(0, 0, 10, 27), id="vForums",
363
                   columns=((_("Channel"), "text", 5.5, ui.ALIGN_W), (_("#"), "tMsgs", 4.5, ui.ALIGN_E)),
364
                   columnLabels=1, action="onForumSelected", sortable=0)
365
        # topics
366
        ui.Listbox(self.win, layout=(10, 0, 30, 15), id="vMessages",
367
                   columns=((_(" "), "tState", 1, ui.ALIGN_NONE),
368
                            (_("Date"), "tDate", 4, ui.ALIGN_W),
369
                            (_("Sender"), "tSender", 7, ui.ALIGN_W),
370
                            (_("Subject"), "text", 0, ui.ALIGN_W)),
371
                   columnLabels=1, action="onMessageSelected", rmbAction="onPostMenu")
372
        # messages
373
        ui.Title(self.win, layout=(10, 15, 5, 1),
374
                 font="normal-bold", align=ui.ALIGN_W)
375
        ui.Button(self.win, layout=(15, 15, 5, 1), text=_("New subject"),
376
                  action="onNewTopic", id="vNewTopic", enabled=0)
377
        ui.Button(self.win, layout=(20, 15, 5, 1), text=_("Reply"),
378
                  action="onReply", id="vReply", enabled=0)
379
        ui.Button(self.win, layout=(25, 15, 5, 1), text=_("Read all"),
380
                  action="onAllReaded", id="vAllReaded", enabled=0)
381
        ui.Button(self.win, layout=(30, 15, 5, 1), text=_("Delete"),
382
                  action="onDelete", id="vDelete", enabled=0)
383
        ui.Button(self.win, layout=(35, 15, 5, 1), text=_("Delete all"),
384
                  action="onDeleteAll", id="vDeleteAll", enabled=0)
385
        s = ui.Scrollbar(self.win, layout=(39, 16, 1, 11))
386
        t = ui.Text(self.win, layout=(10, 16, 29, 11), id="vMessage", editable=0)
387
        t.attachVScrollbar(s)
388
        # status bar
389
        ui.TitleButton(self.win, layout=(30, 27, 5, 1), text=_('Refresh'), action='onRefresh')
390
        ui.TitleButton(self.win, layout=(35, 27, 5, 1), text=_('Close'), action='onClose')
391
        ui.Title(self.win, id='vStatusBar', layout=(0, 27, 30, 1), align=ui.ALIGN_W)
392
        # event menu
393
        self.eventPopup = ui.Menu(self.app, title=_("Message actions"),
394
                                  items=[ui.Item(_("Show location"), action="onShowLoc"),
395
                                         ui.Item(_("Show source"), action="onShowSource"),
396
                                         ui.Item(_("Show location and delete msg"), action="onShowLocDel"),
397
                                         ui.Item(_("Show source and delete msg"), action="onShowSourceDel"),
398
                                         ui.Item(_("Delete"), action="onDelete")])
399
        self.eventPopup.subscribeAction("*", self)
400