]> jfr.im git - irc/weechat/qweechat.git/blob - qweechat/buffer.py
d4a7ef352af09a11e05aaf37d0b57b452a3b9f68
[irc/weechat/qweechat.git] / qweechat / buffer.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # buffer.py - management of WeeChat buffers/nicklist
5 #
6 # Copyright (C) 2011-2014 Sébastien Helleu <flashcode@flashtux.org>
7 #
8 # This file is part of QWeeChat, a Qt remote GUI for WeeChat.
9 #
10 # QWeeChat is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # QWeeChat is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with QWeeChat. If not, see <http://www.gnu.org/licenses/>.
22 #
23
24 from pkg_resources import resource_filename
25 import qt_compat
26 QtCore = qt_compat.import_module('QtCore')
27 QtGui = qt_compat.import_module('QtGui')
28 from chat import ChatTextEdit
29 from input import InputLineEdit
30 import weechat.color as color
31
32
33 class GenericListWidget(QtGui.QListWidget):
34 """Generic QListWidget with dynamic size."""
35
36 def __init__(self, *args):
37 QtGui.QListWidget.__init__(*(self,) + args)
38 self.setMaximumWidth(100)
39 self.setTextElideMode(QtCore.Qt.ElideNone)
40 self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
41 self.setFocusPolicy(QtCore.Qt.NoFocus)
42 pal = self.palette()
43 pal.setColor(QtGui.QPalette.Highlight, QtGui.QColor('#ddddff'))
44 pal.setColor(QtGui.QPalette.HighlightedText, QtGui.QColor('black'))
45 self.setPalette(pal)
46
47 def auto_resize(self):
48 size = self.sizeHintForColumn(0)
49 if size > 0:
50 size += 4
51 self.setMaximumWidth(size)
52
53 def clear(self, *args):
54 """Re-implement clear to set dynamic size after clear."""
55 QtGui.QListWidget.clear(*(self,) + args)
56 self.auto_resize()
57
58 def addItem(self, *args):
59 """Re-implement addItem to set dynamic size after add."""
60 QtGui.QListWidget.addItem(*(self,) + args)
61 self.auto_resize()
62
63 def insertItem(self, *args):
64 """Re-implement insertItem to set dynamic size after insert."""
65 QtGui.QListWidget.insertItem(*(self,) + args)
66 self.auto_resize()
67
68
69 class BufferListWidget(GenericListWidget):
70 """Widget with list of buffers."""
71
72 def __init__(self, *args):
73 GenericListWidget.__init__(*(self,) + args)
74
75 def switch_prev_buffer(self):
76 if self.currentRow() > 0:
77 self.setCurrentRow(self.currentRow() - 1)
78 else:
79 self.setCurrentRow(self.count() - 1)
80
81 def switch_next_buffer(self):
82 if self.currentRow() < self.count() - 1:
83 self.setCurrentRow(self.currentRow() + 1)
84 else:
85 self.setCurrentRow(0)
86
87
88 class BufferWidget(QtGui.QWidget):
89 """
90 Widget with (from top to bottom):
91 title, chat + nicklist (optional) + prompt/input.
92 """
93
94 def __init__(self, display_nicklist=False):
95 QtGui.QWidget.__init__(self)
96
97 # title
98 self.title = QtGui.QLineEdit()
99 self.title.setFocusPolicy(QtCore.Qt.NoFocus)
100
101 # splitter with chat + nicklist
102 self.chat_nicklist = QtGui.QSplitter()
103 self.chat_nicklist.setSizePolicy(QtGui.QSizePolicy.Expanding,
104 QtGui.QSizePolicy.Expanding)
105 self.chat = ChatTextEdit(debug=False)
106 self.chat_nicklist.addWidget(self.chat)
107 self.nicklist = GenericListWidget()
108 if not display_nicklist:
109 self.nicklist.setVisible(False)
110 self.chat_nicklist.addWidget(self.nicklist)
111
112 # prompt + input
113 self.hbox_edit = QtGui.QHBoxLayout()
114 self.hbox_edit.setContentsMargins(0, 0, 0, 0)
115 self.hbox_edit.setSpacing(0)
116 self.input = InputLineEdit(self.chat)
117 self.hbox_edit.addWidget(self.input)
118 prompt_input = QtGui.QWidget()
119 prompt_input.setLayout(self.hbox_edit)
120
121 # vbox with title + chat/nicklist + prompt/input
122 vbox = QtGui.QVBoxLayout()
123 vbox.setContentsMargins(0, 0, 0, 0)
124 vbox.setSpacing(0)
125 vbox.addWidget(self.title)
126 vbox.addWidget(self.chat_nicklist)
127 vbox.addWidget(prompt_input)
128
129 self.setLayout(vbox)
130
131 def set_title(self, title):
132 """Set buffer title."""
133 self.title.clear()
134 if title is not None:
135 self.title.setText(title)
136
137 def set_prompt(self, prompt):
138 """Set prompt."""
139 if self.hbox_edit.count() > 1:
140 self.hbox_edit.takeAt(0)
141 if prompt is not None:
142 label = QtGui.QLabel(prompt)
143 label.setContentsMargins(0, 0, 5, 0)
144 self.hbox_edit.insertWidget(0, label)
145
146
147 class Buffer(QtCore.QObject):
148 """A WeeChat buffer."""
149
150 bufferInput = qt_compat.Signal(str, str)
151
152 def __init__(self, data={}):
153 QtCore.QObject.__init__(self)
154 self.data = data
155 self.nicklist = {}
156 self.widget = BufferWidget(display_nicklist=self.data.get('nicklist',
157 0))
158 self.update_title()
159 self.update_prompt()
160 self.widget.input.textSent.connect(self.input_text_sent)
161
162 def pointer(self):
163 """Return pointer on buffer."""
164 return self.data.get('__path', [''])[0]
165
166 def update_title(self):
167 """Update title."""
168 try:
169 self.widget.set_title(
170 color.remove(self.data['title'].decode('utf-8')))
171 except:
172 self.widget.set_title(None)
173
174 def update_prompt(self):
175 """Update prompt."""
176 try:
177 self.widget.set_prompt(self.data['local_variables']['nick'])
178 except:
179 self.widget.set_prompt(None)
180
181 def input_text_sent(self, text):
182 """Called when text has to be sent to buffer."""
183 if self.data:
184 self.bufferInput.emit(self.data['full_name'], text)
185
186 def nicklist_add_item(self, parent, group, prefix, name, visible):
187 """Add a group/nick in nicklist."""
188 if group:
189 self.nicklist[name] = {
190 'visible': visible,
191 'nicks': []
192 }
193 else:
194 self.nicklist[parent]['nicks'].append({'prefix': prefix,
195 'name': name,
196 'visible': visible})
197
198 def nicklist_remove_item(self, parent, group, name):
199 """Remove a group/nick from nicklist."""
200 if group:
201 if name in self.nicklist:
202 del self.nicklist[name]
203 else:
204 if parent in self.nicklist:
205 self.nicklist[parent]['nicks'] = [
206 nick for nick in self.nicklist[parent]['nicks']
207 if nick['name'] != name
208 ]
209
210 def nicklist_update_item(self, parent, group, prefix, name, visible):
211 """Update a group/nick in nicklist."""
212 if group:
213 if name in self.nicklist:
214 self.nicklist[name]['visible'] = visible
215 else:
216 if parent in self.nicklist:
217 for nick in self.nicklist[parent]['nicks']:
218 if nick['name'] == name:
219 nick['prefix'] = prefix
220 nick['visible'] = visible
221 break
222
223 def nicklist_refresh(self):
224 """Refresh nicklist."""
225 self.widget.nicklist.clear()
226 for group in sorted(self.nicklist):
227 for nick in sorted(self.nicklist[group]['nicks'],
228 key=lambda n: n['name']):
229 prefix_color = {'': '', ' ': '', '+': 'yellow'}
230 color = prefix_color.get(nick['prefix'], 'green')
231 if color:
232 icon = QtGui.QIcon(
233 resource_filename(__name__,
234 'data/icons/bullet_%s_8x8.png' %
235 color))
236 else:
237 pixmap = QtGui.QPixmap(8, 8)
238 pixmap.fill()
239 icon = QtGui.QIcon(pixmap)
240 item = QtGui.QListWidgetItem(icon, nick['name'])
241 self.widget.nicklist.addItem(item)
242 self.widget.nicklist.setVisible(True)