diff options
Diffstat (limited to 'Swift/QtUI')
-rw-r--r-- | Swift/QtUI/QtCheckBoxStyledItemDelegate.cpp | 51 | ||||
-rw-r--r-- | Swift/QtUI/QtCheckBoxStyledItemDelegate.h | 26 | ||||
-rw-r--r-- | Swift/QtUI/QtColorSelectionStyledItemDelegate.cpp | 56 | ||||
-rw-r--r-- | Swift/QtUI/QtColorSelectionStyledItemDelegate.h | 26 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightEditor.cpp | 568 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightEditor.h | 76 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightEditor.ui | 466 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightNotificationConfigDialog.cpp | 246 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightNotificationConfigDialog.h | 41 | ||||
-rw-r--r-- | Swift/QtUI/QtHighlightNotificationConfigDialog.ui | 537 | ||||
-rw-r--r-- | Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp | 111 | ||||
-rw-r--r-- | Swift/QtUI/QtSoundSelectionStyledItemDelegate.h | 23 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 4 | ||||
-rw-r--r-- | Swift/QtUI/QtWebKitChatView.cpp | 20 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 9 |
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>&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>&Background</string> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="groupBox_4"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Sound Action</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QRadioButton" name="noSoundRadio"> - <property name="text"> - <string>No Sound</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="defaultSoundRadio"> - <property name="text"> - <string>Default Sound</string> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="customSoundRadio"> - <property name="text"> - <string>Custom Sound</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_6"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLineEdit" name="soundFile"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="readOnly"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="soundFileButton"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>Swift::QtColorToolButton</class> - <extends>QToolButton</extends> - <header>QtColorToolButton.h</header> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp b/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp new file mode 100644 index 0000000..c4e64ab --- /dev/null +++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2016-2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/QtHighlightNotificationConfigDialog.h> + +#include <Swiften/Base/Log.h> + +#include <Swift/Controllers/Highlighting/HighlightManager.h> + +#include <Swift/QtUI/QtCheckBoxStyledItemDelegate.h> +#include <Swift/QtUI/QtColorSelectionStyledItemDelegate.h> +#include <Swift/QtUI/QtSoundSelectionStyledItemDelegate.h> +#include <Swift/QtUI/QtSwiftUtil.h> + +namespace Swift { + +QtHighlightNotificationConfigDialog::QtHighlightNotificationConfigDialog(QtSettingsProvider* settings, QWidget* parent) : QDialog(parent), settings_(settings) { + ui_.setupUi(this); + + // setup custom delegates for checkboxes, color selection, and sound selection + ui_.userHighlightTreeWidget->setItemDelegateForColumn(1, new QtColorSelectionStyledItemDelegate(this)); + ui_.userHighlightTreeWidget->setItemDelegateForColumn(2, new QtColorSelectionStyledItemDelegate(this)); + ui_.userHighlightTreeWidget->setItemDelegateForColumn(3, new QtSoundSelectionStyledItemDelegate(this)); + ui_.userHighlightTreeWidget->setItemDelegateForColumn(4, new QtCheckBoxStyledItemDelegate(this)); + + ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(1, new QtCheckBoxStyledItemDelegate(this)); + ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(2, new QtColorSelectionStyledItemDelegate(this)); + ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(3, new QtColorSelectionStyledItemDelegate(this)); + ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(4, new QtSoundSelectionStyledItemDelegate(this)); + ui_.keywordHighlightTreeWidget->setItemDelegateForColumn(5, new QtCheckBoxStyledItemDelegate(this)); + + // user highlight edit slots + connect(ui_.addUserHighlightPushButton, &QPushButton::clicked, [&](bool) { + auto item = new QTreeWidgetItem(); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + item->setData(0, Qt::EditRole, ""); + item->setData(1, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#000000")); + item->setData(2, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#ffff00")); + item->setData(3, Qt::EditRole, ""); + item->setData(4, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(true)); + ui_.userHighlightTreeWidget->addTopLevelItem(item); + }); + connect(ui_.removeUserHighlightPushButton, &QPushButton::clicked, [&](bool) { + auto currentItem = ui_.userHighlightTreeWidget->currentItem(); + if (currentItem) { + ui_.userHighlightTreeWidget->takeTopLevelItem(ui_.userHighlightTreeWidget->indexOfTopLevelItem(currentItem)); + } + }); + connect(ui_.userHighlightTreeWidget, &QTreeWidget::currentItemChanged, [&](QTreeWidgetItem* current, QTreeWidgetItem* ) { + ui_.removeUserHighlightPushButton->setEnabled(current != 0); + }); + + // keyword highlight edit slots + connect(ui_.addKeywordHighlightPushButton, &QPushButton::clicked, [&](bool) { + auto item = new QTreeWidgetItem(); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + item->setData(0, Qt::EditRole, ""); + item->setData(1, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(false)); + item->setData(2, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#000000")); + item->setData(3, QtColorSelectionStyledItemDelegate::DATA_ROLE, QColor("#ffff00")); + item->setData(4, Qt::EditRole, ""); + item->setData(5, QtCheckBoxStyledItemDelegate::DATA_ROLE, QVariant(true)); + ui_.keywordHighlightTreeWidget->addTopLevelItem(item); + }); + connect(ui_.removeKeywordHighlightPushButton, &QPushButton::clicked, [&](bool) { + auto currentItem = ui_.keywordHighlightTreeWidget->currentItem(); + if (currentItem) { + ui_.keywordHighlightTreeWidget->takeTopLevelItem(ui_.keywordHighlightTreeWidget->indexOfTopLevelItem(currentItem)); + } + }); + connect(ui_.keywordHighlightTreeWidget, &QTreeWidget::currentItemChanged, [&](QTreeWidgetItem* current, QTreeWidgetItem* ) { + ui_.removeKeywordHighlightPushButton->setEnabled(current != 0); + }); + + // setup slots for main dialog buttons + connect(ui_.buttonBox, &QDialogButtonBox::clicked, [&](QAbstractButton* clickedButton) { + if (clickedButton == ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults)) { + if (highlightManager_) { + highlightManager_->resetToDefaultConfiguration(); + setHighlightConfigurationToDialog(*highlightManager_->getConfiguration()); + } + } + }); + connect(this, &QDialog::accepted, [&]() { + if (highlightManager_) { + highlightManager_->setConfiguration(getHighlightConfigurationFromDialog()); + } + }); +} + +QtHighlightNotificationConfigDialog::~QtHighlightNotificationConfigDialog() { +} + +void QtHighlightNotificationConfigDialog::show() { + if (highlightManager_) { + setHighlightConfigurationToDialog(*(highlightManager_->getConfiguration())); + } + QWidget::show(); + QWidget::activateWindow(); +} + +void QtHighlightNotificationConfigDialog::setHighlightManager(HighlightManager* highlightManager) { + highlightManager_ = highlightManager; +} + +void QtHighlightNotificationConfigDialog::setContactSuggestions(const std::vector<Contact::ref>& /*suggestions*/) { + +} + +HighlightConfiguration QtHighlightNotificationConfigDialog::getHighlightConfigurationFromDialog() const { + auto qtColorToOptionalString = [&](const QColor& color) { + boost::optional<std::string> colorString; + if (color.isValid()) { + colorString = Q2PSTRING(color.name(QColor::HexRgb)); + } + return colorString; + }; + + auto getHighlightActionFromWidgetItem = [&](const QTreeWidgetItem* item, int startingColumn) { + HighlightAction action; + + action.setFrontColor(qtColorToOptionalString(item->data(startingColumn, QtColorSelectionStyledItemDelegate::DATA_ROLE).value<QColor>())); + action.setBackColor(qtColorToOptionalString(item->data(startingColumn + 1, QtColorSelectionStyledItemDelegate::DATA_ROLE).value<QColor>())); + + std::string soundFilePath = Q2PSTRING(item->data(startingColumn + 2, Qt::EditRole).toString()); + if (soundFilePath == "defaultSound") { + action.setSoundFilePath(boost::optional<std::string>("")); + } + else if (soundFilePath.empty()) { + action.setSoundFilePath(boost::optional<std::string>()); + } + else { + action.setSoundFilePath(boost::optional<std::string>(soundFilePath)); + } + + action.setSystemNotificationEnabled(item->data(startingColumn + 3, QtCheckBoxStyledItemDelegate::DATA_ROLE).toBool()); + return action; + }; + + HighlightConfiguration uiConfiguration; + + // contact highlights + for (int i = 0; i < ui_.userHighlightTreeWidget->topLevelItemCount(); i++) { + auto item = ui_.userHighlightTreeWidget->topLevelItem(i); + HighlightConfiguration::ContactHighlight contactHighlight; + contactHighlight.name = Q2PSTRING(item->data(0, Qt::EditRole).toString()); + contactHighlight.action = getHighlightActionFromWidgetItem(item, 1); + uiConfiguration.contactHighlights.push_back(contactHighlight); + } + + // keyword highlights + for (int i = 0; i < ui_.keywordHighlightTreeWidget->topLevelItemCount(); i++) { + auto item = ui_.keywordHighlightTreeWidget->topLevelItem(i); + HighlightConfiguration::KeywordHightlight keywordHighlight; + keywordHighlight.keyword = Q2PSTRING(item->data(0, Qt::EditRole).toString()); + keywordHighlight.matchCaseSensitive = item->data(1, QtCheckBoxStyledItemDelegate::DATA_ROLE).toBool(); + keywordHighlight.action = getHighlightActionFromWidgetItem(item, 2); + uiConfiguration.keywordHighlights.push_back(keywordHighlight); + } + + // general configuration + uiConfiguration.playSoundOnIncomingDirectMessages = ui_.playSoundOnDirectMessagesCheckBox->isChecked(); + uiConfiguration.showNotificationOnIncomingDirectMessages = ui_.notificationOnDirectMessagesCheckBox->isChecked(); + uiConfiguration.playSoundOnIncomingGroupchatMessages = ui_.playSoundOnGroupMessagesCheckBox->isChecked(); + uiConfiguration.showNotificationOnIncomingGroupchatMessages = ui_.notificationOnGroupMessagesCheckBox->isChecked(); + + uiConfiguration.ownMentionAction.setFrontColor(qtColorToOptionalString(ui_.mentionTextColorColorButton->getColor())); + uiConfiguration.ownMentionAction.setBackColor(qtColorToOptionalString(ui_.mentionBackgroundColorButton->getColor())); + uiConfiguration.ownMentionAction.setSoundFilePath(ui_.playSoundOnMentionCheckBox->isChecked() ? boost::optional<std::string>("") : boost::optional<std::string>()); + uiConfiguration.ownMentionAction.setSystemNotificationEnabled(ui_.notificationOnMentionCheckBox->isChecked()); + return uiConfiguration; +} + +void QtHighlightNotificationConfigDialog::setHighlightConfigurationToDialog(const HighlightConfiguration& config) { + auto optionalStringToQtColor = [](const boost::optional<std::string>& colorString) { + QColor qtColor; + if (colorString) { + qtColor = QColor(P2QSTRING(colorString.get_value_or(std::string("")))); + } + return qtColor; + }; + + auto optionalSoundPathStringToQString = [](const boost::optional<std::string>& soundPath) { + QString ret; + if (soundPath) { + if (soundPath.get_value_or("").empty()) { + ret = "defaultSound"; + } + else { + ret = P2QSTRING(soundPath.get_value_or("")); + } + } + return ret; + }; + + auto setHighlightActionOnTreeWidgetItem = [&](QTreeWidgetItem* item, int startingColumn, const HighlightAction& action) { + item->setData(startingColumn, QtColorSelectionStyledItemDelegate::DATA_ROLE, optionalStringToQtColor(action.getFrontColor())); + item->setData(startingColumn + 1, QtColorSelectionStyledItemDelegate::DATA_ROLE, optionalStringToQtColor(action.getBackColor())); + item->setData(startingColumn + 2, Qt::DisplayRole, P2QSTRING(action.getSoundFilePath().get_value_or(std::string("")))); + item->setData(startingColumn + 2, Qt::EditRole, optionalSoundPathStringToQString(action.getSoundFilePath())); + item->setData(startingColumn + 3, QtCheckBoxStyledItemDelegate::DATA_ROLE, action.isSystemNotificationEnabled()); + }; + + // contact highlights + ui_.userHighlightTreeWidget->clear(); + for (const auto& contactHighlight : config.contactHighlights) { + auto item = new QTreeWidgetItem(); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); + item->setData(0, Qt::DisplayRole, P2QSTRING(contactHighlight.name)); + item->setData(0, Qt::EditRole, P2QSTRING(contactHighlight.name)); + + setHighlightActionOnTreeWidgetItem(item, 1, contactHighlight.action); + + ui_.userHighlightTreeWidget->addTopLevelItem(item); + } + + // keyword highlights + ui_.keywordHighlightTreeWidget->clear(); + for (const auto& keywordHighlight : config.keywordHighlights) { + auto item = new QTreeWidgetItem(); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item->setData(0, Qt::DisplayRole, P2QSTRING(keywordHighlight.keyword)); + item->setData(0, Qt::EditRole, P2QSTRING(keywordHighlight.keyword)); + item->setData(1, QtCheckBoxStyledItemDelegate::DATA_ROLE, keywordHighlight.matchCaseSensitive); + + setHighlightActionOnTreeWidgetItem(item, 2, keywordHighlight.action); + + ui_.keywordHighlightTreeWidget->addTopLevelItem(item); + } + + // general configuration + ui_.playSoundOnDirectMessagesCheckBox->setChecked(config.playSoundOnIncomingDirectMessages); + ui_.notificationOnDirectMessagesCheckBox->setChecked(config.showNotificationOnIncomingDirectMessages); + ui_.playSoundOnGroupMessagesCheckBox->setChecked(config.playSoundOnIncomingGroupchatMessages); + ui_.notificationOnGroupMessagesCheckBox->setChecked(config.showNotificationOnIncomingGroupchatMessages); + + ui_.mentionTextColorColorButton->setColor(optionalStringToQtColor(config.ownMentionAction.getFrontColor())); + ui_.mentionBackgroundColorButton->setColor(optionalStringToQtColor(config.ownMentionAction.getBackColor())); + ui_.playSoundOnMentionCheckBox->setChecked(config.ownMentionAction.getSoundFilePath().is_initialized()); + ui_.notificationOnMentionCheckBox->setChecked(config.ownMentionAction.isSystemNotificationEnabled()); +} + +} diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.h b/Swift/QtUI/QtHighlightNotificationConfigDialog.h new file mode 100644 index 0000000..03044eb --- /dev/null +++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016-2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swift/Controllers/Highlighting/HighlightConfiguration.h> +#include <Swift/Controllers/UIInterfaces/HighlightEditorWindow.h> + +#include <Swift/QtUI/ui_QtHighlightNotificationConfigDialog.h> + +namespace Swift { + + class QtSettingsProvider; + class QtSuggestingJIDInput; + + class QtHighlightNotificationConfigDialog : public QDialog, public HighlightEditorWindow { + Q_OBJECT + + public: + QtHighlightNotificationConfigDialog(QtSettingsProvider* settings, QWidget* parent = nullptr); + virtual ~QtHighlightNotificationConfigDialog(); + + virtual void show(); + virtual void setHighlightManager(HighlightManager* highlightManager); + virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions); + + private: + HighlightConfiguration getHighlightConfigurationFromDialog() const; + void setHighlightConfigurationToDialog(const HighlightConfiguration& config); + + private: + Ui::QtHighlightNotificationConfigDialog ui_; + QtSettingsProvider* settings_; + HighlightManager* highlightManager_ = nullptr; + QtSuggestingJIDInput* jid_ = nullptr; + }; + +} diff --git a/Swift/QtUI/QtHighlightNotificationConfigDialog.ui b/Swift/QtUI/QtHighlightNotificationConfigDialog.ui new file mode 100644 index 0000000..7074ad8 --- /dev/null +++ b/Swift/QtUI/QtHighlightNotificationConfigDialog.ui @@ -0,0 +1,537 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>QtHighlightNotificationConfigDialog</class> + <widget class="QDialog" name="QtHighlightNotificationConfigDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>629</width> + <height>515</height> + </rect> + </property> + <property name="windowTitle"> + <string>Highlight and Notification Configuration</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <property name="modal"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Highlight messages from these people</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="spacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QTreeWidget" name="userHighlightTreeWidget"> + <property name="tabKeyNavigation"> + <bool>true</bool> + </property> + <property name="showDropIndicator" stdset="0"> + <bool>false</bool> + </property> + <property name="dragEnabled"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + <property name="defaultDropAction"> + <enum>Qt::MoveAction</enum> + </property> + <property name="indentation"> + <number>0</number> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="animated"> + <bool>true</bool> + </property> + <property name="headerHidden"> + <bool>false</bool> + </property> + <property name="expandsOnDoubleClick"> + <bool>false</bool> + </property> + <attribute name="headerCascadingSectionResizes"> + <bool>false</bool> + </attribute> + <attribute name="headerDefaultSectionSize"> + <number>80</number> + </attribute> + <attribute name="headerHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="headerMinimumSectionSize"> + <number>15</number> + </attribute> + <column> + <property name="text"> + <string>User</string> + </property> + </column> + <column> + <property name="text"> + <string>Text color</string> + </property> + </column> + <column> + <property name="text"> + <string>Background color</string> + </property> + </column> + <column> + <property name="text"> + <string>Play sound</string> + </property> + </column> + <column> + <property name="text"> + <string>Create notification</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <property name="spacing"> + <number>12</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="addUserHighlightPushButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>1</width> + <height>1</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>13</pointsize> + <weight>50</weight> + <italic>false</italic> + <bold>false</bold> + <underline>false</underline> + <strikeout>false</strikeout> + <kerning>true</kerning> + </font> + </property> + <property name="text"> + <string>+</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeUserHighlightPushButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Highlight messages containing these keywords</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <item> + <widget class="QTreeWidget" name="keywordHighlightTreeWidget"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>300</height> + </size> + </property> + <property name="tabKeyNavigation"> + <bool>true</bool> + </property> + <property name="showDropIndicator" stdset="0"> + <bool>false</bool> + </property> + <property name="dragEnabled"> + <bool>true</bool> + </property> + <property name="dragDropMode"> + <enum>QAbstractItemView::InternalMove</enum> + </property> + <property name="defaultDropAction"> + <enum>Qt::MoveAction</enum> + </property> + <property name="indentation"> + <number>0</number> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="animated"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Keyword</string> + </property> + </column> + <column> + <property name="text"> + <string>Match case sensitive</string> + </property> + </column> + <column> + <property name="text"> + <string>Text color</string> + </property> + </column> + <column> + <property name="text"> + <string>Background color</string> + </property> + </column> + <column> + <property name="text"> + <string>Play sound</string> + </property> + </column> + <column> + <property name="text"> + <string>Create notification</string> + </property> + </column> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <property name="spacing"> + <number>12</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="addKeywordHighlightPushButton"> + <property name="maximumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="text"> + <string>+</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeKeywordHighlightPushButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="maximumSize"> + <size> + <width>26</width> + <height>26</height> + </size> + </property> + <property name="text"> + <string>-</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>General notification settings</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <item row="3" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="Swift::QtColorToolButton" name="mentionBackgroundColorButton"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Highlight background color on own mention</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="notificationOnGroupMessagesCheckBox"> + <property name="text"> + <string>Create notification on incoming group messages</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="notificationOnMentionCheckBox"> + <property name="text"> + <string>Create notification when my name is mentioned</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QCheckBox" name="playSoundOnDirectMessagesCheckBox"> + <property name="text"> + <string>Play sound on incoming direct messages</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="playSoundOnGroupMessagesCheckBox"> + <property name="text"> + <string>Play sound on incoming group messages</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="notificationOnDirectMessagesCheckBox"> + <property name="text"> + <string>Create notification on incoming direct messages</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="playSoundOnMentionCheckBox"> + <property name="text"> + <string>Play sound when my name is mentioned</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="Swift::QtColorToolButton" name="mentionTextColorColorButton"> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Highlight text color on own mention</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set> + </property> + <property name="centerButtons"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>Swift::QtColorToolButton</class> + <extends>QToolButton</extends> + <header>QtColorToolButton.h</header> + </customwidget> + </customwidgets> + <tabstops> + <tabstop>userHighlightTreeWidget</tabstop> + <tabstop>addUserHighlightPushButton</tabstop> + <tabstop>removeUserHighlightPushButton</tabstop> + <tabstop>keywordHighlightTreeWidget</tabstop> + <tabstop>addKeywordHighlightPushButton</tabstop> + <tabstop>removeKeywordHighlightPushButton</tabstop> + <tabstop>playSoundOnDirectMessagesCheckBox</tabstop> + <tabstop>notificationOnDirectMessagesCheckBox</tabstop> + <tabstop>playSoundOnGroupMessagesCheckBox</tabstop> + <tabstop>notificationOnGroupMessagesCheckBox</tabstop> + <tabstop>playSoundOnMentionCheckBox</tabstop> + <tabstop>notificationOnMentionCheckBox</tabstop> + <tabstop>mentionTextColorColorButton</tabstop> + <tabstop>mentionBackgroundColorButton</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>QtHighlightNotificationConfigDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>QtHighlightNotificationConfigDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp new file mode 100644 index 0000000..3811004 --- /dev/null +++ b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/QtSoundSelectionStyledItemDelegate.h> + +#include <QApplication> +#include <QComboBox> +#include <QEvent> +#include <QFileDialog> +#include <QMenu> +#include <QMouseEvent> +#include <QPainter> +#include <QStyle> +#include <QStyleOptionComboBox> + +#include <Swiften/Base/Log.h> + +#include <Swift/QtUI/QtSwiftUtil.h> + +namespace Swift { + +QtSoundSelectionStyledItemDelegate::QtSoundSelectionStyledItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { + +} + +void QtSoundSelectionStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + // draw item selected background + painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base()); + + auto editRoleString = index.data(Qt::EditRole).toString(); + + // draw combo box + QStyleOptionComboBox opt; + opt.rect = option.rect; + opt.rect.setHeight(opt.rect.height() + 2); + opt.state = QStyle::State_Active | QStyle::State_Enabled; + if (editRoleString.isEmpty()) { + opt.currentText = tr("No sound"); + } + else if (editRoleString == "defaultSound") { + opt.currentText = tr("Default sound"); + } + else { + opt.currentText = editRoleString; + } + + painter->save(); + QFont smallFont; + smallFont.setPointSize(smallFont.pointSize() - 3); + painter->setFont(smallFont); + + QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &opt, painter); + QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &opt, painter); + painter->restore(); +} + +bool QtSoundSelectionStyledItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& /*option*/, const QModelIndex& index) { + if (event->type() == QEvent::MouseButtonRelease) { + auto mouseEvent = dynamic_cast<QMouseEvent*>(event); + assert(mouseEvent); + auto editRoleString = index.data(Qt::EditRole).toString(); + + auto popUpMenu = new QMenu(); + + auto noSound = popUpMenu->addAction(tr("No sound")); + auto defaultSound = popUpMenu->addAction(tr("Default sound")); + QAction* customSoundFile = nullptr; + QAction* selectedAction = nullptr; + if (editRoleString.isEmpty()) { + selectedAction = noSound; + } + else if (editRoleString == "defaultSound") { + selectedAction = defaultSound; + } + else { + customSoundFile = popUpMenu->addAction(editRoleString); + selectedAction = customSoundFile; + } + if (selectedAction) { + selectedAction->setCheckable(true); + selectedAction->setChecked(true); + } + auto chooseSoundFile = popUpMenu->addAction(tr("Choose sound fileā¦")); + + selectedAction = popUpMenu->exec(mouseEvent->globalPos(), selectedAction); + + if (selectedAction == defaultSound) { + model->setData(index, "defaultSound", Qt::EditRole); + } + else if (customSoundFile && (selectedAction == customSoundFile)) { + model->setData(index, customSoundFile->text(), Qt::EditRole); + } + else if (selectedAction == noSound) { + model->setData(index, "", Qt::EditRole); + } + else if (selectedAction == chooseSoundFile) { + auto newPath = QFileDialog::getOpenFileName(0, tr("Choose notification sound file"), "", tr("WAV Files (*.wav)")); + if (!newPath.isEmpty()) { + model->setData(index, newPath, Qt::EditRole); + } + } + + delete popUpMenu; + } + return true; +} + +}; diff --git a/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h new file mode 100644 index 0000000..fabf668 --- /dev/null +++ b/Swift/QtUI/QtSoundSelectionStyledItemDelegate.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <QStyledItemDelegate> + +namespace Swift { + +class QtSoundSelectionStyledItemDelegate : public QStyledItemDelegate { + public: + QtSoundSelectionStyledItemDelegate(QObject* parent = nullptr); + + virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const; + + protected: + virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index); +}; + +} diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index 16952a0..ece29ec 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -23,7 +23,7 @@ #include <Swift/QtUI/QtChatWindowFactory.h> #include <Swift/QtUI/QtContactEditWindow.h> #include <Swift/QtUI/QtFileTransferListWidget.h> -#include <Swift/QtUI/QtHighlightEditor.h> +#include <Swift/QtUI/QtHighlightNotificationConfigDialog.h> #include <Swift/QtUI/QtHistoryWindow.h> #include <Swift/QtUI/QtJoinMUCWindow.h> #include <Swift/QtUI/QtLoginWindow.h> @@ -169,7 +169,7 @@ WhiteboardWindow* QtUIFactory::createWhiteboardWindow(std::shared_ptr<Whiteboard } HighlightEditorWindow* QtUIFactory::createHighlightEditorWindow() { - return new QtHighlightEditor(qtOnlySettings); + return new QtHighlightNotificationConfigDialog(qtOnlySettings); } BlockListEditorWidget *QtUIFactory::createBlockListEditorWidget() { diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp index 6fe9397..9aeef24 100644 --- a/Swift/QtUI/QtWebKitChatView.cpp +++ b/Swift/QtUI/QtWebKitChatView.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016 Isode Limited. + * Copyright (c) 2010-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -478,7 +478,7 @@ std::string QtWebKitChatView::addMessage( std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { - return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message)); + return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, message.getHighlightActionSender(), ChatSnippet::getDirection(message)); } QString QtWebKitChatView::getHighlightSpanStart(const std::string& text, const std::string& background) { @@ -494,7 +494,7 @@ QString QtWebKitChatView::getHighlightSpanStart(const std::string& text, const s } QString QtWebKitChatView::getHighlightSpanStart(const HighlightAction& highlight) { - return getHighlightSpanStart(highlight.getTextColor(), highlight.getTextBackground()); + return getHighlightSpanStart(highlight.getFrontColor().get_value_or(""), highlight.getBackColor().get_value_or("")); } QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& message) { @@ -523,7 +523,7 @@ QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& messa continue; } if ((highlightPart = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) { - QString spanStart = getHighlightSpanStart(highlightPart->action.getTextColor(), highlightPart->action.getTextBackground()); + QString spanStart = getHighlightSpanStart(highlightPart->action.getFrontColor().get_value_or(""), highlightPart->action.getBackColor().get_value_or("")); result += spanStart + QtUtilities::htmlEscape(P2QSTRING(highlightPart->text)) + "</span>"; continue; } @@ -554,7 +554,7 @@ std::string QtWebKitChatView::addMessage( QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">"; QString styleSpanEnd = style == "" ? "" : "</span>"; - bool highlightWholeMessage = highlight.highlightWholeMessage() && highlight.getTextBackground() != "" && highlight.getTextColor() != ""; + bool highlightWholeMessage = highlight.getFrontColor() || highlight.getBackColor(); QString highlightSpanStart = highlightWholeMessage ? getHighlightSpanStart(highlight) : ""; QString highlightSpanEnd = highlightWholeMessage ? "</span>" : ""; htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ; @@ -572,7 +572,7 @@ std::string QtWebKitChatView::addMessage( } std::string QtWebKitChatView::addAction(const ChatWindow::ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { - return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message)); + return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getHighlightActionSender(), ChatSnippet::getDirection(message)); } static QString encodeButtonArgument(const QString& str) { @@ -835,11 +835,11 @@ std::string QtWebKitChatView::addSystemMessage(const ChatWindow::ChatMessage& me } void QtWebKitChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) { - replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", message.getFullMessageHighlightAction()); + replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", message.getHighlightActionSender()); } void QtWebKitChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) { - replaceMessage(chatMessageToHTML(message), id, time, "", message.getFullMessageHighlightAction()); + replaceMessage(chatMessageToHTML(message), id, time, "", message.getHighlightActionSender()); } void QtWebKitChatView::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, ChatWindow::TimestampBehaviour timestampBehavior) { @@ -876,8 +876,8 @@ void QtWebKitChatView::replaceMessage(const QString& message, const std::string& QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">"; QString styleSpanEnd = style == "" ? "" : "</span>"; - QString highlightSpanStart = highlight.highlightWholeMessage() ? getHighlightSpanStart(highlight) : ""; - QString highlightSpanEnd = highlight.highlightWholeMessage() ? "</span>" : ""; + QString highlightSpanStart = (highlight.getFrontColor() || highlight.getBackColor()) ? getHighlightSpanStart(highlight) : ""; + QString highlightSpanEnd = (highlight.getFrontColor() || highlight.getBackColor()) ? "</span>" : ""; messageHTML = styleSpanStart + highlightSpanStart + messageHTML + highlightSpanEnd + styleSpanEnd; replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time)); diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 3512120..69e99e7 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -145,9 +145,9 @@ sources = [ "QtContactEditWindow.cpp", "QtContactEditWidget.cpp", "QtSingleWindow.cpp", - "QtHighlightEditor.cpp", "QtColorToolButton.cpp", "QtClosableLineEdit.cpp", + "QtHighlightNotificationConfigDialog.cpp", "ChatSnippet.cpp", "MessageSnippet.cpp", "SystemMessageSnippet.cpp", @@ -216,7 +216,10 @@ sources = [ "QtUpdateFeedSelectionDialog.cpp", "Trellis/QtDynamicGridLayout.cpp", "Trellis/QtDNDTabBar.cpp", - "Trellis/QtGridSelectionDialog.cpp" + "Trellis/QtGridSelectionDialog.cpp", + "QtCheckBoxStyledItemDelegate.cpp", + "QtColorSelectionStyledItemDelegate.cpp", + "QtSoundSelectionStyledItemDelegate.cpp" ] if env["PLATFORM"] == "win32" : @@ -311,7 +314,7 @@ myenv.Uic4("QtAffiliationEditor.ui") myenv.Uic4("QtJoinMUCWindow.ui") myenv.Uic4("QtHistoryWindow.ui") myenv.Uic4("QtConnectionSettings.ui") -myenv.Uic4("QtHighlightEditor.ui") +myenv.Uic4("QtHighlightNotificationConfigDialog.ui") myenv.Uic4("QtBlockListEditorWindow.ui") myenv.Uic4("QtSpellCheckerWindow.ui") myenv.Uic4("QtUpdateFeedSelectionDialog.ui") |