summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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
@@ -1,56 +1,56 @@
/*
* Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtUIFactory.h>
#include <algorithm>
#include <QSplitter>
#include <Swiften/Whiteboard/WhiteboardSession.h>
#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h>
#include <Swift/QtUI/QtAdHocCommandWindow.h>
#include <Swift/QtUI/QtBlockListEditorWindow.h>
#include <Swift/QtUI/QtChatTabs.h>
#include <Swift/QtUI/QtChatTabsBase.h>
#include <Swift/QtUI/QtChatWindow.h>
#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>
#include <Swift/QtUI/QtMainWindow.h>
#include <Swift/QtUI/QtProfileWindow.h>
#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtSingleWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtSystemTray.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtXMLConsoleWidget.h>
#include <Swift/QtUI/UserSearch/QtUserSearchWindow.h>
#include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h>
namespace Swift {
QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, AutoUpdater* autoUpdater, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabsBase(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(nullptr), loginWindow(nullptr), statusCache(statusCache), autoUpdater(autoUpdater), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) {
chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE);
historyFontSize_ = settings->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE);
this->tabs = dynamic_cast<QtChatTabs*>(tabsBase);
}
XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() {
QtXMLConsoleWidget* widget = new QtXMLConsoleWidget();
tabsBase->addTab(widget);
showTabs();
widget->show();
return widget;
}
@@ -142,50 +142,50 @@ void QtUIFactory::handleChatWindowFontResized(int size) {
// resize font in other chat windows
for (auto&& existingWindow : chatWindows) {
if (!existingWindow.isNull()) {
existingWindow->handleFontResized(size);
}
}
}
UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) {
return new QtUserSearchWindow(eventStream, type, groups, qtOnlySettings);
}
JoinMUCWindow* QtUIFactory::createJoinMUCWindow(UIEventStream* uiEventStream) {
return new QtJoinMUCWindow(uiEventStream);
}
ProfileWindow* QtUIFactory::createProfileWindow() {
return new QtProfileWindow();
}
ContactEditWindow* QtUIFactory::createContactEditWindow() {
return new QtContactEditWindow();
}
WhiteboardWindow* QtUIFactory::createWhiteboardWindow(std::shared_ptr<WhiteboardSession> whiteboardSession) {
return new QtWhiteboardWindow(whiteboardSession);
}
HighlightEditorWindow* QtUIFactory::createHighlightEditorWindow() {
- return new QtHighlightEditor(qtOnlySettings);
+ return new QtHighlightNotificationConfigDialog(qtOnlySettings);
}
BlockListEditorWidget *QtUIFactory::createBlockListEditorWidget() {
return new QtBlockListEditorWindow();
}
AdHocCommandWindow* QtUIFactory::createAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command) {
return new QtAdHocCommandWindow(command);
}
void QtUIFactory::showTabs() {
if (tabs) {
if (!tabs->isVisible()) {
tabs->show();
}
}
}
}
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,32 +1,32 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtWebKitChatView.h>
#include <QApplication>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QEventLoop>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QInputDialog>
#include <QKeyEvent>
#include <QMessageBox>
#include <QStackedWidget>
#include <QTimer>
#include <QVBoxLayout>
#include <QWebFrame>
#include <QWebSettings>
#include <QtDebug>
#include <Swiften/Base/FileSize.h>
#include <Swiften/Base/Log.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
@@ -451,155 +451,155 @@ void QtWebKitChatView::setMUCInvitationJoined(QString id) {
if (!buttonElement.isNull()) {
buttonElement.setAttribute("value", tr("Return to room"));
}
}
void QtWebKitChatView::askDesktopToOpenFile(const QString& filename) {
QFileInfo fileInfo(filename);
if (fileInfo.exists() && fileInfo.isFile()) {
QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
}
}
int QtWebKitChatView::getSnippetPositionByDate(const QDate& date) {
QWebElement message = webPage_->mainFrame()->documentElement().findFirst(".date" + date.toString(Qt::ISODate));
return message.geometry().top();
}
void QtWebKitChatView::resetTopInsertPoint() {
// TODO: Implement or refactor later.
SWIFT_LOG(error) << "Not yet implemented!" << std::endl;
}
std::string QtWebKitChatView::addMessage(
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, "", 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) {
QString ecsapeColor = QtUtilities::htmlEscape(P2QSTRING(text));
QString escapeBackground = QtUtilities::htmlEscape(P2QSTRING(background));
if (ecsapeColor.isEmpty()) {
ecsapeColor = "black";
}
if (escapeBackground.isEmpty()) {
escapeBackground = "yellow";
}
return QString("<span style=\"color: %1; background: %2\">").arg(ecsapeColor).arg(escapeBackground);
}
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) {
QString result;
for (const auto& part : message.getParts()) {
std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
std::shared_ptr<ChatWindow::ChatURIMessagePart> uriPart;
std::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart;
std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart;
if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
QString text = QtUtilities::htmlEscape(P2QSTRING(textPart->text));
text.replace("\n","<br/>");
result += text;
continue;
}
if ((uriPart = std::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(part))) {
QString uri = QtUtilities::htmlEscape(P2QSTRING(uriPart->target));
result += "<a href='" + uri + "' >" + uri + "</a>";
continue;
}
if ((emoticonPart = std::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) {
QString textStyle = showEmoticons_ ? "style='display:none'" : "";
QString imageStyle = showEmoticons_ ? "" : "style='display:none'";
result += "<span class='swift_emoticon_image' " + imageStyle + "><img src='" + P2QSTRING(emoticonPart->imagePath) + "'/></span><span class='swift_emoticon_text' " + textStyle + ">" + QtUtilities::htmlEscape(P2QSTRING(emoticonPart->alternativeText)) + "</span>";
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;
}
}
return result;
}
std::string QtWebKitChatView::addMessage(
const QString& message,
const std::string& senderName,
bool senderIsSelf,
std::shared_ptr<SecurityLabel> label,
const std::string& avatarPath,
const QString& style,
const boost::posix_time::ptime& time,
const HighlightAction& highlight,
ChatSnippet::Direction direction) {
QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
QString htmlString;
if (label) {
htmlString = QString("<span style=\"border: thin dashed grey; padding-left: .5em; padding-right: .5em; color: %1; background-color: %2; font-size: 90%; margin-right: .5em; \" class='swift_label'>").arg(QtUtilities::htmlEscape(P2QSTRING(label->getForegroundColor()))).arg(QtUtilities::htmlEscape(P2QSTRING(label->getBackgroundColor())));
htmlString += QString("%1</span> ").arg(QtUtilities::htmlEscape(P2QSTRING(label->getDisplayMarking())));
}
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>" ;
bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf);
QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.svg" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), direction));
previousMessageWasSelf_ = senderIsSelf;
previousSenderName_ = P2QSTRING(senderName);
previousMessageKind_ = PreviousMessageWasMessage;
return id;
}
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) {
return QtUtilities::htmlEscape(P2QSTRING(Base64::encode(createByteArray(Q2PSTRING(str)))));
}
static QString decodeButtonArgument(const QString& str) {
return P2QSTRING(byteArrayToString(Base64::decode(Q2PSTRING(str))));
}
QString QtWebKitChatView::buildChatWindowButton(const QString& name, const QString& id, const QString& arg1, const QString& arg2, const QString& arg3, const QString& arg4, const QString& arg5) {
QRegExp regex("[A-Za-z][A-Za-z0-9\\-\\_]+");
Q_ASSERT(regex.exactMatch(id));
QString html = QString("<input id='%2' type='submit' value='%1' onclick='chatwindow.buttonClicked(\"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\");' />").arg(name).arg(id).arg(encodeButtonArgument(arg1)).arg(encodeButtonArgument(arg2)).arg(encodeButtonArgument(arg3)).arg(encodeButtonArgument(arg4)).arg(encodeButtonArgument(arg5));
return html;
}
void QtWebKitChatView::resizeEvent(QResizeEvent* event) {
// This code ensures that if the user is scrolled all to the bottom of a chat view,
// the view stays scrolled to the bottom if the view is resized or if the message
// input widget becomes multi line.
if (isAtBottom_) {
scrollToBottom();
}
QWidget::resizeEvent(event);
}
std::string QtWebKitChatView::addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) {
SWIFT_LOG(debug) << "addFileTransfer" << std::endl;
QString ft_id = QString("ft%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
@@ -808,103 +808,103 @@ void QtWebKitChatView::handleVerticalScrollBarPositionChanged(double position) {
}
}
void QtWebKitChatView::addErrorMessage(const ChatWindow::ChatMessage& errorMessage) {
if (window_->isWidgetSelected()) {
window_->onAllMessagesRead();
}
QString errorMessageHTML(chatMessageToHTML(errorMessage));
std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
addMessageBottom(std::make_shared<SystemMessageSnippet>("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), ChatSnippet::getDirection(errorMessage)));
previousMessageWasSelf_ = false;
previousMessageKind_ = PreviousMessageWasSystem;
}
std::string QtWebKitChatView::addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) {
if (window_->isWidgetSelected()) {
window_->onAllMessagesRead();
}
QString messageHTML = chatMessageToHTML(message);
std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
addMessageBottom(std::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
previousMessageKind_ = PreviousMessageWasSystem;
return id;
}
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) {
replaceSystemMessage(chatMessageToHTML(message), P2QSTRING(id), timestampBehavior);
}
void QtWebKitChatView::replaceSystemMessage(const QString& newMessage, const QString& id, const ChatWindow::TimestampBehaviour timestampBehaviour) {
rememberScrolledToBottom();
QWebElement message = document_.findFirst("#" + id);
if (!message.isNull()) {
QWebElement replaceContent = message.findFirst("span.swift_message");
assert(!replaceContent.isNull());
QString old = replaceContent.toOuterXml();
replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
if (timestampBehaviour == ChatWindow::UpdateTimestamp) {
QWebElement replace = message.findFirst("span.swift_time");
assert(!replace.isNull());
replace.setInnerXml(ChatSnippet::timeToEscapedString(QDateTime::currentDateTime()));
}
}
else {
qWarning() << "Trying to replace element with id " << id << " but it's not there.";
}
}
void QtWebKitChatView::replaceMessage(const QString& message, const std::string& id, const boost::posix_time::ptime& time, const QString& style, const HighlightAction& highlight) {
if (!id.empty()) {
if (window_->isWidgetSelected()) {
window_->onAllMessagesRead();
}
QString messageHTML(message);
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));
}
else {
std::cerr << "Trying to replace a message with no id";
}
}
void QtWebKitChatView::addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) {
if (window_->isWidgetSelected()) {
window_->onAllMessagesRead();
}
QString messageHTML = chatMessageToHTML(message);
std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
addMessageBottom(std::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
previousMessageKind_ = PreviousMessageWasPresence;
}
void QtWebKitChatView::replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour timestampBehaviour) {
replaceLastMessage(chatMessageToHTML(message), timestampBehaviour);
}
void QtWebKitChatView::addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) {
if (window_->isWidgetSelected()) {
window_->onAllMessagesRead();
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 3512120..69e99e7 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -118,63 +118,63 @@ sources = [
"QtWebKitChatView.cpp",
"QtPlainChatView.cpp",
"QtChatTheme.cpp",
"QtChatTabs.cpp",
"QtChatTabsBase.cpp",
"QtChatTabsShortcutOnlySubstitute.cpp",
"QtSoundPlayer.cpp",
"QtSystemTray.cpp",
"QtCachedImageScaler.cpp",
"QtTabbable.cpp",
"QtTabWidget.cpp",
"QtTextEdit.cpp",
"QtXMLConsoleWidget.cpp",
"QtHistoryWindow.cpp",
"QtFileTransferListWidget.cpp",
"QtFileTransferListItemModel.cpp",
"QtAdHocCommandWindow.cpp",
"QtAdHocCommandWithJIDWindow.cpp",
"QtUtilities.cpp",
"QtBookmarkDetailWindow.cpp",
"QtAddBookmarkWindow.cpp",
"QtEditBookmarkWindow.cpp",
"QtEmojisGrid.cpp",
"QtEmojiCell.cpp",
"QtEmojisScroll.cpp",
"QtEmojisSelector.cpp",
"QtRecentEmojisGrid.cpp",
"QtContactEditWindow.cpp",
"QtContactEditWidget.cpp",
"QtSingleWindow.cpp",
- "QtHighlightEditor.cpp",
"QtColorToolButton.cpp",
"QtClosableLineEdit.cpp",
+ "QtHighlightNotificationConfigDialog.cpp",
"ChatSnippet.cpp",
"MessageSnippet.cpp",
"SystemMessageSnippet.cpp",
"QtElidingLabel.cpp",
"QtFormWidget.cpp",
"QtFormResultItemModel.cpp",
"QtLineEdit.cpp",
"QtJoinMUCWindow.cpp",
"QtConnectionSettingsWindow.cpp",
"Roster/RosterModel.cpp",
"Roster/QtTreeWidget.cpp",
"Roster/RosterDelegate.cpp",
"Roster/GroupItemDelegate.cpp",
"Roster/DelegateCommons.cpp",
"Roster/QtFilterWidget.cpp",
"Roster/QtRosterWidget.cpp",
"Roster/QtOccupantListWidget.cpp",
"Roster/RosterTooltip.cpp",
"EventViewer/EventModel.cpp",
"EventViewer/EventDelegate.cpp",
"EventViewer/TwoLineDelegate.cpp",
"EventViewer/QtEventWindow.cpp",
"EventViewer/QtEvent.cpp",
"ChatList/QtChatListWindow.cpp",
"ChatList/ChatListModel.cpp",
"ChatList/ChatListDelegate.cpp",
"ChatList/ChatListMUCItem.cpp",
"ChatList/ChatListRecentItem.cpp",
"ChatList/ChatListWhiteboardItem.cpp",
"MUCSearch/MUCSearchDelegate.cpp",
@@ -189,61 +189,64 @@ sources = [
"UserSearch/QtContactListWidget.cpp",
"UserSearch/QtSuggestingJIDInput.cpp",
"UserSearch/QtUserSearchFirstPage.cpp",
"UserSearch/QtUserSearchFirstMultiJIDPage.cpp",
"UserSearch/QtUserSearchFieldsPage.cpp",
"UserSearch/QtUserSearchResultsPage.cpp",
"UserSearch/QtUserSearchDetailsPage.cpp",
"UserSearch/QtUserSearchWindow.cpp",
"UserSearch/UserSearchModel.cpp",
"UserSearch/UserSearchDelegate.cpp",
"Whiteboard/FreehandLineItem.cpp",
"Whiteboard/GView.cpp",
"Whiteboard/TextDialog.cpp",
"Whiteboard/QtWhiteboardWindow.cpp",
"Whiteboard/ColorWidget.cpp",
"QtSubscriptionRequestWindow.cpp",
"QtRosterHeader.cpp",
"QtWebView.cpp",
"qrc_DefaultTheme.cc",
"qrc_Swift.cc",
"QtChatWindowJSBridge.cpp",
"QtMUCConfigurationWindow.cpp",
"QtAffiliationEditor.cpp",
"QtUISettingConstants.cpp",
"QtURLValidator.cpp",
"QtResourceHelper.cpp",
"QtSpellCheckHighlighter.cpp",
"QtUpdateFeedSelectionDialog.cpp",
"Trellis/QtDynamicGridLayout.cpp",
"Trellis/QtDNDTabBar.cpp",
- "Trellis/QtGridSelectionDialog.cpp"
+ "Trellis/QtGridSelectionDialog.cpp",
+ "QtCheckBoxStyledItemDelegate.cpp",
+ "QtColorSelectionStyledItemDelegate.cpp",
+ "QtSoundSelectionStyledItemDelegate.cpp"
]
if env["PLATFORM"] == "win32" :
sources.extend(["qrc_SwiftWindows.cc"])
# QtVCardWidget
sources.extend([
"QtVCardWidget/QtCloseButton.cpp",
"QtVCardWidget/QtRemovableItemDelegate.cpp",
"QtVCardWidget/QtResizableLineEdit.cpp",
"QtVCardWidget/QtTagComboBox.cpp",
"QtVCardWidget/QtVCardHomeWork.cpp",
"QtVCardWidget/QtVCardAddressField.cpp",
"QtVCardWidget/QtVCardAddressLabelField.cpp",
"QtVCardWidget/QtVCardBirthdayField.cpp",
"QtVCardWidget/QtVCardDescriptionField.cpp",
"QtVCardWidget/QtVCardInternetEMailField.cpp",
"QtVCardWidget/QtVCardJIDField.cpp",
"QtVCardWidget/QtVCardOrganizationField.cpp",
"QtVCardWidget/QtVCardPhotoAndNameFields.cpp",
"QtVCardWidget/QtVCardRoleField.cpp",
"QtVCardWidget/QtVCardTelephoneField.cpp",
"QtVCardWidget/QtVCardTitleField.cpp",
"QtVCardWidget/QtVCardURLField.cpp",
"QtVCardWidget/QtVCardGeneralField.cpp",
"QtVCardWidget/QtVCardWidget.cpp"
])
myenv.Uic4("QtVCardWidget/QtVCardPhotoAndNameFields.ui")
myenv.Uic4("QtVCardWidget/QtVCardWidget.ui")
@@ -284,61 +287,61 @@ if env["PLATFORM"] == "posix" :
"QtDBUSURIHandler.cpp",
]
if env["PLATFORM"] == "darwin" :
sources += ["CocoaApplicationActivateHelper.mm"]
sources += ["CocoaUIHelpers.mm"]
if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" :
swiftProgram = myenv.Program("Swift", sources)
else :
sources += ["QtCertificateViewerDialog.cpp"];
myenv.Uic4("QtCertificateViewerDialog.ui");
swiftProgram = myenv.Program("swift-im", sources)
if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" :
openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp")
else :
openURIProgram = []
myenv.Uic4("MUCSearch/QtMUCSearchWindow.ui")
myenv.Uic4("UserSearch/QtUserSearchWizard.ui")
myenv.Uic4("UserSearch/QtUserSearchFirstPage.ui")
myenv.Uic4("UserSearch/QtUserSearchFirstMultiJIDPage.ui")
myenv.Uic4("UserSearch/QtUserSearchFieldsPage.ui")
myenv.Uic4("UserSearch/QtUserSearchResultsPage.ui")
myenv.Uic4("QtBookmarkDetailWindow.ui")
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")
myenv.Qrc("DefaultTheme.qrc")
myenv.Qrc("Swift.qrc")
if env["PLATFORM"] == "win32" :
myenv.Qrc("SwiftWindows.qrc")
# Resources
commonResources = {
"": ["#/Swift/resources/sounds"]
}
## COPYING file generation
myenv["TEXTFILESUFFIX"] = ""
copying_files = [myenv.File("../../COPYING.gpl"), myenv.File("../../COPYING.thirdparty"), myenv.File("../../COPYING.dependencies")]
if env["PLATFORM"] == "darwin" and env["HAVE_SPARKLE"] :
copying_files.append(env["SPARKLE_COPYING"])
myenv.MyTextfile(target = "COPYING", source = copying_files, LINESEPARATOR = "\n\n========\n\n\n")
################################################################################
# Translation
################################################################################
# Collect available languages
translation_languages = []
for file in os.listdir(Dir("#/Swift/Translations").abspath) :