info_wins.py 12.3 KB
Newer Older
1 2 3 4 5 6 7 8
"""
Module defining all the "info wins", ie the bar which is on top of the
info buffer in normal tabs
"""

import logging
log = logging.getLogger(__name__)

9 10
from poezio.common import safeJID
from poezio.config import config
11

Link Mauve's avatar
Link Mauve committed
12
from poezio.windows.base_wins import Win
mathieui's avatar
mathieui committed
13
from poezio.windows.funcs import truncate_nick
14
from poezio.theming import get_theme, to_curses_attr
15

mathieui's avatar
mathieui committed
16

17 18 19 20 21
class InfoWin(Win):
    """
    Base class for all the *InfoWin, used in various tabs. For example
    MucInfoWin, etc. Provides some useful methods.
    """
mathieui's avatar
mathieui committed
22

23 24
    __slots__ = ()

25 26 27 28 29 30 31 32 33 34 35
    def __init__(self):
        Win.__init__(self)

    def print_scroll_position(self, window):
        """
        Print, like in Weechat, a -MORE(n)- where n
        is the number of available lines to scroll
        down
        """
        if window.pos > 0:
            plus = ' -MORE(%s)-' % window.pos
mathieui's avatar
mathieui committed
36 37 38
            self.addstr(plus,
                        to_curses_attr(get_theme().COLOR_SCROLLABLE_NUMBER))

39 40 41 42 43

class XMLInfoWin(InfoWin):
    """
    Info about the latest xml filter used and the state of the buffer.
    """
mathieui's avatar
mathieui committed
44

45 46
    __slots__ = ()

47 48 49 50 51
    def __init__(self):
        InfoWin.__init__(self)

    def refresh(self, filter_t='', filter='', window=None):
        log.debug('Refresh: %s', self.__class__.__name__)
52 53 54 55 56 57 58 59 60 61
        self._win.erase()
        bar = to_curses_attr(get_theme().COLOR_INFORMATION_BAR)
        if not filter_t:
            self.addstr('[No filter]', bar)
        else:
            info = '[%s] %s' % (filter_t, filter)
            self.addstr(info, bar)
        self.print_scroll_position(window)
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
62

mathieui's avatar
mathieui committed
63

64 65
class PrivateInfoWin(InfoWin):
    """
66
    The line above the information window, displaying information
67 68
    about the MUC user we are talking to
    """
mathieui's avatar
mathieui committed
69

70 71
    __slots__ = ()

72 73 74
    def __init__(self):
        InfoWin.__init__(self)

75
    def refresh(self, name, window, chatstate, information):
76
        log.debug('Refresh: %s', self.__class__.__name__)
77 78 79 80
        self._win.erase()
        self.write_room_name(name)
        self.print_scroll_position(window)
        self.write_chatstate(chatstate)
81
        self.write_additional_information(information, name)
82 83
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
84

85
    def write_additional_information(self, information, jid):
86
        """
87
        Write all information added by plugins by getting the
88 89
        value returned by the callbacks.
        """
90
        for key in information:
mathieui's avatar
mathieui committed
91 92
            self.addstr(information[key](jid),
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
93 94 95 96 97 98 99 100 101 102

    def write_room_name(self, name):
        jid = safeJID(name)
        room_name, nick = jid.bare, jid.resource
        self.addstr(nick, to_curses_attr(get_theme().COLOR_PRIVATE_NAME))
        txt = ' from room %s' % room_name
        self.addstr(txt, to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

    def write_chatstate(self, state):
        if state:
mathieui's avatar
mathieui committed
103 104 105
            self.addstr(' %s' % (state, ),
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

106 107 108

class MucListInfoWin(InfoWin):
    """
109
    The live above the information window, displaying informatios
110 111
    about the muc server being listed
    """
mathieui's avatar
mathieui committed
112

113 114
    __slots__ = ('message')

115 116 117 118 119 120
    def __init__(self, message=''):
        InfoWin.__init__(self)
        self.message = message

    def refresh(self, name=None, window=None):
        log.debug('Refresh: %s', self.__class__.__name__)
121 122
        self._win.erase()
        if name:
mathieui's avatar
mathieui committed
123 124
            self.addstr(name,
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
125
        else:
mathieui's avatar
mathieui committed
126 127
            self.addstr(self.message,
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
128 129 130 131
        if window:
            self.print_scroll_position(window)
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
132

mathieui's avatar
mathieui committed
133

134 135
class ConversationInfoWin(InfoWin):
    """
136
    The line above the information window, displaying information
137 138 139
    about the user we are talking to
    """

140 141
    __slots__ = ()

142 143 144
    def __init__(self):
        InfoWin.__init__(self)

145
    def refresh(self, jid, contact, window, chatstate, information):
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
        # contact can be None, if we receive a message
        # from someone not in our roster. In this case, we display
        # only the maximum information from the message we can get.
        log.debug('Refresh: %s', self.__class__.__name__)
        jid = safeJID(jid)
        if contact:
            if jid.resource:
                resource = contact[jid.full]
            else:
                resource = contact.get_highest_priority_resource()
        else:
            resource = None
        # if contact is None, then resource is None too:
        # user is not in the roster so we know almost nothing about it
        # If contact is a Contact, then
        # resource can now be a Resource: user is in the roster and online
        # or resource is None: user is in the roster but offline
163
        self._win.erase()
164 165
        if config.get('show_jid_in_conversations'):
            self.write_contact_jid(jid)
166
        self.write_contact_information(contact)
167 168 169
        self.write_resource_information(resource)
        self.print_scroll_position(window)
        self.write_chatstate(chatstate)
170
        self.write_additional_information(information, jid)
171 172
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
173

174
    def write_additional_information(self, information, jid):
175
        """
176
        Write all information added by plugins by getting the
177 178
        value returned by the callbacks.
        """
179 180
        for key in information:
            self.addstr(information[key](jid),
mathieui's avatar
mathieui committed
181
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
182 183 184

    def write_resource_information(self, resource):
        """
185
        Write the information about the resource
186 187 188 189 190 191
        """
        if not resource:
            presence = "unavailable"
        else:
            presence = resource.presence
        color = get_theme().color_show(presence)
192 193
        if not presence:
            presence = get_theme().CHAR_STATUS
194
        self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
195 196
        self.addstr(presence, to_curses_attr(color))
        if resource and resource.status:
ge0rg's avatar
ge0rg committed
197
            shortened = resource.status[:20] + (resource.status[:20] and '…')
mathieui's avatar
mathieui committed
198 199
            self.addstr(' %s' % shortened,
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
200 201
        self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

202
    def write_contact_information(self, contact):
203
        """
204
        Write the information about the contact
205 206
        """
        if not contact:
mathieui's avatar
mathieui committed
207 208
            self.addstr("(contact not in roster)",
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
209 210 211
            return
        display_name = contact.name
        if display_name:
mathieui's avatar
mathieui committed
212 213
            self.addstr('%s ' % (display_name),
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
214 215 216 217 218 219

    def write_contact_jid(self, jid):
        """
        Just write the jid that we are talking to
        """
        self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
mathieui's avatar
mathieui committed
220 221
        self.addstr(jid.full,
                    to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
222 223 224 225
        self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

    def write_chatstate(self, state):
        if state:
mathieui's avatar
mathieui committed
226 227 228
            self.addstr(' %s' % (state, ),
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

229 230

class DynamicConversationInfoWin(ConversationInfoWin):
231 232
    __slots__ = ()

233 234 235 236 237
    def write_contact_jid(self, jid):
        """
        Just displays the resource in an other color
        """
        log.debug("write_contact_jid DynamicConversationInfoWin, jid: %s",
mathieui's avatar
mathieui committed
238
                  jid.resource)
239
        self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
mathieui's avatar
mathieui committed
240 241
        self.addstr(jid.bare,
                    to_curses_attr(get_theme().COLOR_CONVERSATION_NAME))
242
        if jid.resource:
mathieui's avatar
mathieui committed
243 244 245
            self.addstr(
                "/%s" % (jid.resource, ),
                to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE))
246 247
        self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

mathieui's avatar
mathieui committed
248

249 250
class MucInfoWin(InfoWin):
    """
251
    The line just above the information window, displaying information
252 253
    about the MUC we are viewing
    """
mathieui's avatar
mathieui committed
254

255 256
    __slots__ = ()

257 258 259
    def __init__(self):
        InfoWin.__init__(self)

260
    def refresh(self, room, window=None, user=None):
261
        log.debug('Refresh: %s', self.__class__.__name__)
262 263 264 265 266
        self._win.erase()
        self.write_room_name(room)
        self.write_participants_number(room)
        self.write_own_nick(room)
        self.write_disconnected(room)
267
        self.write_role(room, user)
268 269 270 271
        if window:
            self.print_scroll_position(window)
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
272 273 274

    def write_room_name(self, room):
        self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
mathieui's avatar
mathieui committed
275 276
        self.addstr(room.name,
                    to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME))
277 278 279 280
        self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

    def write_participants_number(self, room):
        self.addstr('{', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
mathieui's avatar
mathieui committed
281 282 283
        self.addstr(
            str(len(room.users)),
            to_curses_attr(get_theme().COLOR_GROUPCHAT_NAME))
284 285 286 287 288 289 290
        self.addstr('} ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

    def write_disconnected(self, room):
        """
        Shows a message if the room is not joined
        """
        if not room.joined:
mathieui's avatar
mathieui committed
291 292
            self.addstr(' -!- Not connected ',
                        to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
293 294 295 296 297 298 299 300

    def write_own_nick(self, room):
        """
        Write our own nick in the info bar
        """
        nick = room.own_nick
        if not nick:
            return
mathieui's avatar
mathieui committed
301 302 303
        self.addstr(
            truncate_nick(nick, 13),
            to_curses_attr(get_theme().COLOR_INFORMATION_BAR))
304

305
    def write_role(self, room, user):
306 307 308
        """
        Write our own role and affiliation
        """
309
        if not user:
310 311
            return
        txt = ' ('
312 313 314
        if user.affiliation != 'none':
            txt += user.affiliation + ', '
        txt += user.role + ')'
315 316
        self.addstr(txt, to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

mathieui's avatar
mathieui committed
317

318 319 320 321
class ConversationStatusMessageWin(InfoWin):
    """
    The upper bar displaying the status message of the contact
    """
mathieui's avatar
mathieui committed
322

323 324
    __slots__ = ()

325 326 327 328 329 330 331 332 333 334 335 336 337
    def __init__(self):
        InfoWin.__init__(self)

    def refresh(self, jid, contact):
        log.debug('Refresh: %s', self.__class__.__name__)
        jid = safeJID(jid)
        if contact:
            if jid.resource:
                resource = contact[jid.full]
            else:
                resource = contact.get_highest_priority_resource()
        else:
            resource = None
338 339 340 341 342
        self._win.erase()
        if resource:
            self.write_status_message(resource)
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()
343 344

    def write_status_message(self, resource):
mathieui's avatar
mathieui committed
345 346 347
        self.addstr(resource.status,
                    to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

348

mathieui's avatar
mathieui committed
349
class BookmarksInfoWin(InfoWin):
350 351
    __slots__ = ()

mathieui's avatar
mathieui committed
352 353 354 355 356 357 358 359 360 361 362
    def __init__(self):
        InfoWin.__init__(self)

    def refresh(self, preferred):
        log.debug('Refresh: %s', self.__class__.__name__)
        self._win.erase()
        self.write_remote_status(preferred)
        self.finish_line(get_theme().COLOR_INFORMATION_BAR)
        self._refresh()

    def write_remote_status(self, preferred):
mathieui's avatar
mathieui committed
363 364 365
        self.addstr('Remote storage: %s' % preferred,
                    to_curses_attr(get_theme().COLOR_INFORMATION_BAR))

mathieui's avatar
mathieui committed
366

mathieui's avatar
mathieui committed
367
class ConfirmStatusWin(Win):
368 369
    __slots__ = ('text', 'critical')

mathieui's avatar
mathieui committed
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    def __init__(self, text, critical=False):
        Win.__init__(self)
        self.text = text
        self.critical = critical

    def refresh(self):
        log.debug('Refresh: %s', self.__class__.__name__)
        self._win.erase()
        if self.critical:
            color = get_theme().COLOR_WARNING_PROMPT
        else:
            color = get_theme().COLOR_INFORMATION_BAR
        c_color = to_curses_attr(color)
        self.addstr(self.text, c_color)
        self.finish_line(color)
        self._refresh()