]> jfr.im git - irc/weechat/qweechat.git/blob - qweechat/buffer.py
Update copyright dates
[irc/weechat/qweechat.git] / qweechat / buffer.py
1 # -*- coding: utf-8 -*-
2 #
3 # buffer.py - management of WeeChat buffers/nicklist
4 #
5 # Copyright (C) 2011-2021 Sébastien Helleu <flashcode@flashtux.org>
6 #
7 # This file is part of QWeeChat, a Qt remote GUI for WeeChat.
8 #
9 # QWeeChat is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # QWeeChat is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with QWeeChat. If not, see <http://www.gnu.org/licenses/>.
21 #
22
23 from pkg_resources import resource_filename
24 import qt_compat
25 from chat import ChatTextEdit
26 from input import InputLineEdit
27 import weechat.color as color
28
29 QtCore = qt_compat.import_module('QtCore')
30 QtGui = qt_compat.import_module('QtGui')
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: # noqa: E722
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: # noqa: E722
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({
195 'prefix': prefix,
196 'name': name,
197 'visible': visible,
198 })
199
200 def nicklist_remove_item(self, parent, group, name):
201 """Remove a group/nick from nicklist."""
202 if group:
203 if name in self.nicklist:
204 del self.nicklist[name]
205 else:
206 if parent in self.nicklist:
207 self.nicklist[parent]['nicks'] = [
208 nick for nick in self.nicklist[parent]['nicks']
209 if nick['name'] != name
210 ]
211
212 def nicklist_update_item(self, parent, group, prefix, name, visible):
213 """Update a group/nick in nicklist."""
214 if group:
215 if name in self.nicklist:
216 self.nicklist[name]['visible'] = visible
217 else:
218 if parent in self.nicklist:
219 for nick in self.nicklist[parent]['nicks']:
220 if nick['name'] == name:
221 nick['prefix'] = prefix
222 nick['visible'] = visible
223 break
224
225 def nicklist_refresh(self):
226 """Refresh nicklist."""
227 self.widget.nicklist.clear()
228 for group in sorted(self.nicklist):
229 for nick in sorted(self.nicklist[group]['nicks'],
230 key=lambda n: n['name']):
231 prefix_color = {
232 '': '',
233 ' ': '',
234 '+': 'yellow',
235 }
236 color = prefix_color.get(nick['prefix'], 'green')
237 if color:
238 icon = QtGui.QIcon(
239 resource_filename(__name__,
240 'data/icons/bullet_%s_8x8.png' %
241 color))
242 else:
243 pixmap = QtGui.QPixmap(8, 8)
244 pixmap.fill()
245 icon = QtGui.QIcon(pixmap)
246 item = QtGui.QListWidgetItem(icon, nick['name'])
247 self.widget.nicklist.addItem(item)
248 self.widget.nicklist.setVisible(True)