summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2017-01-31 14:57:22 (GMT)
committerEdwin Mons <edwin.mons@isode.com>2017-02-27 14:07:13 (GMT)
commitfc8f5b31c22ed7af4f0e2473f269601a87a0438c (patch)
tree0c59a9debf72247c7409947a3a4cccb6c616dd06 /Swift/QtUI
parentabd81d4a3cf08ffaa1e5265d204cdd80c8c0583b (diff)
downloadswift-fc8f5b31c22ed7af4f0e2473f269601a87a0438c.zip
swift-fc8f5b31c22ed7af4f0e2473f269601a87a0438c.tar.bz2
Redesign highlight logic and processing
The new highlight logic follows a simpler model. It supports: * highlighting of whole words in a message * highlighting messages by sender name * highlighting if the user’s name is mentioned Possible actions for these highlights are text colouring, sound playback of WAV files, and system notifications. In addition the user can decide to receive sound and system notification on general incoming direct and group messages. Redesigned the highlight configuration UI dialog for this new model. ChatMessageParser class now deals with all parsing and marking up the chat message with the matching HighlightActions. Highlighter class has been extended to deal with all sound and system notification highlights that should be emitted by a specified chat message. Moved some tests over to gtest in the process. Test-Information: Tested UI on macOS 10.12.3 with Qt 5.7.1. Manually tested that correct system notification are emitted on mentions, keyword highlights and general messages. Added new unit tests to cover new highlighting behaviour. Change-Id: I1c89e29d81022174187fb44af0d384036ec51594
Diffstat (limited to 'Swift/QtUI')
-rw-r--r--Swift/QtUI/QtCheckBoxStyledItemDelegate.cpp51
-rw-r--r--Swift/QtUI/QtCheckBoxStyledItemDelegate.h26
-rw-r--r--Swift/QtUI/QtColorSelectionStyledItemDelegate.cpp56
-rw-r--r--Swift/QtUI/QtColorSelectionStyledItemDelegate.h26
-rw-r--r--Swift/QtUI/QtHighlightEditor.cpp568
-rw-r--r--Swift/QtUI/QtHighlightEditor.h76
-rw-r--r--Swift/QtUI/QtHighlightEditor.ui466
-rw-r--r--Swift/QtUI/QtHighlightNotificationConfigDialog.cpp246
-rw-r--r--Swift/QtUI/QtHighlightNotificationConfigDialog.h41
-rw-r--r--Swift/QtUI/QtHighlightNotificationConfigDialog.ui537
-rw-r--r--Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp111
-rw-r--r--Swift/QtUI/QtSoundSelectionStyledItemDelegate.h23
-rw-r--r--Swift/QtUI/QtUIFactory.cpp4
-rw-r--r--Swift/QtUI/QtWebKitChatView.cpp20
-rw-r--r--Swift/QtUI/SConscript9
15 files changed, 1135 insertions, 1125 deletions
diff --git a/Swift/QtUI/QtCheckBoxStyledItemDelegate.cpp b/Swift/QtUI/QtCheckBoxStyledItemDelegate.cpp
new file mode 100644
index 0000000..5f71ed4
--- /dev/null
+++ b/Swift/QtUI/QtCheckBoxStyledItemDelegate.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtCheckBoxStyledItemDelegate.h>
+
+#include <array>
+
+#include <QApplication>
+#include <QEvent>
+#include <QPainter>
+
+namespace Swift {
+
+QtCheckBoxStyledItemDelegate::QtCheckBoxStyledItemDelegate(QObject* parent) : QStyledItemDelegate(parent) {
+
+}
+
+void QtCheckBoxStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+ QStyleOptionButton cbOpt;
+ cbOpt.rect = option.rect;
+ cbOpt.state = QStyle::State_Active;
+
+ auto copyFlags = std::array<QStyle::StateFlag, 2>({{QStyle::State_Enabled/*, QStyle::State_Sunken*/}});
+ for (auto flag : copyFlags) {
+ if (option.state && flag) {
+ cbOpt.state |= flag;
+ }
+ }
+
+ bool isChecked = index.data(DATA_ROLE).toBool();
+ if (isChecked) {
+ cbOpt.state |= QStyle::State_On;
+ }
+ else {
+ cbOpt.state |= QStyle::State_Off;
+ }
+ painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
+ QApplication::style()->drawControl(QStyle::CE_CheckBox, &cbOpt, painter);
+}
+
+bool QtCheckBoxStyledItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& /*option*/, const QModelIndex& index) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ model->setData(index, !index.data(DATA_ROLE).toBool(), DATA_ROLE);
+ }
+ return true;
+}
+
+};
diff --git a/Swift/QtUI/QtCheckBoxStyledItemDelegate.h b/Swift/QtUI/QtCheckBoxStyledItemDelegate.h
new file mode 100644
index 0000000..1d8db62
--- /dev/null
+++ b/Swift/QtUI/QtCheckBoxStyledItemDelegate.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QStyledItemDelegate>
+
+namespace Swift {
+
+class QtCheckBoxStyledItemDelegate : public QStyledItemDelegate {
+ public:
+ QtCheckBoxStyledItemDelegate(QObject* parent = nullptr);
+
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
+
+ public:
+ static const int DATA_ROLE = Qt::UserRole + 1;
+
+ protected:
+ virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
+};
+
+}
diff --git a/Swift/QtUI/QtColorSelectionStyledItemDelegate.cpp b/Swift/QtUI/QtColorSelectionStyledItemDelegate.cpp
new file mode 100644
index 0000000..c3fef5a
--- /dev/null
+++ b/Swift/QtUI/QtColorSelectionStyledItemDelegate.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtColorSelectionStyledItemDelegate.h>
+
+#include <QApplication>
+#include <QColorDialog>
+#include <QEvent>
+#include <QPainter>
+#include <QStyleOptionComboBox>
+
+namespace Swift {
+
+QtColorSelectionStyledItemDelegate::QtColorSelectionStyledItemDelegate(QObject* parent) : QStyledItemDelegate(parent) {
+
+}
+
+void QtColorSelectionStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+ // draw item selected background
+ painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
+
+ // draw combo box
+ QStyleOptionComboBox opt;
+ opt.rect = option.rect;
+ opt.state = QStyle::State_Active | QStyle::State_Enabled;
+ QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &opt, painter);
+
+ // draw currently selected color
+ auto contentRect = QApplication::style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField);
+ auto currentColor = index.data(DATA_ROLE).value<QColor>();
+ painter->save();
+ painter->setClipRect(contentRect);
+ painter->fillRect(contentRect.adjusted(1, -4, -1, -3), currentColor);
+ painter->restore();
+}
+
+bool QtColorSelectionStyledItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& /*option*/, const QModelIndex& index) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ auto currentColor = index.data(DATA_ROLE).value<QColor>();
+ auto newColor = QColorDialog::getColor(currentColor);
+ if (newColor.isValid()) {
+ model->setData(index, newColor, DATA_ROLE);
+ }
+
+ auto correspondingDialog = qobject_cast<QDialog*>(parent());
+ if (correspondingDialog) {
+ correspondingDialog->raise();
+ }
+ }
+ return true;
+}
+
+};
diff --git a/Swift/QtUI/QtColorSelectionStyledItemDelegate.h b/Swift/QtUI/QtColorSelectionStyledItemDelegate.h
new file mode 100644
index 0000000..d6b3336
--- /dev/null
+++ b/Swift/QtUI/QtColorSelectionStyledItemDelegate.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QStyledItemDelegate>
+
+namespace Swift {
+
+class QtColorSelectionStyledItemDelegate : public QStyledItemDelegate {
+ public:
+ QtColorSelectionStyledItemDelegate(QObject* parent = nullptr);
+
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
+
+ public:
+ static const int DATA_ROLE = Qt::UserRole + 1;
+
+ protected:
+ virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
+};
+
+}
diff --git a/Swift/QtUI/QtHighlightEditor.cpp b/Swift/QtUI/QtHighlightEditor.cpp
deleted file mode 100644
index dd95941..0000000
--- a/Swift/QtUI/QtHighlightEditor.cpp
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-/*
- * Copyright (c) 2014-2016 Isode Limited.
- * All rights reserved.
- * See the COPYING file for more information.
- */
-
-#include <Swift/QtUI/QtHighlightEditor.h>
-
-#include <cassert>
-
-#include <boost/lexical_cast.hpp>
-
-#include <QFileDialog>
-#include <QScrollBar>
-#include <QTreeWidgetItem>
-
-#include <Swift/Controllers/HighlightManager.cpp>
-
-#include <Swift/QtUI/QtSettingsProvider.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h>
-
-namespace Swift {
-
-QtHighlightEditor::QtHighlightEditor(QtSettingsProvider* settings, QWidget* parent)
- : QWidget(parent), settings_(settings), previousRow_(-1)
-{
- ui_.setupUi(this);
-
- connect(ui_.listWidget, SIGNAL(currentRowChanged(int)), SLOT(onCurrentRowChanged(int)));
-
- connect(ui_.newButton, SIGNAL(clicked()), SLOT(onNewButtonClicked()));
- connect(ui_.deleteButton, SIGNAL(clicked()), SLOT(onDeleteButtonClicked()));
-
- connect(ui_.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(onApplyButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), SLOT(onCancelButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(onOkButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), SLOT(onResetToDefaultRulesClicked()));
-
- connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(colorOtherSelect()));
- connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(colorCustomSelect()));
-
- connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
- connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
- connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(soundCustomSelect()));
-
- /* replace the static line-edit control with the roster autocompleter */
- ui_.dummySenderName->setVisible(false);
- jid_ = new QtSuggestingJIDInput(this, settings);
- ui_.senderName->addWidget(jid_);
- jid_->onUserSelected.connect(boost::bind(&QtHighlightEditor::handleOnUserSelected, this, _1));
-
- /* handle autocomplete */
- connect(jid_, SIGNAL(textEdited(QString)), SLOT(handleContactSuggestionRequested(QString)));
-
- /* we need to be notified if any of the state changes so that we can update our textual rule description */
- connect(ui_.chatRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.roomRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.nickIsKeyword, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.allMsgRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.senderRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(jid_, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
- connect(ui_.keywordRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.keyword, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
- connect(ui_.matchPartialWords, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.matchCase, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
-
- /* allow selection of a custom sound file */
- connect(ui_.soundFileButton, SIGNAL(clicked()), SLOT(selectSoundFile()));
-
- /* allowing reordering items */
- connect(ui_.moveUpButton, SIGNAL(clicked()), this, SLOT(onUpButtonClicked()));
- connect(ui_.moveDownButton, SIGNAL(clicked()), this, SLOT(onDownButtonClicked()));
-
- setWindowTitle(tr("Highlight Rules"));
-}
-
-QtHighlightEditor::~QtHighlightEditor()
-{
-}
-
-QString QtHighlightEditor::formatShortDescription(const HighlightRule &rule)
-{
- const QString chatOrRoom = (rule.getMatchChat() ? tr("chat") : tr("room"));
-
- std::vector<std::string> senders = rule.getSenders();
- std::vector<std::string> keywords = rule.getKeywords();
-
- if (senders.empty() && keywords.empty() && !rule.getNickIsKeyword()) {
- return tr("All %1 messages.").arg(chatOrRoom);
- }
-
- if (rule.getNickIsKeyword()) {
- return tr("All %1 messages that mention my name.").arg(chatOrRoom);
- }
-
- if (!senders.empty()) {
- return tr("All %1 messages from %2.").arg(chatOrRoom, P2QSTRING(senders[0]));
- }
-
- if (!keywords.empty()) {
- return tr("All %1 messages mentioning the keyword '%2'.").arg(chatOrRoom, P2QSTRING(keywords[0]));
- }
-
- return tr("Unknown Rule");
-}
-
-void QtHighlightEditor::show()
-{
- highlightManager_->loadSettings();
-
- populateList();
-
- if (ui_.listWidget->count()) {
- selectRow(0);
- }
-
- updateResetToDefaultRulesVisibility();
-
- /* prepare default states */
- widgetClick();
-
- QWidget::show();
- QWidget::activateWindow();
-}
-
-void QtHighlightEditor::setHighlightManager(HighlightManager* highlightManager)
-{
- highlightManager_ = highlightManager;
-}
-
-void QtHighlightEditor::setContactSuggestions(const std::vector<Contact::ref>& suggestions)
-{
- jid_->setSuggestions(suggestions);
-}
-
-void QtHighlightEditor::colorOtherSelect()
-{
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
-}
-
-void QtHighlightEditor::colorCustomSelect()
-{
- ui_.foregroundColor->setEnabled(true);
- ui_.backgroundColor->setEnabled(true);
-}
-
-void QtHighlightEditor::soundOtherSelect()
-{
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
-}
-
-void QtHighlightEditor::soundCustomSelect()
-{
- ui_.soundFile->setEnabled(true);
- ui_.soundFileButton->setEnabled(true);
-}
-
-void QtHighlightEditor::onNewButtonClicked()
-{
- int row = getSelectedRow() + 1;
- populateList();
- HighlightRule newRule;
- newRule.setMatchMUC(true);
- highlightManager_->insertRule(row, newRule);
- QListWidgetItem *item = new QListWidgetItem();
- item->setText(formatShortDescription(newRule));
- QFont font;
- font.setItalic(true);
- item->setFont(font);
- ui_.listWidget->insertItem(row, item);
- selectRow(row);
-}
-
-void QtHighlightEditor::onDeleteButtonClicked()
-{
- int selectedRow = getSelectedRow();
- assert(selectedRow>=0 && selectedRow<ui_.listWidget->count());
- delete ui_.listWidget->takeItem(selectedRow);
- highlightManager_->removeRule(selectedRow);
-
- if (!ui_.listWidget->count()) {
- disableDialog();
- ui_.deleteButton->setEnabled(false);
- } else {
- if (selectedRow == ui_.listWidget->count()) {
- selectRow(ui_.listWidget->count() - 1);
- } else {
- selectRow(selectedRow);
- }
- }
-}
-
-void QtHighlightEditor::moveRowFromTo(int fromRow, int toRow) {
- int verticalScrollAreaPosition = ui_.scrollArea->verticalScrollBar()->value();
- highlightManager_->swapRules(fromRow, toRow);
- populateList();
- selectRow(toRow);
- ui_.scrollArea->verticalScrollBar()->setValue(verticalScrollAreaPosition);
-}
-
-void QtHighlightEditor::onUpButtonClicked() {
- const size_t moveFrom = ui_.listWidget->currentRow();
- const size_t moveTo = moveFrom - 1;
- moveRowFromTo(moveFrom, moveTo);
-}
-
-void QtHighlightEditor::onDownButtonClicked() {
- const size_t moveFrom = ui_.listWidget->currentRow();
- const size_t moveTo = moveFrom + 1;
- moveRowFromTo(moveFrom, moveTo);
-}
-
-void QtHighlightEditor::onCurrentRowChanged(int currentRow)
-{
- ui_.deleteButton->setEnabled(currentRow != -1);
- ui_.moveUpButton->setEnabled(currentRow != -1 && currentRow != 0);
- ui_.moveDownButton->setEnabled(currentRow != -1 && currentRow != (ui_.listWidget->count()-1));
-
- if (previousRow_ != -1) {
- if (ui_.listWidget->count() > previousRow_) {
- QFont font;
- font.setItalic(false);
- ui_.listWidget->item(previousRow_)->setFont(font);
- highlightManager_->setRule(previousRow_, ruleFromDialog());
- }
- }
-
- if (currentRow != -1) {
- HighlightRule rule = highlightManager_->getRule(currentRow);
- ruleToDialog(rule);
- if (ui_.listWidget->currentItem()) {
- QFont font;
- font.setItalic(true);
- ui_.listWidget->currentItem()->setFont(font);
- ui_.listWidget->currentItem()->setText(formatShortDescription(rule));
- }
- }
-
- /* grey the dialog if we have nothing selected */
- if (currentRow == -1) {
- disableDialog();
- }
-
- previousRow_ = currentRow;
-
- updateResetToDefaultRulesVisibility();
-}
-
-void QtHighlightEditor::onApplyButtonClick()
-{
- selectRow(getSelectedRow()); /* force save */
- highlightManager_->storeSettings();
-}
-
-void QtHighlightEditor::onCancelButtonClick()
-{
- close();
-}
-
-void QtHighlightEditor::onOkButtonClick()
-{
- onApplyButtonClick();
- close();
-}
-
-void QtHighlightEditor::setChildWidgetStates()
-{
- /* disable appropriate radio button child widgets */
-
- if (ui_.chatRadio->isChecked()) {
- if (ui_.nickIsKeyword->isChecked()) {
- /* switch to another choice before we disable this button */
- ui_.allMsgRadio->setChecked(true);
- }
- ui_.nickIsKeyword->setEnabled(false);
- } else if (ui_.roomRadio->isChecked()) {
- ui_.nickIsKeyword->setEnabled(true);
- } else { /* chats and rooms */
- ui_.nickIsKeyword->setEnabled(true);
- }
-
- if (ui_.senderRadio->isChecked()) {
- jid_->setEnabled(true);
- } else {
- jid_->setEnabled(false);
- }
-
- if (ui_.keywordRadio->isChecked()) {
- ui_.keyword->setEnabled(true);
- ui_.matchPartialWords->setEnabled(true);
- ui_.matchCase->setEnabled(true);
- } else {
- ui_.keyword->setEnabled(false);
- ui_.matchPartialWords->setEnabled(false);
- ui_.matchCase->setEnabled(false);
- }
-
- if (ui_.chatRadio->isChecked()) {
- ui_.allMsgRadio->setText(tr("Apply to all chat messages"));
- } else {
- ui_.allMsgRadio->setText(tr("Apply to all room messages"));
- }
-}
-
-void QtHighlightEditor::widgetClick()
-{
- setChildWidgetStates();
-
- HighlightRule rule = ruleFromDialog();
-
- if (ui_.listWidget->currentItem()) {
- ui_.listWidget->currentItem()->setText(formatShortDescription(rule));
- }
-}
-
-void QtHighlightEditor::disableDialog()
-{
- ui_.chatRadio->setEnabled(false);
- ui_.roomRadio->setEnabled(false);
- ui_.allMsgRadio->setEnabled(false);
- ui_.nickIsKeyword->setEnabled(false);
- ui_.senderRadio->setEnabled(false);
- ui_.dummySenderName->setEnabled(false);
- ui_.keywordRadio->setEnabled(false);
- ui_.keyword->setEnabled(false);
- ui_.matchPartialWords->setEnabled(false);
- ui_.matchCase->setEnabled(false);
- ui_.noColorRadio->setEnabled(false);
- ui_.customColorRadio->setEnabled(false);
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
- ui_.noSoundRadio->setEnabled(false);
- ui_.defaultSoundRadio->setEnabled(false);
- ui_.customSoundRadio->setEnabled(false);
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
-}
-
-void QtHighlightEditor::handleContactSuggestionRequested(const QString& text)
-{
- std::string stdText = Q2PSTRING(text);
- onContactSuggestionsRequested(stdText);
-}
-
-void QtHighlightEditor::selectSoundFile()
-{
- QString path = QFileDialog::getOpenFileName(this, tr("Select sound file..."), QString(), tr("Sounds (*.wav)"));
- ui_.soundFile->setText(path);
-}
-
-void QtHighlightEditor::onResetToDefaultRulesClicked() {
- highlightManager_->resetToDefaultRulesList();
- populateList();
- updateResetToDefaultRulesVisibility();
-}
-
-void QtHighlightEditor::handleOnUserSelected(const Contact::ref& contact) {
- /* this might seem like it should be standard behaviour for the suggesting input box, but is not desirable in all cases */
- if (contact->jid.isValid()) {
- jid_->setText(P2QSTRING(contact->jid.toString()));
- } else {
- jid_->setText(P2QSTRING(contact->name));
- }
-}
-
-void QtHighlightEditor::populateList()
-{
- previousRow_ = -1;
- ui_.listWidget->clear();
- HighlightRulesListPtr rules = highlightManager_->getRules();
- for (size_t i = 0; i < rules->getSize(); ++i) {
- const HighlightRule& rule = rules->getRule(i);
- QListWidgetItem *item = new QListWidgetItem();
- item->setText(formatShortDescription(rule));
- ui_.listWidget->addItem(item);
- }
-}
-
-void QtHighlightEditor::selectRow(int row)
-{
- for (int i = 0; i < ui_.listWidget->count(); ++i) {
- if (i == row) {
- ui_.listWidget->item(i)->setSelected(true);
- onCurrentRowChanged(i);
- } else {
- ui_.listWidget->item(i)->setSelected(false);
- }
- }
- ui_.listWidget->setCurrentRow(row);
-}
-
-int QtHighlightEditor::getSelectedRow() const
-{
- for (int i = 0; i < ui_.listWidget->count(); ++i) {
- if (ui_.listWidget->item(i)->isSelected()) {
- return i;
- }
- }
- return -1;
-}
-
-HighlightRule QtHighlightEditor::ruleFromDialog()
-{
- HighlightRule rule;
- HighlightAction& action = rule.getAction();
-
- if (ui_.chatRadio->isChecked()) {
- rule.setMatchChat(true);
- rule.setMatchMUC(false);
- } else {
- rule.setMatchChat(false);
- rule.setMatchMUC(true);
- }
-
- if (ui_.allMsgRadio->isChecked()) {
- action.setHighlightWholeMessage(true);
- }
-
- if (ui_.senderRadio->isChecked()) {
- QString senderName = jid_->text();
- if (!senderName.isEmpty()) {
- std::vector<std::string> senders;
- senders.push_back(Q2PSTRING(senderName));
- rule.setSenders(senders);
- action.setHighlightWholeMessage(true);
- }
- }
-
- if (ui_.keywordRadio->isChecked()) {
- QString keywordString = ui_.keyword->text();
- if (!keywordString.isEmpty()) {
- std::vector<std::string> keywords;
- keywords.push_back(Q2PSTRING(keywordString));
- rule.setKeywords(keywords);
- }
- }
-
- if (ui_.nickIsKeyword->isChecked()) {
- rule.setNickIsKeyword(true);
- rule.setMatchWholeWords(true);
- rule.setMatchCase(true);
- } else {
- rule.setMatchWholeWords(!ui_.matchPartialWords->isChecked());
- rule.setMatchCase(ui_.matchCase->isChecked());
- }
-
- if (ui_.noColorRadio->isChecked()) {
- action.setTextColor("");
- action.setTextBackground("");
- } else {
- action.setTextColor(Q2PSTRING(ui_.foregroundColor->getColor().name()));
- action.setTextBackground(Q2PSTRING(ui_.backgroundColor->getColor().name()));
- }
-
- if (ui_.noSoundRadio->isChecked()) {
- action.setPlaySound(false);
- } else if (ui_.defaultSoundRadio->isChecked()) {
- action.setPlaySound(true);
- action.setSoundFile("");
- } else {
- action.setPlaySound(true);
- action.setSoundFile(Q2PSTRING(ui_.soundFile->text()));
- }
-
- return rule;
-}
-
-void QtHighlightEditor::ruleToDialog(const HighlightRule& rule)
-{
- ui_.chatRadio->setEnabled(true);
- ui_.roomRadio->setEnabled(true);
-
- if (rule.getMatchMUC()) {
- ui_.chatRadio->setChecked(false);
- ui_.roomRadio->setChecked(true);
- } else {
- ui_.chatRadio->setChecked(true);
- ui_.roomRadio->setChecked(false);
- }
-
- ui_.allMsgRadio->setEnabled(true);
- ui_.allMsgRadio->setChecked(true); /* this is the default radio button */
- jid_->setText("");
- ui_.keyword->setText("");
- ui_.matchPartialWords->setChecked(false);
- ui_.matchCase->setChecked(false);
-
- ui_.nickIsKeyword->setEnabled(true);
- if (rule.getNickIsKeyword()) {
- ui_.nickIsKeyword->setChecked(true);
- }
-
- ui_.senderRadio->setEnabled(true);
- std::vector<std::string> senders = rule.getSenders();
- if (!senders.empty()) {
- ui_.senderRadio->setChecked(true);
- jid_->setText(P2QSTRING(senders[0]));
- }
-
- ui_.keywordRadio->setEnabled(true);
- std::vector<std::string> keywords = rule.getKeywords();
- if (!keywords.empty()) {
- ui_.keywordRadio->setChecked(true);
- ui_.keyword->setText(P2QSTRING(keywords[0]));
- ui_.matchPartialWords->setChecked(!rule.getMatchWholeWords());
- ui_.matchCase->setChecked(rule.getMatchCase());
- }
-
- const HighlightAction& action = rule.getAction();
-
- ui_.noColorRadio->setEnabled(true);
- ui_.customColorRadio->setEnabled(true);
- if (action.getTextColor().empty() && action.getTextBackground().empty()) {
- ui_.noColorRadio->setChecked(true);
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
- } else {
- ui_.foregroundColor->setEnabled(true);
- ui_.backgroundColor->setEnabled(true);
- QColor foregroundColor(P2QSTRING(action.getTextColor()));
- ui_.foregroundColor->setColor(foregroundColor);
- QColor backgroundColor(P2QSTRING(action.getTextBackground()));
- ui_.backgroundColor->setColor(backgroundColor);
- ui_.customColorRadio->setChecked(true);
- }
-
- ui_.noSoundRadio->setEnabled(true);
- ui_.defaultSoundRadio->setEnabled(true);
- ui_.customSoundRadio->setEnabled(true);
- ui_.soundFile->setText("");
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
- if (action.playSound()) {
- if (action.getSoundFile().empty()) {
- ui_.defaultSoundRadio->setChecked(true);
- } else {
- ui_.customSoundRadio->setChecked(true);
- ui_.soundFile->setText(P2QSTRING(action.getSoundFile()));
- ui_.soundFile->setEnabled(true);
- ui_.soundFileButton->setEnabled(true);
- }
- } else {
- ui_.noSoundRadio->setChecked(true);
- }
-
- /* set radio button child option states */
- setChildWidgetStates();
-}
-
-void QtHighlightEditor::updateResetToDefaultRulesVisibility() {
- ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setVisible(!highlightManager_->isDefaultRulesList());
-}
-
-}
diff --git a/Swift/QtUI/QtHighlightEditor.h b/Swift/QtUI/QtHighlightEditor.h
deleted file mode 100644
index c4a12e2..0000000
--- a/Swift/QtUI/QtHighlightEditor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-/*
- * Copyright (c) 2014-2016 Isode Limited.
- * All rights reserved.
- * See the COPYING file for more information.
- */
-
-#pragma once
-
-#include <Swift/Controllers/HighlightRule.h>
-#include <Swift/Controllers/UIInterfaces/HighlightEditorWindow.h>
-
-#include <Swift/QtUI/ui_QtHighlightEditor.h>
-
-namespace Swift {
-
- class QtSettingsProvider;
- class QtSuggestingJIDInput;
- class QtWebKitChatView;
-
- class QtHighlightEditor : public QWidget, public HighlightEditorWindow {
- Q_OBJECT
-
- public:
- QtHighlightEditor(QtSettingsProvider* settings, QWidget* parent = nullptr);
- virtual ~QtHighlightEditor();
-
- virtual void show();
- virtual void setHighlightManager(HighlightManager* highlightManager);
- virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions);
-
- private slots:
- void colorOtherSelect();
- void colorCustomSelect();
- void soundOtherSelect();
- void soundCustomSelect();
- void onNewButtonClicked();
- void onDeleteButtonClicked();
- void onUpButtonClicked();
- void onDownButtonClicked();
- void onCurrentRowChanged(int currentRow);
- void onApplyButtonClick();
- void onCancelButtonClick();
- void onOkButtonClick();
- void setChildWidgetStates();
- void widgetClick();
- void disableDialog();
- void handleContactSuggestionRequested(const QString& text);
- void selectSoundFile();
- void onResetToDefaultRulesClicked();
-
- private:
- QString formatShortDescription(const HighlightRule &rule);
- void handleOnUserSelected(const Contact::ref& contact);
- void populateList();
- void selectRow(int row);
- int getSelectedRow() const;
- HighlightRule ruleFromDialog();
- void ruleToDialog(const HighlightRule& rule);
- void updateResetToDefaultRulesVisibility();
- void moveRowFromTo(int fromRow, int toRow);
-
- private:
- Ui::QtHighlightEditor ui_;
- QtSettingsProvider* settings_;
- HighlightManager* highlightManager_ = nullptr;
- QtSuggestingJIDInput* jid_;
- int previousRow_;
- };
-
-}
diff --git a/Swift/QtUI/QtHighlightEditor.ui b/Swift/QtUI/QtHighlightEditor.ui
deleted file mode 100644
index 6d2338d..0000000
--- a/Swift/QtUI/QtHighlightEditor.ui
+++ /dev/null
@@ -1,466 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QtHighlightEditor</class>
- <widget class="QWidget" name="QtHighlightEditor">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>500</width>
- <height>600</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>500</width>
- <height>600</height>
- </size>
- </property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QScrollArea" name="scrollArea">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- <property name="widgetResizable">
- <bool>true</bool>
- </property>
- <widget class="QWidget" name="scrollAreaWidgetContents">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>463</width>
- <height>792</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Incoming messages are checked against the following rules. First rule that matches will be executed.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QListWidget" name="listWidget">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <spacer name="horizontalSpacer_8">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="newButton">
- <property name="text">
- <string>New Rule</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="deleteButton">
- <property name="text">
- <string>Remove Rule</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveUpButton">
- <property name="text">
- <string>Move Up</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveDownButton">
- <property name="text">
- <string>Move Down</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Apply Rule To</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QRadioButton" name="roomRadio">
- <property name="text">
- <string>Rooms</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="chatRadio">
- <property name="text">
- <string>Chats</string>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>246</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Rule Conditions</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QRadioButton" name="allMsgRadio">
- <property name="text">
- <string>Apply to all messages</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="nickIsKeyword">
- <property name="text">
- <string>Only messages mentioning me</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="senderRadio">
- <property name="text">
- <string>Messages from this sender:</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="senderName">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinimumSize</enum>
- </property>
- <item>
- <widget class="QLineEdit" name="dummySenderName"/>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QRadioButton" name="keywordRadio">
- <property name="text">
- <string>Messages containing this keyword:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="keyword"/>
- </item>
- <item>
- <widget class="QCheckBox" name="matchPartialWords">
- <property name="text">
- <string>Match keyword within longer words</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="matchCase">
- <property name="text">
- <string>Keyword is case sensitive</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Highlight Action</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <widget class="QRadioButton" name="noColorRadio">
- <property name="text">
- <string>No Highlight</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="customColorRadio">
- <property name="text">
- <string>Custom Color</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_5">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="Swift::QtColorToolButton" name="foregroundColor">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>&amp;Text</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="Swift::QtColorToolButton" name="backgroundColor">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>&amp;Background</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Sound Action</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <item>
- <widget class="QRadioButton" name="noSoundRadio">
- <property name="text">
- <string>No Sound</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="defaultSoundRadio">
- <property name="text">
- <string>Default Sound</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="customSoundRadio">
- <property name="text">
- <string>Custom Sound</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_6">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_8">
- <item>
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLineEdit" name="soundFile">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="readOnly">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="soundFileButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_9">
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>Swift::QtColorToolButton</class>
- <extends>QToolButton</extends>
- <header>QtColorToolButton.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp b/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp
new file mode 100644
index 0000000..c4e64ab
--- /dev/null
+++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtHighlightNotificationConfigDialog.h>
+
+#include <Swiften/Base/Log.h>
+
+#include <Swift/Controllers/Highlighting/HighlightManager.h>
+
+#include <Swift/QtUI/QtCheckBoxStyledItemDelegate.h>
+#include <Swift/QtUI/QtColorSelectionStyledItemDelegate.h>
+#include <Swift/QtUI/QtSoundSelectionStyledItemDelegate.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtHighlightNotificationConfigDialog::QtHighlightNotificationConfigDialog(QtSettingsProvider* settings, QWidget* parent) : QDialog(parent), settings_(settings) {
+ ui_.setupUi(this);
+
+ // setup custom delegates for checkboxes, color selection, and sound selection
+ ui_.userHighlightTreeWidget->setItemDelegateForColumn(1, new QtColorSelectionStyledItemDelegate(this));
+ ui_.userHighlightTreeWidget->setItemDelegateForColumn(2, new QtColorSelectionStyledItemDelegate(this));
+ ui_.userHighlightTreeWidget->setItemDelegateForColumn(3, new QtSoundSelectionStyledItemDelegate(this));
+ ui_.userHighlightTreeWidget->setItemDelegateForColumn(4, new QtCheckBoxStyledItemDelegate(this));
+
+ ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(1, new QtCheckBoxStyledItemDelegate(this));
+ ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(2, new QtColorSelectionStyledItemDelegate(this));
+ ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(3, new QtColorSelectionStyledItemDelegate(this));
+ ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(4, new QtSoundSelectionStyledItemDelegate(this));
+ ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(5, new QtCheckBoxStyledItemDelegate(this));
+
+ // user highlight edit slots
+ connect(ui_.addUserHighlightPushButton, &QPushButton::clicked, [&](bool) {
+ auto item = new QTreeWidgetItem();
+ item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
+ item->setData(0, Qt::EditRole, "");
+ item->setData(1, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#000000"));
+ item->setData(2, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#ffff00"));
+ item->setData(3, Qt::EditRole, "");
+ item->setData(4, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(true));
+ ui_.userHighlightTreeWidget->addTopLevelItem(item);
+ });
+ connect(ui_.removeUserHighlightPushButton, &QPushButton::clicked, [&](bool) {
+ auto currentItem = ui_.userHighlightTreeWidget->currentItem();
+ if (currentItem) {
+ ui_.userHighlightTreeWidget->takeTopLevelItem(ui_.userHighlightTreeWidget->indexOfTopLevelItem(currentItem));
+ }
+ });
+ connect(ui_.userHighlightTreeWidget, &QTreeWidget::currentItemChanged, [&](QTreeWidgetItem* current, QTreeWidgetItem* ) {
+ ui_.removeUserHighlightPushButton->setEnabled(current != 0);
+ });
+
+ // keyword highlight edit slots
+ connect(ui_.addKeywordHighlightPushButton, &QPushButton::clicked, [&](bool) {
+ auto item = new QTreeWidgetItem();
+ item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
+ item->setData(0, Qt::EditRole, "");
+ item->setData(1, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(false));
+ item->setData(2, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#000000"));
+ item->setData(3, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#ffff00"));
+ item->setData(4, Qt::EditRole, "");
+ item->setData(5, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(true));
+ ui_.keywordHighlightTreeWidget->addTopLevelItem(item);
+ });
+ connect(ui_.removeKeywordHighlightPushButton, &QPushButton::clicked, [&](bool) {
+ auto currentItem = ui_.keywordHighlightTreeWidget->currentItem();
+ if (currentItem) {
+ ui_.keywordHighlightTreeWidget->takeTopLevelItem(ui_.keywordHighlightTreeWidget->indexOfTopLevelItem(currentItem));
+ }
+ });
+ connect(ui_.keywordHighlightTreeWidget, &QTreeWidget::currentItemChanged, [&](QTreeWidgetItem* current, QTreeWidgetItem* ) {
+ ui_.removeKeywordHighlightPushButton->setEnabled(current != 0);
+ });
+
+ // setup slots for main dialog buttons
+ connect(ui_.buttonBox, &QDialogButtonBox::clicked, [&](QAbstractButton* clickedButton) {
+ if (clickedButton == ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults)) {
+ if (highlightManager_) {
+ highlightManager_->resetToDefaultConfiguration();
+ setHighlightConfigurationToDialog(*highlightManager_->getConfiguration());
+ }
+ }
+ });
+ connect(this, &QDialog::accepted, [&]() {
+ if (highlightManager_) {
+ highlightManager_->setConfiguration(getHighlightConfigurationFromDialog());
+ }
+ });
+}
+
+QtHighlightNotificationConfigDialog::~QtHighlightNotificationConfigDialog() {
+}
+
+void QtHighlightNotificationConfigDialog::show() {
+ if (highlightManager_) {
+ setHighlightConfigurationToDialog(*(highlightManager_->getConfiguration()));
+ }
+ QWidget::show();
+ QWidget::activateWindow();
+}
+
+void QtHighlightNotificationConfigDialog::setHighlightManager(HighlightManager* highlightManager) {
+ highlightManager_ = highlightManager;
+}
+
+void QtHighlightNotificationConfigDialog::setContactSuggestions(const std::vector<Contact::ref>& /*suggestions*/) {
+
+}
+
+HighlightConfiguration QtHighlightNotificationConfigDialog::getHighlightConfigurationFromDialog() const {
+ auto qtColorToOptionalString = [&](const QColor& color) {
+ boost::optional<std::string> colorString;
+ if (color.isValid()) {
+ colorString = Q2PSTRING(color.name(QColor::HexRgb));
+ }
+ return colorString;
+ };
+
+ auto getHighlightActionFromWidgetItem = [&](const QTreeWidgetItem* item, int startingColumn) {
+ HighlightAction action;
+
+ action.setFrontColor(qtColorToOptionalString(item->data(startingColumn, QtColorSelectionStyledItemDelegate::DATA_ROLE).value<QColor>()));
+ action.setBackColor(qtColorToOptionalString(item->data(startingColumn + 1, QtColorSelectionStyledItemDelegate::DATA_ROLE).value<QColor>()));
+
+ std::string soundFilePath = Q2PSTRING(item->data(startingColumn + 2, Qt::EditRole).toString());
+ if (soundFilePath == "defaultSound") {
+ action.setSoundFilePath(boost::optional<std::string>(""));
+ }
+ else if (soundFilePath.empty()) {
+ action.setSoundFilePath(boost::optional<std::string>());
+ }
+ else {
+ action.setSoundFilePath(boost::optional<std::string>(soundFilePath));
+ }
+
+ action.setSystemNotificationEnabled(item->data(startingColumn + 3, QtCheckBoxStyledItemDelegate::DATA_ROLE).toBool());
+ return action;
+ };
+
+ HighlightConfiguration uiConfiguration;
+
+ // contact highlights
+ for (int i = 0; i < ui_.userHighlightTreeWidget->topLevelItemCount(); i++) {
+ auto item = ui_.userHighlightTreeWidget->topLevelItem(i);
+ HighlightConfiguration::ContactHighlight contactHighlight;
+ contactHighlight.name = Q2PSTRING(item->data(0, Qt::EditRole).toString());
+ contactHighlight.action = getHighlightActionFromWidgetItem(item, 1);
+ uiConfiguration.contactHighlights.push_back(contactHighlight);
+ }
+
+ // keyword highlights
+ for (int i = 0; i < ui_.keywordHighlightTreeWidget->topLevelItemCount(); i++) {
+ auto item = ui_.keywordHighlightTreeWidget->topLevelItem(i);
+ HighlightConfiguration::KeywordHightlight keywordHighlight;
+ keywordHighlight.keyword = Q2PSTRING(item->data(0, Qt::EditRole).toString());
+ keywordHighlight.matchCaseSensitive = item->data(1, QtCheckBoxStyledItemDelegate::DATA_ROLE).toBool();
+ keywordHighlight.action = getHighlightActionFromWidgetItem(item, 2);
+ uiConfiguration.keywordHighlights.push_back(keywordHighlight);
+ }
+
+ // general configuration
+ uiConfiguration.playSoundOnIncomingDirectMessages = ui_.playSoundOnDirectMessagesCheckBox->isChecked();
+ uiConfiguration.showNotificationOnIncomingDirectMessages = ui_.notificationOnDirectMessagesCheckBox->isChecked();
+ uiConfiguration.playSoundOnIncomingGroupchatMessages = ui_.playSoundOnGroupMessagesCheckBox->isChecked();
+ uiConfiguration.showNotificationOnIncomingGroupchatMessages = ui_.notificationOnGroupMessagesCheckBox->isChecked();
+
+ uiConfiguration.ownMentionAction.setFrontColor(qtColorToOptionalString(ui_.mentionTextColorColorButton->getColor()));
+ uiConfiguration.ownMentionAction.setBackColor(qtColorToOptionalString(ui_.mentionBackgroundColorButton->getColor()));
+ uiConfiguration.ownMentionAction.setSoundFilePath(ui_.playSoundOnMentionCheckBox->isChecked() ? boost::optional<std::string>("") : boost::optional<std::string>());
+ uiConfiguration.ownMentionAction.setSystemNotificationEnabled(ui_.notificationOnMentionCheckBox->isChecked());
+ return uiConfiguration;
+}
+
+void QtHighlightNotificationConfigDialog::setHighlightConfigurationToDialog(const HighlightConfiguration& config) {
+ auto optionalStringToQtColor = [](const boost::optional<std::string>& colorString) {
+ QColor qtColor;
+ if (colorString) {
+ qtColor = QColor(P2QSTRING(colorString.get_value_or(std::string(""))));
+ }
+ return qtColor;
+ };
+
+ auto optionalSoundPathStringToQString = [](const boost::optional<std::string>& soundPath) {
+ QString ret;
+ if (soundPath) {
+ if (soundPath.get_value_or("").empty()) {
+ ret = "defaultSound";
+ }
+ else {
+ ret = P2QSTRING(soundPath.get_value_or(""));
+ }
+ }
+ return ret;
+ };
+
+ auto setHighlightActionOnTreeWidgetItem = [&](QTreeWidgetItem* item, int startingColumn, const HighlightAction& action) {
+ item->setData(startingColumn, QtColorSelectionStyledItemDelegate::DATA_ROLE, optionalStringToQtColor(action.getFrontColor()));
+ item->setData(startingColumn + 1, QtColorSelectionStyledItemDelegate::DATA_ROLE, optionalStringToQtColor(action.getBackColor()));
+ item->setData(startingColumn + 2, Qt::DisplayRole, P2QSTRING(action.getSoundFilePath().get_value_or(std::string(""))));
+ item->setData(startingColumn + 2, Qt::EditRole, optionalSoundPathStringToQString(action.getSoundFilePath()));
+ item->setData(startingColumn + 3, QtCheckBoxStyledItemDelegate::DATA_ROLE, action.isSystemNotificationEnabled());
+ };
+
+ // contact highlights
+ ui_.userHighlightTreeWidget->clear();
+ for (const auto& contactHighlight : config.contactHighlights) {
+ auto item = new QTreeWidgetItem();
+ item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
+ item->setData(0, Qt::DisplayRole, P2QSTRING(contactHighlight.name));
+ item->setData(0, Qt::EditRole, P2QSTRING(contactHighlight.name));
+
+ setHighlightActionOnTreeWidgetItem(item, 1, contactHighlight.action);
+
+ ui_.userHighlightTreeWidget->addTopLevelItem(item);
+ }
+
+ // keyword highlights
+ ui_.keywordHighlightTreeWidget->clear();
+ for (const auto& keywordHighlight : config.keywordHighlights) {
+ auto item = new QTreeWidgetItem();
+ item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ item->setData(0, Qt::DisplayRole, P2QSTRING(keywordHighlight.keyword));
+ item->setData(0, Qt::EditRole, P2QSTRING(keywordHighlight.keyword));
+ item->setData(1, QtCheckBoxStyledItemDelegate::DATA_ROLE, keywordHighlight.matchCaseSensitive);
+
+ setHighlightActionOnTreeWidgetItem(item, 2, keywordHighlight.action);
+
+ ui_.keywordHighlightTreeWidget->addTopLevelItem(item);
+ }
+
+ // general configuration
+ ui_.playSoundOnDirectMessagesCheckBox->setChecked(config.playSoundOnIncomingDirectMessages);
+ ui_.notificationOnDirectMessagesCheckBox->setChecked(config.showNotificationOnIncomingDirectMessages);
+ ui_.playSoundOnGroupMessagesCheckBox->setChecked(config.playSoundOnIncomingGroupchatMessages);
+ ui_.notificationOnGroupMessagesCheckBox->setChecked(config.showNotificationOnIncomingGroupchatMessages);
+
+ ui_.mentionTextColorColorButton->setColor(optionalStringToQtColor(config.ownMentionAction.getFrontColor()));
+ ui_.mentionBackgroundColorButton->setColor(optionalStringToQtColor(config.ownMentionAction.getBackColor()));
+ ui_.playSoundOnMentionCheckBox->setChecked(config.ownMentionAction.getSoundFilePath().is_initialized());
+ ui_.notificationOnMentionCheckBox->setChecked(config.ownMentionAction.isSystemNotificationEnabled());
+}
+
+}
diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.h b/Swift/QtUI/QtHighlightNotificationConfigDialog.h
new file mode 100644
index 0000000..03044eb
--- /dev/null
+++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/Highlighting/HighlightConfiguration.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWindow.h>
+
+#include <Swift/QtUI/ui_QtHighlightNotificationConfigDialog.h>
+
+namespace Swift {
+
+ class QtSettingsProvider;
+ class QtSuggestingJIDInput;
+
+ class QtHighlightNotificationConfigDialog : public QDialog, public HighlightEditorWindow {
+ Q_OBJECT
+
+ public:
+ QtHighlightNotificationConfigDialog(QtSettingsProvider* settings, QWidget* parent = nullptr);
+ virtual ~QtHighlightNotificationConfigDialog();
+
+ virtual void show();
+ virtual void setHighlightManager(HighlightManager* highlightManager);
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions);
+
+ private:
+ HighlightConfiguration getHighlightConfigurationFromDialog() const;
+ void setHighlightConfigurationToDialog(const HighlightConfiguration& config);
+
+ private:
+ Ui::QtHighlightNotificationConfigDialog ui_;
+ QtSettingsProvider* settings_;
+ HighlightManager* highlightManager_ = nullptr;
+ QtSuggestingJIDInput* jid_ = nullptr;
+ };
+
+}
diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.ui b/Swift/QtUI/QtHighlightNotificationConfigDialog.ui
new file mode 100644
index 0000000..7074ad8
--- /dev/null
+++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.ui
@@ -0,0 +1,537 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtHighlightNotificationConfigDialog</class>
+ <widget class="QDialog" name="QtHighlightNotificationConfigDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>629</width>
+ <height>515</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Highlight and Notification Configuration</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="modal">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Highlight messages from these people</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="userHighlightTreeWidget">
+ <property name="tabKeyNavigation">
+ <bool>true</bool>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ <property name="defaultDropAction">
+ <enum>Qt::MoveAction</enum>
+ </property>
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="animated">
+ <bool>true</bool>
+ </property>
+ <property name="headerHidden">
+ <bool>false</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerCascadingSectionResizes">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>80</number>
+ </attribute>
+ <attribute name="headerHighlightSections">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>15</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>User</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Text color</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Background color</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Play sound</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Create notification</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="addUserHighlightPushButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>26</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="sizeIncrement">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>13</pointsize>
+ <weight>50</weight>
+ <italic>false</italic>
+ <bold>false</bold>
+ <underline>false</underline>
+ <strikeout>false</strikeout>
+ <kerning>true</kerning>
+ </font>
+ </property>
+ <property name="text">
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeUserHighlightPushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>26</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Highlight messages containing these keywords</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTreeWidget" name="keywordHighlightTreeWidget">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>300</height>
+ </size>
+ </property>
+ <property name="tabKeyNavigation">
+ <bool>true</bool>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>false</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::InternalMove</enum>
+ </property>
+ <property name="defaultDropAction">
+ <enum>Qt::MoveAction</enum>
+ </property>
+ <property name="indentation">
+ <number>0</number>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="animated">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Keyword</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Match case sensitive</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Text color</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Background color</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Play sound</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Create notification</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="addKeywordHighlightPushButton">
+ <property name="maximumSize">
+ <size>
+ <width>26</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>+</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeKeywordHighlightPushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>26</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>-</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>General notification settings</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <item row="3" column="1">
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="Swift::QtColorToolButton" name="mentionBackgroundColorButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Highlight background color on own mention</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="notificationOnGroupMessagesCheckBox">
+ <property name="text">
+ <string>Create notification on incoming group messages</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="notificationOnMentionCheckBox">
+ <property name="text">
+ <string>Create notification when my name is mentioned</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="playSoundOnDirectMessagesCheckBox">
+ <property name="text">
+ <string>Play sound on incoming direct messages</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="playSoundOnGroupMessagesCheckBox">
+ <property name="text">
+ <string>Play sound on incoming group messages</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QCheckBox" name="notificationOnDirectMessagesCheckBox">
+ <property name="text">
+ <string>Create notification on incoming direct messages</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="playSoundOnMentionCheckBox">
+ <property name="text">
+ <string>Play sound when my name is mentioned</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="Swift::QtColorToolButton" name="mentionTextColorColorButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Highlight text color on own mention</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>Swift::QtColorToolButton</class>
+ <extends>QToolButton</extends>
+ <header>QtColorToolButton.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>userHighlightTreeWidget</tabstop>
+ <tabstop>addUserHighlightPushButton</tabstop>
+ <tabstop>removeUserHighlightPushButton</tabstop>
+ <tabstop>keywordHighlightTreeWidget</tabstop>
+ <tabstop>addKeywordHighlightPushButton</tabstop>
+ <tabstop>removeKeywordHighlightPushButton</tabstop>
+ <tabstop>playSoundOnDirectMessagesCheckBox</tabstop>
+ <tabstop>notificationOnDirectMessagesCheckBox</tabstop>
+ <tabstop>playSoundOnGroupMessagesCheckBox</tabstop>
+ <tabstop>notificationOnGroupMessagesCheckBox</tabstop>
+ <tabstop>playSoundOnMentionCheckBox</tabstop>
+ <tabstop>notificationOnMentionCheckBox</tabstop>
+ <tabstop>mentionTextColorColorButton</tabstop>
+ <tabstop>mentionBackgroundColorButton</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtHighlightNotificationConfigDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtHighlightNotificationConfigDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp
new file mode 100644
index 0000000..3811004
--- /dev/null
+++ b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtSoundSelectionStyledItemDelegate.h>
+
+#include <QApplication>
+#include <QComboBox>
+#include <QEvent>
+#include <QFileDialog>
+#include <QMenu>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QStyle>
+#include <QStyleOptionComboBox>
+
+#include <Swiften/Base/Log.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+namespace Swift {
+
+QtSoundSelectionStyledItemDelegate::QtSoundSelectionStyledItemDelegate(QObject* parent) : QStyledItemDelegate(parent) {
+
+}
+
+void QtSoundSelectionStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+ // draw item selected background
+ painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
+
+ auto editRoleString = index.data(Qt::EditRole).toString();
+
+ // draw combo box
+ QStyleOptionComboBox opt;
+ opt.rect = option.rect;
+ opt.rect.setHeight(opt.rect.height() + 2);
+ opt.state = QStyle::State_Active | QStyle::State_Enabled;
+ if (editRoleString.isEmpty()) {
+ opt.currentText = tr("No sound");
+ }
+ else if (editRoleString == "defaultSound") {
+ opt.currentText = tr("Default sound");
+ }
+ else {
+ opt.currentText = editRoleString;
+ }
+
+ painter->save();
+ QFont smallFont;
+ smallFont.setPointSize(smallFont.pointSize() - 3);
+ painter->setFont(smallFont);
+
+ QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &opt, painter);
+ QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &opt, painter);
+ painter->restore();
+}
+
+bool QtSoundSelectionStyledItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& /*option*/, const QModelIndex& index) {
+ if (event->type() == QEvent::MouseButtonRelease) {
+ auto mouseEvent = dynamic_cast<QMouseEvent*>(event);
+ assert(mouseEvent);
+ auto editRoleString = index.data(Qt::EditRole).toString();
+
+ auto popUpMenu = new QMenu();
+
+ auto noSound = popUpMenu->addAction(tr("No sound"));
+ auto defaultSound = popUpMenu->addAction(tr("Default sound"));
+ QAction* customSoundFile = nullptr;
+ QAction* selectedAction = nullptr;
+ if (editRoleString.isEmpty()) {
+ selectedAction = noSound;
+ }
+ else if (editRoleString == "defaultSound") {
+ selectedAction = defaultSound;
+ }
+ else {
+ customSoundFile = popUpMenu->addAction(editRoleString);
+ selectedAction = customSoundFile;
+ }
+ if (selectedAction) {
+ selectedAction->setCheckable(true);
+ selectedAction->setChecked(true);
+ }
+ auto chooseSoundFile = popUpMenu->addAction(tr("Choose sound file…"));
+
+ selectedAction = popUpMenu->exec(mouseEvent->globalPos(), selectedAction);
+
+ if (selectedAction == defaultSound) {
+ model->setData(index, "defaultSound", Qt::EditRole);
+ }
+ else if (customSoundFile && (selectedAction == customSoundFile)) {
+ model->setData(index, customSoundFile->text(), Qt::EditRole);
+ }
+ else if (selectedAction == noSound) {
+ model->setData(index, "", Qt::EditRole);
+ }
+ else if (selectedAction == chooseSoundFile) {
+ auto newPath = QFileDialog::getOpenFileName(0, tr("Choose notification sound file"), "", tr("WAV Files (*.wav)"));
+ if (!newPath.isEmpty()) {
+ model->setData(index, newPath, Qt::EditRole);
+ }
+ }
+
+ delete popUpMenu;
+ }
+ return true;
+}
+
+};
diff --git a/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h
new file mode 100644
index 0000000..fabf668
--- /dev/null
+++ b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QStyledItemDelegate>
+
+namespace Swift {
+
+class QtSoundSelectionStyledItemDelegate : public QStyledItemDelegate {
+ public:
+ QtSoundSelectionStyledItemDelegate(QObject* parent = nullptr);
+
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
+
+ protected:
+ virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
+};
+
+}
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index 16952a0..ece29ec 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -23,7 +23,7 @@
#include <Swift/QtUI/QtChatWindowFactory.h>
#include <Swift/QtUI/QtContactEditWindow.h>
#include <Swift/QtUI/QtFileTransferListWidget.h>
-#include <Swift/QtUI/QtHighlightEditor.h>
+#include <Swift/QtUI/QtHighlightNotificationConfigDialog.h>
#include <Swift/QtUI/QtHistoryWindow.h>
#include <Swift/QtUI/QtJoinMUCWindow.h>
#include <Swift/QtUI/QtLoginWindow.h>
@@ -169,7 +169,7 @@ WhiteboardWindow* QtUIFactory::createWhiteboardWindow(std::shared_ptr<Whiteboard
}
HighlightEditorWindow* QtUIFactory::createHighlightEditorWindow() {
- return new QtHighlightEditor(qtOnlySettings);
+ return new QtHighlightNotificationConfigDialog(qtOnlySettings);
}
BlockListEditorWidget *QtUIFactory::createBlockListEditorWidget() {
diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp
index 6fe9397..9aeef24 100644
--- a/Swift/QtUI/QtWebKitChatView.cpp
+++ b/Swift/QtUI/QtWebKitChatView.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -478,7 +478,7 @@ std::string QtWebKitChatView::addMessage(
std::shared_ptr<SecurityLabel> label,
const std::string& avatarPath,
const boost::posix_time::ptime& time) {
- return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message));
+ return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, message.getHighlightActionSender(), ChatSnippet::getDirection(message));
}
QString QtWebKitChatView::getHighlightSpanStart(const std::string& text, const std::string& background) {
@@ -494,7 +494,7 @@ QString QtWebKitChatView::getHighlightSpanStart(const std::string& text, const s
}
QString QtWebKitChatView::getHighlightSpanStart(const HighlightAction& highlight) {
- return getHighlightSpanStart(highlight.getTextColor(), highlight.getTextBackground());
+ return getHighlightSpanStart(highlight.getFrontColor().get_value_or(""), highlight.getBackColor().get_value_or(""));
}
QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& message) {
@@ -523,7 +523,7 @@ QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& messa
continue;
}
if ((highlightPart = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) {
- QString spanStart = getHighlightSpanStart(highlightPart->action.getTextColor(), highlightPart->action.getTextBackground());
+ QString spanStart = getHighlightSpanStart(highlightPart->action.getFrontColor().get_value_or(""), highlightPart->action.getBackColor().get_value_or(""));
result += spanStart + QtUtilities::htmlEscape(P2QSTRING(highlightPart->text)) + "</span>";
continue;
}
@@ -554,7 +554,7 @@ std::string QtWebKitChatView::addMessage(
QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
QString styleSpanEnd = style == "" ? "" : "</span>";
- bool highlightWholeMessage = highlight.highlightWholeMessage() && highlight.getTextBackground() != "" && highlight.getTextColor() != "";
+ bool highlightWholeMessage = highlight.getFrontColor() || highlight.getBackColor();
QString highlightSpanStart = highlightWholeMessage ? getHighlightSpanStart(highlight) : "";
QString highlightSpanEnd = highlightWholeMessage ? "</span>" : "";
htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ;
@@ -572,7 +572,7 @@ std::string QtWebKitChatView::addMessage(
}
std::string QtWebKitChatView::addAction(const ChatWindow::ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) {
- return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message));
+ return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getHighlightActionSender(), ChatSnippet::getDirection(message));
}
static QString encodeButtonArgument(const QString& str) {
@@ -835,11 +835,11 @@ std::string QtWebKitChatView::addSystemMessage(const ChatWindow::ChatMessage& me
}
void QtWebKitChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
- replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", message.getFullMessageHighlightAction());
+ replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", message.getHighlightActionSender());
}
void QtWebKitChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
- replaceMessage(chatMessageToHTML(message), id, time, "", message.getFullMessageHighlightAction());
+ replaceMessage(chatMessageToHTML(message), id, time, "", message.getHighlightActionSender());
}
void QtWebKitChatView::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, ChatWindow::TimestampBehaviour timestampBehavior) {
@@ -876,8 +876,8 @@ void QtWebKitChatView::replaceMessage(const QString& message, const std::string&
QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
QString styleSpanEnd = style == "" ? "" : "</span>";
- QString highlightSpanStart = highlight.highlightWholeMessage() ? getHighlightSpanStart(highlight) : "";
- QString highlightSpanEnd = highlight.highlightWholeMessage() ? "</span>" : "";
+ QString highlightSpanStart = (highlight.getFrontColor() || highlight.getBackColor()) ? getHighlightSpanStart(highlight) : "";
+ QString highlightSpanEnd = (highlight.getFrontColor() || highlight.getBackColor()) ? "</span>" : "";
messageHTML = styleSpanStart + highlightSpanStart + messageHTML + highlightSpanEnd + styleSpanEnd;
replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time));
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 3512120..69e99e7 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -145,9 +145,9 @@ sources = [
"QtContactEditWindow.cpp",
"QtContactEditWidget.cpp",
"QtSingleWindow.cpp",
- "QtHighlightEditor.cpp",
"QtColorToolButton.cpp",
"QtClosableLineEdit.cpp",
+ "QtHighlightNotificationConfigDialog.cpp",
"ChatSnippet.cpp",
"MessageSnippet.cpp",
"SystemMessageSnippet.cpp",
@@ -216,7 +216,10 @@ sources = [
"QtUpdateFeedSelectionDialog.cpp",
"Trellis/QtDynamicGridLayout.cpp",
"Trellis/QtDNDTabBar.cpp",
- "Trellis/QtGridSelectionDialog.cpp"
+ "Trellis/QtGridSelectionDialog.cpp",
+ "QtCheckBoxStyledItemDelegate.cpp",
+ "QtColorSelectionStyledItemDelegate.cpp",
+ "QtSoundSelectionStyledItemDelegate.cpp"
]
if env["PLATFORM"] == "win32" :
@@ -311,7 +314,7 @@ myenv.Uic4("QtAffiliationEditor.ui")
myenv.Uic4("QtJoinMUCWindow.ui")
myenv.Uic4("QtHistoryWindow.ui")
myenv.Uic4("QtConnectionSettings.ui")
-myenv.Uic4("QtHighlightEditor.ui")
+myenv.Uic4("QtHighlightNotificationConfigDialog.ui")
myenv.Uic4("QtBlockListEditorWindow.ui")
myenv.Uic4("QtSpellCheckerWindow.ui")
myenv.Uic4("QtUpdateFeedSelectionDialog.ui")