From d558eb9f29faf12ffc0322b23081bf55e1d51271 Mon Sep 17 00:00:00 2001 From: Ricky Date: Sun, 13 Nov 2016 19:54:42 -0800 Subject: [PATCH 1/8] Added basic preferences dialog. (Entire config.) --- qweechat/preferences.py | 126 ++++++++++++++++++++++++++++++++++++++++ qweechat/qweechat.py | 7 +-- 2 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 qweechat/preferences.py diff --git a/qweechat/preferences.py b/qweechat/preferences.py new file mode 100644 index 0000000..68d30e3 --- /dev/null +++ b/qweechat/preferences.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# +# preferences.py - preferences dialog box +# +# This file is part of QWeeChat, a Qt remote GUI for WeeChat. +# +# QWeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# QWeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with QWeeChat. If not, see . +# + +import qt_compat +import config +from buffer import GenericListWidget + +QtCore = qt_compat.import_module('QtCore') +QtGui = qt_compat.import_module('QtGui') + + +class PreferencesDialog(QtGui.QDialog): + """Preferences dialog.""" + + def __init__(self, name, config, *args): + QtGui.QDialog.__init__(*(self,) + args) + self.setModal(True) + self.setWindowTitle(name) + self.config = config + self.stacked_panes = QtGui.QStackedWidget() + self.list_panes = PreferencesListWidget() + splitter = QtGui.QSplitter() + splitter.addWidget(self.list_panes) + splitter.addWidget(self.stacked_panes) + + for section_name in config.sections(): + item = QtGui.QListWidgetItem(section_name) + pane = PreferencesPaneWidget(section_name) + self.list_panes.addItem(item) + self.stacked_panes.addWidget(pane) + for name, value in config.items(section_name): + pane.addItem(name, value) + self.list_panes.currentRowChanged.connect(self._pane_switch) + + hbox = QtGui.QHBoxLayout() + self.dialog_buttons = QtGui.QDialogButtonBox() + self.dialog_buttons.setStandardButtons( + QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) + self.dialog_buttons.rejected.connect(self.close) + self.dialog_buttons.accepted.connect(self._save_and_close) + + hbox.addStretch(1) + hbox.addWidget(self.dialog_buttons) + hbox.addStretch(1) + + vbox = QtGui.QVBoxLayout() + vbox.addWidget(splitter) + vbox.addLayout(hbox) + + self.setLayout(vbox) + self.show() + + def _pane_switch(self, index): + """Switch the visible preference pane.""" + if index >= 0: + self.stacked_panes.setCurrentIndex(index) + + def _save_and_close(self): + for widget in (self.stacked_panes.widget(i) + for i in range(self.stacked_panes.count())): + for key, field in widget.fields.iteritems(): + self.config.set(widget.section_name, key, str(field.text())) + config.write(self.config) + self.close() + + +class PreferencesListWidget(GenericListWidget): + """Widget with list of preferences.""" + + def __init__(self, *args): + GenericListWidget.__init__(*(self,) + args) + + def switch_prev_buffer(self): + if self.currentRow() > 0: + self.setCurrentRow(self.currentRow() - 1) + else: + self.setCurrentRow(self.count() - 1) + + def switch_next_buffer(self): + if self.currentRow() < self.count() - 1: + self.setCurrentRow(self.currentRow() + 1) + else: + self.setCurrentRow(0) + + +class PreferencesPaneWidget(QtGui.QWidget): + """ + Widget with (from top to bottom): + title, chat + nicklist (optional) + prompt/input. + """ + + def __init__(self, section_name): + QtGui.QWidget.__init__(self) + self.grid = QtGui.QGridLayout() + self.section_name = section_name + self.fields = {} + self.setLayout(self.grid) + + def addItem(self, key, value): + """Add a key-value pair.""" + line = len(self.fields) + self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, 0) + line_edit = QtGui.QLineEdit() + line_edit.setFixedWidth(200) + line_edit.insert(value) + if key == 'password': + line_edit.setEchoMode(QtGui.QLineEdit.Password) + self.grid.addWidget(line_edit, line, 1) + self.fields[key] = line_edit diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index cf0bca3..e430d35 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -44,6 +44,7 @@ from connection import ConnectionDialog from buffer import BufferListWidget, Buffer from debug import DebugDialog from about import AboutDialog +from preferences import PreferencesDialog from version import qweechat_version QtCore = qt_compat.import_module('QtCore') @@ -198,10 +199,8 @@ class MainWindow(QtGui.QMainWindow): def open_preferences_dialog(self): """Open a dialog with preferences.""" - # TODO: implement the preferences dialog box - messages = ['Not yet implemented!', - ''] - self.preferences_dialog = AboutDialog('Preferences', messages, self) + self.preferences_dialog = PreferencesDialog('Preferences', self.config, + self) def save_connection(self): """Save connection configuration.""" From 75f017b60db474303104113f1977c7cf8bd5739e Mon Sep 17 00:00:00 2001 From: Ricky Date: Mon, 14 Nov 2016 00:29:18 -0800 Subject: [PATCH 2/8] Improved preferences, added options to change qt style and save toolbar state. --- qweechat/config.py | 2 ++ qweechat/preferences.py | 59 ++++++++++++++++++++++++++--------------- qweechat/qweechat.py | 17 ++++++++++-- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/qweechat/config.py b/qweechat/config.py index 71760e6..b695afe 100644 --- a/qweechat/config.py +++ b/qweechat/config.py @@ -36,6 +36,8 @@ CONFIG_DEFAULT_OPTIONS = (('relay.server', ''), ('relay.autoconnect', 'off'), ('relay.lines', str(CONFIG_DEFAULT_RELAY_LINES)), ('look.debug', 'off'), + ('look.style', ''), + ('look.toolbar', 'on'), ('look.statusbar', 'off')) # Default colors for WeeChat color options (option name, #rgb value) diff --git a/qweechat/preferences.py b/qweechat/preferences.py index 68d30e3..6acc1c6 100644 --- a/qweechat/preferences.py +++ b/qweechat/preferences.py @@ -20,7 +20,6 @@ import qt_compat import config -from buffer import GenericListWidget QtCore = qt_compat.import_module('QtCore') QtGui = qt_compat.import_module('QtGui') @@ -29,30 +28,33 @@ QtGui = qt_compat.import_module('QtGui') class PreferencesDialog(QtGui.QDialog): """Preferences dialog.""" - def __init__(self, name, config, *args): + def __init__(self, name, parent, *args): QtGui.QDialog.__init__(*(self,) + args) self.setModal(True) self.setWindowTitle(name) - self.config = config + self.parent = parent + self.config = parent.config self.stacked_panes = QtGui.QStackedWidget() - self.list_panes = PreferencesListWidget() + self.list_panes = PreferencesTreeWidget("Settings") + splitter = QtGui.QSplitter() splitter.addWidget(self.list_panes) splitter.addWidget(self.stacked_panes) - for section_name in config.sections(): - item = QtGui.QListWidgetItem(section_name) + for section_name in self.config.sections(): + item = QtGui.QTreeWidgetItem(section_name) + item.setText(0, section_name) pane = PreferencesPaneWidget(section_name) - self.list_panes.addItem(item) + self.list_panes.addTopLevelItem(item) self.stacked_panes.addWidget(pane) - for name, value in config.items(section_name): + for name, value in self.config.items(section_name): pane.addItem(name, value) - self.list_panes.currentRowChanged.connect(self._pane_switch) + self.list_panes.currentItemChanged.connect(self._pane_switch) hbox = QtGui.QHBoxLayout() self.dialog_buttons = QtGui.QDialogButtonBox() self.dialog_buttons.setStandardButtons( - QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) + QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) self.dialog_buttons.rejected.connect(self.close) self.dialog_buttons.accepted.connect(self._save_and_close) @@ -67,8 +69,9 @@ class PreferencesDialog(QtGui.QDialog): self.setLayout(vbox) self.show() - def _pane_switch(self, index): + def _pane_switch(self, item): """Switch the visible preference pane.""" + index = self.list_panes.indexOfTopLevelItem(item) if index >= 0: self.stacked_panes.setCurrentIndex(index) @@ -76,16 +79,23 @@ class PreferencesDialog(QtGui.QDialog): for widget in (self.stacked_panes.widget(i) for i in range(self.stacked_panes.count())): for key, field in widget.fields.iteritems(): - self.config.set(widget.section_name, key, str(field.text())) + if isinstance(field, QtGui.QComboBox): + text = field.itemText(field.currentIndex()) + else: + text = field.text() + self.config.set(widget.section_name, key, str(text)) config.write(self.config) + self.parent.apply_preferences() self.close() -class PreferencesListWidget(GenericListWidget): - """Widget with list of preferences.""" +class PreferencesTreeWidget(QtGui.QTreeWidget): + """Widget with tree list of preferences.""" - def __init__(self, *args): - GenericListWidget.__init__(*(self,) + args) + def __init__(self, header_label, *args): + QtGui.QTreeWidget.__init__(*(self,) + args) + self.setHeaderLabel(header_label) + self.setRootIsDecorated(False) def switch_prev_buffer(self): if self.currentRow() > 0: @@ -117,10 +127,15 @@ class PreferencesPaneWidget(QtGui.QWidget): """Add a key-value pair.""" line = len(self.fields) self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, 0) - line_edit = QtGui.QLineEdit() - line_edit.setFixedWidth(200) - line_edit.insert(value) + edit = QtGui.QLineEdit() + edit.setFixedWidth(200) + edit.insert(value) if key == 'password': - line_edit.setEchoMode(QtGui.QLineEdit.Password) - self.grid.addWidget(line_edit, line, 1) - self.fields[key] = line_edit + edit.setEchoMode(QtGui.QLineEdit.Password) + if key == 'style': + edit = QtGui.QComboBox() + edit.addItems(QtGui.QStyleFactory.keys()) + edit.setCurrentIndex(edit.findText(QtGui.qApp.style().objectName(), + QtCore.Qt.MatchFixedString)) + self.grid.addWidget(edit, line, 1) + self.fields[key] = edit diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index e430d35..e4f0417 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -160,12 +160,14 @@ class MainWindow(QtGui.QMainWindow): # toolbar toolbar = self.addToolBar('toolBar') toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) + toolbar.setMovable(False); toolbar.addActions([self.actions['connect'], self.actions['disconnect'], self.actions['debug'], self.actions['preferences'], self.actions['about'], self.actions['quit']]) + self.toolbar = toolbar self.buffers[0].widget.input.setFocus() @@ -181,9 +183,21 @@ class MainWindow(QtGui.QMainWindow): 'ssl'), self.config.get('relay', 'password'), self.config.get('relay', 'lines')) + self.apply_preferences() self.show() + def apply_preferences(self): + """Apply non-server options from preferences.""" + app = QtCore.QCoreApplication.instance() + if self.config.getboolean('look', 'toolbar'): + self.toolbar.show() + else: + self.toolbar.hide() + if self.config.get('look', 'style'): + app.setStyle(QtGui.QStyleFactory.create( + self.config.get('look', 'style'))) + def _buffer_switch(self, index): """Switch to a buffer.""" if index >= 0: @@ -199,8 +213,7 @@ class MainWindow(QtGui.QMainWindow): def open_preferences_dialog(self): """Open a dialog with preferences.""" - self.preferences_dialog = PreferencesDialog('Preferences', self.config, - self) + self.preferences_dialog = PreferencesDialog('Preferences', self) def save_connection(self): """Save connection configuration.""" From cbc372c0335d1587ed371d2611d655dbc3bd9460 Mon Sep 17 00:00:00 2001 From: Ricky Date: Mon, 14 Nov 2016 01:29:15 -0800 Subject: [PATCH 3/8] Added option to move buffer list to the left --- qweechat/config.py | 1 + qweechat/preferences.py | 11 +++++++++-- qweechat/qweechat.py | 22 ++++++++++++++-------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/qweechat/config.py b/qweechat/config.py index b695afe..3a33042 100644 --- a/qweechat/config.py +++ b/qweechat/config.py @@ -37,6 +37,7 @@ CONFIG_DEFAULT_OPTIONS = (('relay.server', ''), ('relay.lines', str(CONFIG_DEFAULT_RELAY_LINES)), ('look.debug', 'off'), ('look.style', ''), + ('look.buffer_list', 'left'), ('look.toolbar', 'on'), ('look.statusbar', 'off')) diff --git a/qweechat/preferences.py b/qweechat/preferences.py index 6acc1c6..ab4f153 100644 --- a/qweechat/preferences.py +++ b/qweechat/preferences.py @@ -119,14 +119,21 @@ class PreferencesPaneWidget(QtGui.QWidget): def __init__(self, section_name): QtGui.QWidget.__init__(self) self.grid = QtGui.QGridLayout() + self.grid.setAlignment(QtCore.Qt.AlignTop) self.section_name = section_name self.fields = {} self.setLayout(self.grid) + self.grid.setColumnStretch(2, 1) + self.grid.setSpacing(10) def addItem(self, key, value): """Add a key-value pair.""" line = len(self.fields) - self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, 0) + start = 0 + if self.section_name == "color": + start = 2 * (line % 2) + line = line // 2 + self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, start + 0) edit = QtGui.QLineEdit() edit.setFixedWidth(200) edit.insert(value) @@ -137,5 +144,5 @@ class PreferencesPaneWidget(QtGui.QWidget): edit.addItems(QtGui.QStyleFactory.keys()) edit.setCurrentIndex(edit.findText(QtGui.qApp.style().objectName(), QtCore.Qt.MatchFixedString)) - self.grid.addWidget(edit, line, 1) + self.grid.addWidget(edit, line, start + 1) self.fields[key] = edit diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index e4f0417..080cf93 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -92,14 +92,11 @@ class MainWindow(QtGui.QMainWindow): self.stacked_buffers.addWidget(self.buffers[0].widget) # splitter with buffers + chat/input - splitter = QtGui.QSplitter() - splitter.addWidget(self.list_buffers) - splitter.addWidget(self.stacked_buffers) + self.splitter = QtGui.QSplitter() + self.splitter.addWidget(self.list_buffers) + self.splitter.addWidget(self.stacked_buffers) - self.setCentralWidget(splitter) - - if self.config.getboolean('look', 'statusbar'): - self.statusBar().visible = True + self.setCentralWidget(self.splitter) # actions for menu and toolbar actions_def = { @@ -160,7 +157,7 @@ class MainWindow(QtGui.QMainWindow): # toolbar toolbar = self.addToolBar('toolBar') toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) - toolbar.setMovable(False); + toolbar.setMovable(False) toolbar.addActions([self.actions['connect'], self.actions['disconnect'], self.actions['debug'], @@ -197,6 +194,15 @@ class MainWindow(QtGui.QMainWindow): if self.config.get('look', 'style'): app.setStyle(QtGui.QStyleFactory.create( self.config.get('look', 'style'))) + if self.config.getboolean('look', 'statusbar'): + self.statusBar().show() + else: + self.statusBar().hide() + # Move the buffer list / main buffer view: + if self.config.get('look', 'buffer_list') == 'right': + self.splitter.insertWidget(1, self.list_buffers) + else: + self.splitter.insertWidget(1, self.stacked_buffers) def _buffer_switch(self, index): """Switch to a buffer.""" From 473336e643418094f2526ae0b59ffb4391bd1a1b Mon Sep 17 00:00:00 2001 From: Ricky Date: Mon, 14 Nov 2016 02:08:06 -0800 Subject: [PATCH 4/8] Added option to change nicklist visibility --- qweechat/buffer.py | 15 +++++++++++++-- qweechat/config.py | 1 + qweechat/qweechat.py | 5 ++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index eefb5e1..4a193ee 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -149,9 +149,10 @@ class Buffer(QtCore.QObject): bufferInput = qt_compat.Signal(str, str) - def __init__(self, data={}): + def __init__(self, data={}, config=False): QtCore.QObject.__init__(self) self.data = data + self.config = config self.nicklist = {} self.widget = BufferWidget(display_nicklist=self.data.get('nicklist', 0)) @@ -222,6 +223,12 @@ class Buffer(QtCore.QObject): nick['visible'] = visible break + def nicklist_update_config(self): + """Match nicklist to configuration, quicker than a refresh""" + if (self.config): + setting = self.config.get("look", "nick_list") != "off" + self.widget.nicklist.setVisible(setting) + def nicklist_refresh(self): """Refresh nicklist.""" self.widget.nicklist.clear() @@ -245,4 +252,8 @@ class Buffer(QtCore.QObject): icon = QtGui.QIcon(pixmap) item = QtGui.QListWidgetItem(icon, nick['name']) self.widget.nicklist.addItem(item) - self.widget.nicklist.setVisible(True) + if self.config and self.config.get("look", + "nick_list") == "off": + self.widget.nicklist.setVisible(False) + else: + self.widget.nicklist.setVisible(True) diff --git a/qweechat/config.py b/qweechat/config.py index 3a33042..642bfdf 100644 --- a/qweechat/config.py +++ b/qweechat/config.py @@ -38,6 +38,7 @@ CONFIG_DEFAULT_OPTIONS = (('relay.server', ''), ('look.debug', 'off'), ('look.style', ''), ('look.buffer_list', 'left'), + ('look.nick_list', 'on'), ('look.toolbar', 'on'), ('look.statusbar', 'off')) diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 080cf93..1391ed6 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -203,6 +203,9 @@ class MainWindow(QtGui.QMainWindow): self.splitter.insertWidget(1, self.list_buffers) else: self.splitter.insertWidget(1, self.stacked_buffers) + # Update visibility of all nicklists: + for buffer in self.buffers: + buffer.nicklist_update_config() def _buffer_switch(self, index): """Switch to a buffer.""" @@ -516,7 +519,7 @@ class MainWindow(QtGui.QMainWindow): def create_buffer(self, item): """Create a new buffer.""" - buf = Buffer(item) + buf = Buffer(item, self.config) buf.bufferInput.connect(self.buffer_input) buf.widget.input.bufferSwitchPrev.connect( self.list_buffers.switch_prev_buffer) From 68cdba2d2824d0636695cb7441ee3c05d9945e12 Mon Sep 17 00:00:00 2001 From: Ricky Date: Mon, 14 Nov 2016 03:38:28 -0800 Subject: [PATCH 5/8] Added "view" menu, toggle for menubar and topic and fullscreen --- qweechat/buffer.py | 16 +++---- qweechat/config.py | 4 +- qweechat/preferences.py | 2 +- qweechat/qt_compat.py | 5 ++- qweechat/qweechat.py | 93 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/qweechat/buffer.py b/qweechat/buffer.py index 4a193ee..4554cf6 100644 --- a/qweechat/buffer.py +++ b/qweechat/buffer.py @@ -184,6 +184,14 @@ class Buffer(QtCore.QObject): if self.data: self.bufferInput.emit(self.data['full_name'], text) + def update_config(self): + """Match visibility to configuration, faster than a nicklist refresh""" + if (self.config): + nicklist_visible = self.config.get("look", "nicklist") != "off" + topic_visible = self.config.get("look", "topic") != "off" + self.widget.nicklist.setVisible(nicklist_visible) + self.widget.title.setVisible(topic_visible) + def nicklist_add_item(self, parent, group, prefix, name, visible): """Add a group/nick in nicklist.""" if group: @@ -223,12 +231,6 @@ class Buffer(QtCore.QObject): nick['visible'] = visible break - def nicklist_update_config(self): - """Match nicklist to configuration, quicker than a refresh""" - if (self.config): - setting = self.config.get("look", "nick_list") != "off" - self.widget.nicklist.setVisible(setting) - def nicklist_refresh(self): """Refresh nicklist.""" self.widget.nicklist.clear() @@ -253,7 +255,7 @@ class Buffer(QtCore.QObject): item = QtGui.QListWidgetItem(icon, nick['name']) self.widget.nicklist.addItem(item) if self.config and self.config.get("look", - "nick_list") == "off": + "nicklist") == "off": self.widget.nicklist.setVisible(False) else: self.widget.nicklist.setVisible(True) diff --git a/qweechat/config.py b/qweechat/config.py index 642bfdf..19f94e4 100644 --- a/qweechat/config.py +++ b/qweechat/config.py @@ -38,8 +38,10 @@ CONFIG_DEFAULT_OPTIONS = (('relay.server', ''), ('look.debug', 'off'), ('look.style', ''), ('look.buffer_list', 'left'), - ('look.nick_list', 'on'), + ('look.nicklist', 'on'), ('look.toolbar', 'on'), + ('look.menubar', 'on'), + ('look.topic', 'on'), ('look.statusbar', 'off')) # Default colors for WeeChat color options (option name, #rgb value) diff --git a/qweechat/preferences.py b/qweechat/preferences.py index ab4f153..ab5a0b9 100644 --- a/qweechat/preferences.py +++ b/qweechat/preferences.py @@ -78,7 +78,7 @@ class PreferencesDialog(QtGui.QDialog): def _save_and_close(self): for widget in (self.stacked_panes.widget(i) for i in range(self.stacked_panes.count())): - for key, field in widget.fields.iteritems(): + for key, field in widget.fields.items(): if isinstance(field, QtGui.QComboBox): text = field.itemText(field.currentIndex()) else: diff --git a/qweechat/qt_compat.py b/qweechat/qt_compat.py index 8940288..aa3a2e5 100644 --- a/qweechat/qt_compat.py +++ b/qweechat/qt_compat.py @@ -29,7 +29,10 @@ except ImportError: def _pyside_import_module(moduleName): pyside = __import__('PySide', globals(), locals(), [moduleName], -1) - return getattr(pyside, moduleName) + mod = getattr(pyside, moduleName) + if moduleName == "QtGui": + mod.QWIDGETSIZE_MAX = ((1 << 24) - 1) + return mod def _pyqt4_import_module(moduleName): diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 1391ed6..15c4ab5 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -122,6 +122,27 @@ class MainWindow(QtGui.QMainWindow): 'application-exit.png', 'Quit application', 'Ctrl+Q', self.close], } + # toggleable actions + self.toggles_def = { + 'show menubar': [ + 'look.menubar', 'Show Menubar', + 'Ctrl+M', self.toggle_menubar], + 'show toolbar': [ + 'look.toolbar', 'Show Toolbar', + False, self.toggle_toolbar], + 'show status bar': [ + 'look.statusbar', 'Show Status Bar', + False, self.toggle_statusbar], + 'show topic': [ + 'look.topic', 'Show Topic', + False, self.toggle_topic], + 'show nick list': [ + 'look.nicklist', 'Show Nick List', + 'Ctrl+F7', self.toggle_nicklist], + 'fullscreen': [ + False, 'Fullscreen', + 'F11', self.toggle_fullscreen], + } self.actions = {} for name, action in list(actions_def.items()): self.actions[name] = QtGui.QAction( @@ -131,6 +152,13 @@ class MainWindow(QtGui.QMainWindow): self.actions[name].setStatusTip(action[1]) self.actions[name].setShortcut(action[2]) self.actions[name].triggered.connect(action[3]) + for name, action in list(self.toggles_def.items()): + self.actions[name] = QtGui.QAction(name.capitalize(), self) + self.actions[name].setStatusTip(action[1]) + self.actions[name].setCheckable(True) + if action[2]: + self.actions[name].setShortcut(action[2]) + self.actions[name].triggered.connect(action[3]) # menu self.menu = self.menuBar() @@ -140,6 +168,15 @@ class MainWindow(QtGui.QMainWindow): self.actions['preferences'], self.actions['save connection'], self.actions['quit']]) + menu_view = self.menu.addMenu('&View') + menu_view.addActions([self.actions['show menubar'], + self.actions['show toolbar'], + self.actions['show status bar'], + self._actions_separator(), + self.actions['show topic'], + self.actions['show nick list'], + self._actions_separator(), + self.actions['fullscreen']]) menu_window = self.menu.addMenu('&Window') menu_window.addAction(self.actions['debug']) menu_help = self.menu.addMenu('&Help') @@ -184,6 +221,12 @@ class MainWindow(QtGui.QMainWindow): self.show() + def _actions_separator(self): + """Create a new QAction separator.""" + sep = QtGui.QAction("", self) + sep.setSeparator(True) + return sep + def apply_preferences(self): """Apply non-server options from preferences.""" app = QtCore.QCoreApplication.instance() @@ -191,9 +234,16 @@ class MainWindow(QtGui.QMainWindow): self.toolbar.show() else: self.toolbar.hide() + # Change the height to avoid losing all hotkeys: + if self.config.getboolean('look', 'menubar'): + self.menu.setMaximumHeight(QtGui.QWIDGETSIZE_MAX) + else: + self.menu.setFixedHeight(1) + # Apply the selected qt style here so it will update without a restart if self.config.get('look', 'style'): app.setStyle(QtGui.QStyleFactory.create( self.config.get('look', 'style'))) + # Statusbar: if self.config.getboolean('look', 'statusbar'): self.statusBar().show() else: @@ -203,9 +253,15 @@ class MainWindow(QtGui.QMainWindow): self.splitter.insertWidget(1, self.list_buffers) else: self.splitter.insertWidget(1, self.stacked_buffers) - # Update visibility of all nicklists: + # Update visibility of all nicklists/topics: for buffer in self.buffers: - buffer.nicklist_update_config() + buffer.update_config() + # Update toggle state for menubar: + for name, action in list(self.toggles_def.items()): + if action[0]: + ac = action[0].split(".") + toggle = self.config.get(ac[0], ac[1]) + self.actions[name].setChecked(toggle == "on") def _buffer_switch(self, index): """Switch to a buffer.""" @@ -287,6 +343,39 @@ class MainWindow(QtGui.QMainWindow): self.connection_dialog.dialog_buttons.accepted.connect( self.connect_weechat) + def toggle_setting(self, section, option): + """Toggles any boolean setting.""" + val = self.config.getboolean(section, option) + self.config.set(section, option, "off" if val else "on") + self.apply_preferences() + + def toggle_menubar(self): + """Toggle menubar.""" + self.toggle_setting('look', 'menubar') + + def toggle_toolbar(self): + """Toggle toolbar.""" + self.toggle_setting('look', 'toolbar') + + def toggle_statusbar(self): + """Toggle statusbar.""" + self.toggle_setting('look', 'statusbar') + + def toggle_topic(self): + """Toggle topic.""" + self.toggle_setting('look', 'topic') + + def toggle_nicklist(self): + """Toggle nicklist.""" + self.toggle_setting('look', 'nicklist') + + def toggle_fullscreen(self): + """Toggle fullscreen.""" + if self.isFullScreen(): + self.showNormal() + else: + self.showFullScreen() + def connect_weechat(self): """Connect to WeeChat.""" self.network.connect_weechat( From 0bfb73d20c1e56e156dcc7cf6964fdaee9099791 Mon Sep 17 00:00:00 2001 From: Ricky Brent Date: Mon, 14 Nov 2016 13:11:11 -0800 Subject: [PATCH 6/8] Added swatches for color picker and color picker, better boolean/combobox preferences --- qweechat/preferences.py | 66 ++++++++++++++++++++++++++++++++++++----- qweechat/qweechat.py | 14 +++++++++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/qweechat/preferences.py b/qweechat/preferences.py index ab5a0b9..d9aebe2 100644 --- a/qweechat/preferences.py +++ b/qweechat/preferences.py @@ -2,6 +2,8 @@ # # preferences.py - preferences dialog box # +# Copyright (C) 2016 Ricky Brent +# # This file is part of QWeeChat, a Qt remote GUI for WeeChat. # # QWeeChat is free software; you can redistribute it and/or modify @@ -81,6 +83,8 @@ class PreferencesDialog(QtGui.QDialog): for key, field in widget.fields.items(): if isinstance(field, QtGui.QComboBox): text = field.itemText(field.currentIndex()) + elif isinstance(field, QtGui.QCheckBox): + text = "on" if field.isChecked() else "off" else: text = field.text() self.config.set(widget.section_name, key, str(text)) @@ -110,6 +114,40 @@ class PreferencesTreeWidget(QtGui.QTreeWidget): self.setCurrentRow(0) +class PreferencesColorEdit(QtGui.QPushButton): + """Simple color square that changes based on the color selected.""" + def __init__(self, *args): + QtGui.QPushButton.__init__(*(self,) + args) + self.color = "#000000" + self.clicked.connect(self._color_picker) + # Some of the configured colors use a astrisk prefix. + # Toggle this on right click. + self.star = False + self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.customContextMenuRequested.connect(self._color_star) + + def insert(self, color): + """Insert the desired color for the widget.""" + if color[:1] == "*": + self.star = True + color = color[1:] + self.setText("*" if self.star else "") + self.color = color + self.setStyleSheet("background-color: " + color) + + def text(self): + """Returns the hex value of the color.""" + return ("*" if self.star else "") + self.color + + def _color_picker(self): + color = QtGui.QColorDialog.getColor() + self.insert(color.name()) + + def _color_star(self): + self.star = not self.star + self.insert(self.text()) + + class PreferencesPaneWidget(QtGui.QWidget): """ Widget with (from top to bottom): @@ -125,6 +163,10 @@ class PreferencesPaneWidget(QtGui.QWidget): self.setLayout(self.grid) self.grid.setColumnStretch(2, 1) self.grid.setSpacing(10) + self.checkboxes = ("ssl", "autoconnect", "statusbar", "topic", + "menubar", "toolbar", "nicklist", "debug") + self.comboboxes = {"style": QtGui.QStyleFactory.keys(), + "buffer_list": ["left", "right"]} def addItem(self, key, value): """Add a key-value pair.""" @@ -134,15 +176,23 @@ class PreferencesPaneWidget(QtGui.QWidget): start = 2 * (line % 2) line = line // 2 self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, start + 0) - edit = QtGui.QLineEdit() - edit.setFixedWidth(200) - edit.insert(value) + if self.section_name == "color": + edit = PreferencesColorEdit() + edit.setFixedWidth(edit.sizeHint().height()) + edit.insert(value) + elif key in self.comboboxes.keys(): + edit = QtGui.QComboBox() + edit.addItems(self.comboboxes[key]) + edit.setCurrentIndex(edit.findText(value)) + edit.setFixedWidth(200) + elif key in self.checkboxes: + edit = QtGui.QCheckBox() + edit.setChecked(value == "on") + else: + edit = QtGui.QLineEdit() + edit.setFixedWidth(200) + edit.insert(value) if key == 'password': edit.setEchoMode(QtGui.QLineEdit.Password) - if key == 'style': - edit = QtGui.QComboBox() - edit.addItems(QtGui.QStyleFactory.keys()) - edit.setCurrentIndex(edit.findText(QtGui.qApp.style().objectName(), - QtCore.Qt.MatchFixedString)) self.grid.addWidget(edit, line, start + 1) self.fields[key] = edit diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 15c4ab5..6fddda5 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -203,6 +203,12 @@ class MainWindow(QtGui.QMainWindow): self.actions['quit']]) self.toolbar = toolbar + # Override context menu for both -- default is a simple menubar toggle. + self.menu.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.toolbar.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.menu.customContextMenuRequested.connect(self._menu_context) + self.toolbar.customContextMenuRequested.connect(self._menu_context) + self.buffers[0].widget.input.setFocus() # open debug dialog @@ -263,6 +269,14 @@ class MainWindow(QtGui.QMainWindow): toggle = self.config.get(ac[0], ac[1]) self.actions[name].setChecked(toggle == "on") + def _menu_context(self, event): + """Show a slightly nicer context menu for the menu/toolbar.""" + menu = QtGui.QMenu() + menu.addActions([self.actions['show menubar'], + self.actions['show toolbar'], + self.actions['show status bar']]) + action = menu.exec_(self.mapToGlobal(event)) + def _buffer_switch(self, index): """Switch to a buffer.""" if index >= 0: From b23d7a877292bd4688e6b0160091b398e4a84c3a Mon Sep 17 00:00:00 2001 From: Ricky Date: Tue, 15 Nov 2016 01:53:34 -0800 Subject: [PATCH 7/8] Reordered settings and formatting fixes. --- qweechat/preferences.py | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/qweechat/preferences.py b/qweechat/preferences.py index d9aebe2..043e19d 100644 --- a/qweechat/preferences.py +++ b/qweechat/preferences.py @@ -43,15 +43,23 @@ class PreferencesDialog(QtGui.QDialog): splitter.addWidget(self.list_panes) splitter.addWidget(self.stacked_panes) - for section_name in self.config.sections(): - item = QtGui.QTreeWidgetItem(section_name) - item.setText(0, section_name) - pane = PreferencesPaneWidget(section_name) + # Follow same order as defaults: + section_panes = {} + for section in self.config.sections(): + item = QtGui.QTreeWidgetItem(section) + item.setText(0, section) + section_panes[section] = PreferencesPaneWidget(section) self.list_panes.addTopLevelItem(item) - self.stacked_panes.addWidget(pane) - for name, value in self.config.items(section_name): - pane.addItem(name, value) + self.stacked_panes.addWidget(section_panes[section]) + + for setting, default in config.CONFIG_DEFAULT_OPTIONS: + section, key = setting.split(".") + section_panes[section].addItem(key, self.config.get(section, key)) + for key, value in self.config.items("color"): + section_panes["color"].addItem(key, value) + self.list_panes.currentItemChanged.connect(self._pane_switch) + self.list_panes.setCurrentItem(self.list_panes.topLevelItem(0)) hbox = QtGui.QHBoxLayout() self.dialog_buttons = QtGui.QDialogButtonBox() @@ -100,18 +108,10 @@ class PreferencesTreeWidget(QtGui.QTreeWidget): QtGui.QTreeWidget.__init__(*(self,) + args) self.setHeaderLabel(header_label) self.setRootIsDecorated(False) - - def switch_prev_buffer(self): - if self.currentRow() > 0: - self.setCurrentRow(self.currentRow() - 1) - else: - self.setCurrentRow(self.count() - 1) - - def switch_next_buffer(self): - if self.currentRow() < self.count() - 1: - self.setCurrentRow(self.currentRow() + 1) - else: - self.setCurrentRow(0) + self.setMaximumWidth(90) + self.setTextElideMode(QtCore.Qt.ElideNone) + self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.setFocusPolicy(QtCore.Qt.NoFocus) class PreferencesColorEdit(QtGui.QPushButton): @@ -120,7 +120,7 @@ class PreferencesColorEdit(QtGui.QPushButton): QtGui.QPushButton.__init__(*(self,) + args) self.color = "#000000" self.clicked.connect(self._color_picker) - # Some of the configured colors use a astrisk prefix. + # Some of the configured colors use a astrisk prefix. # Toggle this on right click. self.star = False self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) @@ -138,7 +138,7 @@ class PreferencesColorEdit(QtGui.QPushButton): def text(self): """Returns the hex value of the color.""" return ("*" if self.star else "") + self.color - + def _color_picker(self): color = QtGui.QColorDialog.getColor() self.insert(color.name()) @@ -164,18 +164,19 @@ class PreferencesPaneWidget(QtGui.QWidget): self.grid.setColumnStretch(2, 1) self.grid.setSpacing(10) self.checkboxes = ("ssl", "autoconnect", "statusbar", "topic", - "menubar", "toolbar", "nicklist", "debug") - self.comboboxes = {"style": QtGui.QStyleFactory.keys(), + "menubar", "toolbar", "nicklist", "debug") + self.comboboxes = {"style": QtGui.QStyleFactory.keys(), "buffer_list": ["left", "right"]} def addItem(self, key, value): """Add a key-value pair.""" line = len(self.fields) + name = key.capitalize().replace("_", " ") start = 0 if self.section_name == "color": start = 2 * (line % 2) line = line // 2 - self.grid.addWidget(QtGui.QLabel(key.capitalize()), line, start + 0) + self.grid.addWidget(QtGui.QLabel(name), line, start + 0) if self.section_name == "color": edit = PreferencesColorEdit() edit.setFixedWidth(edit.sizeHint().height()) From 78409b8a5efdd6f26a51138f71a5c99d5f019d4a Mon Sep 17 00:00:00 2001 From: Ricky Date: Tue, 15 Nov 2016 04:29:48 -0800 Subject: [PATCH 8/8] Format fixes --- qweechat/qweechat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qweechat/qweechat.py b/qweechat/qweechat.py index 6fddda5..dd81e6d 100644 --- a/qweechat/qweechat.py +++ b/qweechat/qweechat.py @@ -208,7 +208,7 @@ class MainWindow(QtGui.QMainWindow): self.toolbar.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.menu.customContextMenuRequested.connect(self._menu_context) self.toolbar.customContextMenuRequested.connect(self._menu_context) - + self.buffers[0].widget.input.setFocus() # open debug dialog @@ -275,7 +275,7 @@ class MainWindow(QtGui.QMainWindow): menu.addActions([self.actions['show menubar'], self.actions['show toolbar'], self.actions['show status bar']]) - action = menu.exec_(self.mapToGlobal(event)) + menu.exec_(self.mapToGlobal(event)) def _buffer_switch(self, index): """Switch to a buffer."""