summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-05-19 11:18:52 (GMT)
committerSwift Review <review@swift.im>2014-07-09 10:19:41 (GMT)
commit05d9e618e4c756e50b633448f0546614a645a13d (patch)
tree5a05e5c2c939c240a58c4aa468af0806a7ed8822
parentacac7962ba04c083377f62f4265ecc754176f74e (diff)
downloadswift-contrib-05d9e618e4c756e50b633448f0546614a645a13d.zip
swift-contrib-05d9e618e4c756e50b633448f0546614a645a13d.tar.bz2
Add dialog to send AdHoc's to target specific JID's. Fix multi-item Form rendering.
Test-Information: Use AdHoc bot that presents a multi-item form and check that it is rendered correctly. Check that entering invalid JID and node parameters in the dialog do not cause malfunction. Check that canceling the JID prompt closes the dialog without sending any server commands. Change-Id: I10e6f4c7eccd1a35c8c885d548994b5f57fdbf66
-rw-r--r--Swift/Controllers/AdHocManager.cpp8
-rw-r--r--Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h21
-rw-r--r--Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp61
-rw-r--r--Swift/QtUI/QtAdHocCommandWithJIDWindow.h32
-rw-r--r--Swift/QtUI/QtFormWidget.cpp55
-rw-r--r--Swift/QtUI/QtFormWidget.h4
-rw-r--r--Swift/QtUI/QtMainWindow.cpp12
-rw-r--r--Swift/QtUI/QtMainWindow.h4
-rw-r--r--Swift/QtUI/QtSwift.cpp4
-rw-r--r--Swift/QtUI/QtUIFactory.cpp4
-rw-r--r--Swift/QtUI/QtUIFactory.h3
-rw-r--r--Swift/QtUI/SConscript1
12 files changed, 184 insertions, 25 deletions
diff --git a/Swift/Controllers/AdHocManager.cpp b/Swift/Controllers/AdHocManager.cpp
index 59e139b..b179ec6 100644
--- a/Swift/Controllers/AdHocManager.cpp
+++ b/Swift/Controllers/AdHocManager.cpp
@@ -1,86 +1,94 @@
/*
* Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/Controllers/AdHocManager.h>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h>
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
+#include <Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestAdHocUIEvent.h>
namespace Swift {
AdHocManager::AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow) : jid_(jid) {
iqRouter_ = iqRouter;
uiEventStream_ = uiEventStream;
mainWindow_ = mainWindow;
factory_ = factory;
uiEventStream_->onUIEvent.connect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
}
AdHocManager::~AdHocManager() {
uiEventStream_->onUIEvent.disconnect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
for (size_t i = 0; i < controllers_.size(); ++i) {
controllers_[i]->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controllers_[i]));
}
}
void AdHocManager::removeController(boost::shared_ptr<AdHocController> controller) {
controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller));
controllers_.erase(std::find(controllers_.begin(), controllers_.end(), controller));
}
void AdHocManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) {
if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::CommandsFeature)) {
if (discoItemsRequest_) {
discoItemsRequest_->onResponse.disconnect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
discoItemsRequest_.reset();
}
discoItemsRequest_ = GetDiscoItemsRequest::create(JID(jid_.getDomain()), DiscoInfo::CommandsFeature, iqRouter_);
discoItemsRequest_->onResponse.connect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
discoItemsRequest_->send();
} else {
mainWindow_->setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
}
}
void AdHocManager::setOnline(bool online) {
foreach (boost::shared_ptr<AdHocController> controller, controllers_) {
controller->setOnline(online);
}
}
void AdHocManager::handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error) {
std::vector<DiscoItems::Item> commands;
if (!error) {
foreach (DiscoItems::Item item, items->getItems()) {
if (item.getNode() != "http://isode.com/xmpp/commands#test") {
commands.push_back(item);
}
}
}
mainWindow_->setAvailableAdHocCommands(commands);
}
void AdHocManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
boost::shared_ptr<RequestAdHocUIEvent> adHocEvent = boost::dynamic_pointer_cast<RequestAdHocUIEvent>(event);
if (adHocEvent) {
boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocEvent->getCommand().getJID(), adHocEvent->getCommand().getNode(), iqRouter_);
boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command);
controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
controllers_.push_back(controller);
}
+ boost::shared_ptr<RequestAdHocWithJIDUIEvent> adHocJIDEvent = boost::dynamic_pointer_cast<RequestAdHocWithJIDUIEvent>(event);
+ if (!!adHocJIDEvent) {
+ boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocJIDEvent->getJID(), adHocJIDEvent->getNode(), iqRouter_);
+ boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command);
+ controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
+ controllers_.push_back(controller);
+ }
}
}
diff --git a/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h
new file mode 100644
index 0000000..2b1fcea
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Kevin Smith and Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include "Swift/Controllers/UIEvents/UIEvent.h"
+
+namespace Swift {
+ class RequestAdHocWithJIDUIEvent : public UIEvent {
+ public:
+ RequestAdHocWithJIDUIEvent(const JID& jid, const std::string& node) : jid_(jid), node_(node) {}
+ JID getJID() const { return jid_; }
+ std::string getNode() const { return node_; }
+ private:
+ JID jid_;
+ std::string node_;
+ };
+}
diff --git a/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp b/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp
new file mode 100644
index 0000000..7f33f77
--- /dev/null
+++ b/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010-2014 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <boost/bind.hpp>
+#include <QLabel>
+#include <QPushButton>
+#include <QBoxLayout>
+#include <QDialogButtonBox>
+#include <Swiften/Elements/Command.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h>
+#include <Swift/QtUI/QtAdHocCommandWithJIDWindow.h>
+#include <Swift/QtUI/QtFormWidget.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
+const int FormLayoutIndex = 1;
+
+namespace Swift {
+QtAdHocCommandWithJIDWindow::QtAdHocCommandWithJIDWindow(UIEventStream* uiEventStream) : uiEventStream_(uiEventStream) {
+ QVBoxLayout* hlayout = new QVBoxLayout(this);
+
+ QLabel* jidLabel = new QLabel("JID:", this);
+ hlayout->addWidget(jidLabel);
+ jid_ = new QLineEdit(this);
+ hlayout->addWidget(jid_);
+
+ QLabel* commandLabel = new QLabel("Command:", this);
+ hlayout->addWidget(commandLabel);
+ node_ = new QLineEdit(this);
+ hlayout->addWidget(node_);
+
+ QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
+ QPushButton* rejectButton = buttonBox->addButton("Cancel", QDialogButtonBox::RejectRole);
+ connect(rejectButton, SIGNAL(clicked()), this, SLOT(handleRejectClick()));
+ QPushButton* acceptButton = buttonBox->addButton("Complete", QDialogButtonBox::AcceptRole);
+ connect(acceptButton, SIGNAL(clicked()), this, SLOT(handleAcceptClick()));
+ hlayout->addWidget(buttonBox);
+
+ setLayout(hlayout);
+ show();
+}
+
+QtAdHocCommandWithJIDWindow::~QtAdHocCommandWithJIDWindow() {
+}
+
+void QtAdHocCommandWithJIDWindow::handleAcceptClick() {
+ const JID jid = JID(Q2PSTRING(jid_->text()));
+ const std::string node = Q2PSTRING(node_->text());
+ boost::shared_ptr<UIEvent> event(new RequestAdHocWithJIDUIEvent(jid, node));
+ uiEventStream_->send(event);
+ accept();
+}
+
+void QtAdHocCommandWithJIDWindow::handleRejectClick() {
+ reject();
+}
+
+}
diff --git a/Swift/QtUI/QtAdHocCommandWithJIDWindow.h b/Swift/QtUI/QtAdHocCommandWithJIDWindow.h
new file mode 100644
index 0000000..b168827
--- /dev/null
+++ b/Swift/QtUI/QtAdHocCommandWithJIDWindow.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010-2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <QDialog>
+#include <QLineEdit>
+
+#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h>
+
+class QBoxLayout;
+
+namespace Swift {
+ class UIEventStream;
+ class QtFormWidget;
+ class QtAdHocCommandWithJIDWindow : public QDialog {
+ Q_OBJECT
+ public:
+ QtAdHocCommandWithJIDWindow(UIEventStream* eventStream);
+ virtual ~QtAdHocCommandWithJIDWindow();
+ public slots:
+ void handleAcceptClick();
+ void handleRejectClick();
+ private:
+ UIEventStream* uiEventStream_;
+ QLineEdit* jid_;
+ QLineEdit* node_;
+ };
+}
diff --git a/Swift/QtUI/QtFormWidget.cpp b/Swift/QtUI/QtFormWidget.cpp
index 874c8a1..b4840e9 100644
--- a/Swift/QtUI/QtFormWidget.cpp
+++ b/Swift/QtUI/QtFormWidget.cpp
@@ -1,164 +1,185 @@
/*
- * Copyright (c) 2010-2013 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/QtUI/QtFormWidget.h>
#include <QGridLayout>
#include <QLabel>
#include <QListWidget>
#include <QLineEdit>
#include <QTextEdit>
#include <QCheckBox>
#include <QScrollArea>
#include <qdebug.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swiften/Base/foreach.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/smart_ptr/make_shared.hpp>
namespace Swift {
QtFormWidget::QtFormWidget(Form::ref form, QWidget* parent) : QWidget(parent), form_(form) {
QGridLayout* thisLayout = new QGridLayout(this);
int row = 0;
if (!form->getTitle().empty()) {
QLabel* instructions = new QLabel(("<b>" + form->getTitle() + "</b>").c_str(), this);
thisLayout->addWidget(instructions, row++, 0, 1, 2);
}
if (!form->getInstructions().empty()) {
QLabel* instructions = new QLabel(form->getInstructions().c_str(), this);
thisLayout->addWidget(instructions, row++, 0, 1, 2);
}
QScrollArea* scrollArea = new QScrollArea(this);
thisLayout->addWidget(scrollArea);
QWidget* scroll = new QWidget(this);
QGridLayout* layout = new QGridLayout(scroll);
- foreach (boost::shared_ptr<FormField> field, form->getFields()) {
- QWidget* widget = createWidget(field);
- if (widget) {
- layout->addWidget(new QLabel(field->getLabel().c_str(), this), row, 0);
- layout->addWidget(widget, row++, 1);
+ const std::vector<Form::FormItem> items = form->getItems();
+ if (items.empty()) { /* single item forms */
+ foreach (FormField::ref field, form->getFields()) {
+ QWidget* widget = createWidget(field, field->getType(), 0);
+ if (widget) {
+ layout->addWidget(new QLabel(field->getLabel().c_str(), this), row, 0);
+ layout->addWidget(widget, row++, 1);
+ }
+ }
+ } else { /* multi-item forms */
+ const Form::FormItem& headers = form->getFields();
+ for (size_t i = 0; i < items.size(); ++i) {
+ const Form::FormItem& item = items[i];
+ assert(item.size() == headers.size());
+ for (size_t j = 0; j < item.size(); ++j) {
+ QWidget* widget = createWidget(item[j], headers[j]->getType(), i);
+ if (widget) {
+ layout->addWidget(new QLabel(item[j]->getLabel().c_str(), this), row, 0);
+ layout->addWidget(widget, row++, 1);
+ }
+ }
}
}
scrollArea->setWidget(scroll);
scrollArea->setWidgetResizable(true);
setEditable(form->getType() != Form::CancelType && form->getType() != Form::ResultType);
}
QtFormWidget::~QtFormWidget() {
}
QListWidget* QtFormWidget::createList(FormField::ref field) {
QListWidget* listWidget = new QListWidget(this);
listWidget->setSortingEnabled(false);
listWidget->setSelectionMode(field->getType() == FormField::ListMultiType ? QAbstractItemView::MultiSelection : QAbstractItemView::SingleSelection);
std::vector<bool> selected;
/* if this is an editable form, use the 'options' list, otherwise use the 'values' list */
if (form_->getType() != Form::FormType) {
foreach (const std::string& value, field->getValues()) {
listWidget->addItem(P2QSTRING(value));
selected.push_back(false);
}
} else {
foreach (FormField::Option option, field->getOptions()) {
listWidget->addItem(option.label.c_str());
if (field->getType() == FormField::ListSingleType) {
selected.push_back(!field->getValues().empty() && option.value == field->getValues()[0]);
}
else if (field->getType() == FormField::ListMultiType) {
std::string text = option.value;
selected.push_back(std::find(field->getValues().begin(), field->getValues().end(), text) != field->getValues().end());
}
}
}
for (int i = 0; i < listWidget->count(); i++) {
QListWidgetItem* item = listWidget->item(i);
item->setSelected(selected[i]);
}
return listWidget;
}
-QWidget* QtFormWidget::createWidget(FormField::ref field) {
+QWidget* QtFormWidget::createWidget(FormField::ref field, const FormField::Type type, const size_t index) {
QWidget* widget = NULL;
- if (field->getType() == FormField::BooleanType) {
+ if (type == FormField::BooleanType) {
QCheckBox* checkWidget = new QCheckBox(this);
checkWidget->setCheckState(field->getBoolValue() ? Qt::Checked : Qt::Unchecked);
widget = checkWidget;
}
- if (field->getType() == FormField::FixedType) {
+ if (type == FormField::FixedType) {
QString value = field->getFixedValue().c_str();
widget = new QLabel(value, this);
}
- if (field->getType() == FormField::ListSingleType) {
+ if (type == FormField::ListSingleType) {
widget = createList(field);
}
- if (field->getType() == FormField::TextMultiType) {
+ if (type == FormField::TextMultiType) {
QString value = field->getTextMultiValue().c_str();
QTextEdit* textWidget = new QTextEdit(this);
textWidget->setPlainText(value);
widget = textWidget;
}
- if (field->getType() == FormField::TextPrivateType) {
+ if (type == FormField::TextPrivateType) {
QString value = field->getTextPrivateValue().c_str();
QLineEdit* lineWidget = new QLineEdit(value, this);
lineWidget->setEchoMode(QLineEdit::Password);
widget = lineWidget;
}
- if (field->getType() == FormField::TextSingleType) {
+ if (type == FormField::TextSingleType) {
QString value = field->getTextSingleValue().c_str();
widget = new QLineEdit(value, this);
}
- if (field->getType() == FormField::JIDSingleType) {
+ if (type == FormField::JIDSingleType) {
QString value = field->getJIDSingleValue().toString().c_str();
widget = new QLineEdit(value, this);
}
- if (field->getType() == FormField::JIDMultiType) {
+ if (type == FormField::JIDMultiType) {
QString text = boost::join(field->getValues(), "\n").c_str();
QTextEdit* textWidget = new QTextEdit(this);
textWidget->setPlainText(text);
widget = textWidget;
}
- if (field->getType() == FormField::ListMultiType) {
+ if (type == FormField::ListMultiType) {
widget = createList(field);
}
- fields_[field->getName()] = widget;
+ std::string indexString;
+ if (index) {
+ /* for multi-item forms we need to distinguish between the different rows */
+ indexString = boost::lexical_cast<std::string>(index);
+ }
+ fields_[field->getName() + indexString] = widget;
return widget;
}
Form::ref QtFormWidget::getCompletedForm() {
Form::ref result(new Form(Form::SubmitType));
foreach (boost::shared_ptr<FormField> field, form_->getFields()) {
boost::shared_ptr<FormField> resultField = boost::make_shared<FormField>(field->getType());
if (field->getType() == FormField::BooleanType) {
resultField->setBoolValue(qobject_cast<QCheckBox*>(fields_[field->getName()])->checkState() == Qt::Checked);
}
if (field->getType() == FormField::FixedType || field->getType() == FormField::HiddenType) {
resultField->addValue(field->getValues().empty() ? "" : field->getValues()[0]);
}
if (field->getType() == FormField::ListSingleType) {
QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]);
if (listWidget->selectedItems().size() > 0) {
int i = listWidget->row(listWidget->selectedItems()[0]);
resultField->addValue(field->getOptions()[i].value);
}
}
if (field->getType() == FormField::TextMultiType) {
QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]);
QString string = widget->toPlainText();
if (!string.isEmpty()) {
resultField->setTextMultiValue(Q2PSTRING(string));
}
}
if (field->getType() == FormField::TextPrivateType || field->getType() == FormField::TextSingleType || field->getType() == FormField::JIDSingleType) {
QLineEdit* widget = qobject_cast<QLineEdit*>(fields_[field->getName()]);
QString string = widget->text();
if (!string.isEmpty()) {
resultField->addValue(Q2PSTRING(string));
}
}
if (field->getType() == FormField::JIDMultiType) {
diff --git a/Swift/QtUI/QtFormWidget.h b/Swift/QtUI/QtFormWidget.h
index c7aae73..f58ff4b 100644
--- a/Swift/QtUI/QtFormWidget.h
+++ b/Swift/QtUI/QtFormWidget.h
@@ -1,34 +1,34 @@
/*
- * Copyright (c) 2011 Kevin Smith
+ * Copyright (c) 2011-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <QWidget>
#include <map>
#include <Swiften/Elements/Form.h>
class QListWidget;
namespace Swift {
class QtFormWidget : public QWidget {
Q_OBJECT
public:
QtFormWidget(Form::ref form, QWidget* parent = NULL);
virtual ~QtFormWidget();
Form::ref getCompletedForm();
void setEditable(bool editable);
private:
- QWidget* createWidget(FormField::ref field);
+ QWidget* createWidget(FormField::ref field, const FormField::Type type, const size_t index);
QListWidget* createList(FormField::ref field);
template<class T> void setEnabled(QWidget* rawWidget, bool editable);
template<class T> void setEditable(QWidget* rawWidget, bool editable);
std::map<std::string, QWidget*> fields_;
Form::ref form_;
};
}
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index 31a8234..1db8c77 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -8,81 +8,82 @@
#include <boost/optional.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <QBoxLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QListWidget>
#include <QListWidgetItem>
#include <QPushButton>
#include <QMenuBar>
#include <QToolBar>
#include <QAction>
#include <QTabWidget>
#include <Swiften/Base/Platform.h>
#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestHistoryUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAdHocUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/QtUI/Roster/QtFilterWidget.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtTabWidget.h>
#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtLoginWindow.h>
#include <Swift/QtUI/Roster/QtRosterWidget.h>
#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/QtAdHocCommandWithJIDWindow.h>
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <Swift/QtUI/CocoaUIHelpers.h>
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
#include <Swift/QtUI/WinUIHelpers.h>
#else
#include <Swift/QtUI/QtCertificateViewerDialog.h>
#endif
namespace Swift {
-QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist) : QWidget(), MainWindow(false), loginMenus_(loginMenus) {
+QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist, bool enableAdHocCommandOnJID) : QWidget(), MainWindow(false), loginMenus_(loginMenus) {
uiEventStream_ = uiEventStream;
settings_ = settings;
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
mainLayout->setContentsMargins(0,0,0,0);
mainLayout->setSpacing(0);
meView_ = new QtRosterHeader(settings, statusCache, this);
mainLayout->addWidget(meView_);
connect(meView_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleStatusChanged(StatusShow::Type, const QString&)));
connect(meView_, SIGNAL(onEditProfileRequest()), this, SLOT(handleEditProfileRequest()));
connect(meView_, SIGNAL(onShowCertificateInfo()), this, SLOT(handleShowCertificateInfo()));
tabs_ = new QtTabWidget(this);
#if QT_VERSION >= 0x040500
tabs_->setDocumentMode(true);
#endif
tabs_->setTabPosition(QTabWidget::South);
mainLayout->addWidget(tabs_);
contactsTabWidget_ = new QWidget(this);
contactsTabWidget_->setContentsMargins(0, 0, 0, 0);
QBoxLayout *contactTabLayout = new QBoxLayout(QBoxLayout::TopToBottom, contactsTabWidget_);
contactsTabWidget_->setLayout(contactTabLayout);
contactTabLayout->setSpacing(0);
contactTabLayout->setContentsMargins(0, 0, 0, 0);
treeWidget_ = new QtRosterWidget(uiEventStream_, settings_, this);
contactTabLayout->addWidget(treeWidget_);
new QtFilterWidget(this, treeWidget_, uiEventStream_, contactTabLayout);
tabs_->addTab(contactsTabWidget_, tr("&Contacts"));
eventWindow_ = new QtEventWindow(uiEventStream_);
connect(eventWindow_, SIGNAL(onNewEventCountUpdated(int)), this, SLOT(handleEventCountUpdated(int)));
@@ -143,70 +144,75 @@ QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStr
//compactRosterAction_->setChecked(false);
//connect(compactRosterAction_, SIGNAL(toggled(bool)), uiPreferences_, SLOT(setCompactRosters(bool)));
//viewMenu->addAction(compactRosterAction_);
QMenu* actionsMenu = new QMenu(tr("&Actions"), this);
menus_.push_back(actionsMenu);
QAction* editProfileAction = new QAction(tr("Edit &Profile…"), this);
connect(editProfileAction, SIGNAL(triggered()), SLOT(handleEditProfileAction()));
actionsMenu->addAction(editProfileAction);
QAction* joinMUCAction = new QAction(tr("Enter &Room…"), this);
connect(joinMUCAction, SIGNAL(triggered()), SLOT(handleJoinMUCAction()));
actionsMenu->addAction(joinMUCAction);
#ifdef SWIFT_EXPERIMENTAL_HISTORY
QAction* viewLogsAction = new QAction(tr("&View History…"), this);
connect(viewLogsAction, SIGNAL(triggered()), SLOT(handleViewLogsAction()));
actionsMenu->addAction(viewLogsAction);
#endif
openBlockingListEditor_ = new QAction(tr("Edit &Blocking List…"), this);
connect(openBlockingListEditor_, SIGNAL(triggered()), SLOT(handleEditBlockingList()));
actionsMenu->addAction(openBlockingListEditor_);
openBlockingListEditor_->setVisible(false);
addUserAction_ = new QAction(tr("&Add Contact…"), this);
addUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
addUserAction_->setShortcutContext(Qt::ApplicationShortcut);
connect(addUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleAddUserActionTriggered(bool)));
actionsMenu->addAction(addUserAction_);
editUserAction_ = new QAction(tr("&Edit Selected Contact…"), this);
connect(editUserAction_, SIGNAL(triggered(bool)), treeWidget_, SLOT(handleEditUserActionTriggered(bool)));
actionsMenu->addAction(editUserAction_);
editUserAction_->setEnabled(false);
chatUserAction_ = new QAction(tr("Start &Chat…"), this);
chatUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
chatUserAction_->setShortcutContext(Qt::ApplicationShortcut);
connect(chatUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleChatUserActionTriggered(bool)));
actionsMenu->addAction(chatUserAction_);
+ if (enableAdHocCommandOnJID) {
+ otherAdHocAction_ = new QAction(tr("Run Other Command"), this);
+ connect(otherAdHocAction_, SIGNAL(triggered()), this, SLOT(handleOtherAdHocActionTriggered()));
+ actionsMenu->addAction(otherAdHocAction_);
+ }
serverAdHocMenu_ = new QMenu(tr("Run Server Command"), this);
actionsMenu->addMenu(serverAdHocMenu_);
actionsMenu->addSeparator();
QAction* signOutAction = new QAction(tr("&Sign Out"), this);
connect(signOutAction, SIGNAL(triggered()), SLOT(handleSignOutAction()));
actionsMenu->addAction(signOutAction);
toggleRequestDeliveryReceipts_ = new QAction(tr("&Request Delivery Receipts"), this);
toggleRequestDeliveryReceipts_->setCheckable(true);
toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
connect(toggleRequestDeliveryReceipts_, SIGNAL(toggled(bool)), SLOT(handleToggleRequestDeliveryReceipts(bool)));
QList< QAction* > generalMenuActions = loginMenus_.generalMenu->actions();
loginMenus_.generalMenu->insertAction(generalMenuActions.at(generalMenuActions.count()-2),toggleRequestDeliveryReceipts_);
treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QAction::setEnabled, editUserAction_, _1));
setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
QAction* adHocAction = new QAction(tr("Collecting commands..."), this);
adHocAction->setEnabled(false);
serverAdHocMenu_->addAction(adHocAction);
serverAdHocCommandActions_.append(adHocAction);
settings_->onSettingChanged.connect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
}
QtMainWindow::~QtMainWindow() {
settings_->onSettingChanged.disconnect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
}
void QtMainWindow::handleTabChanged(int index) {
settings_->storeSetting(QtUISettingConstants::CURRENT_ROSTER_TAB, index);
}
void QtMainWindow::handleToggleRequestDeliveryReceipts(bool enabled) {
@@ -237,70 +243,74 @@ void QtMainWindow::handleEditProfileRequest() {
uiEventStream_->send(boost::make_shared<RequestProfileEditorUIEvent>());
}
void QtMainWindow::handleEventCountUpdated(int count) {
QColor eventTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
int eventIndex = 2;
tabs_->tabBar()->setTabTextColor(eventIndex, eventTabColor);
QString text = tr("&Notices");
if (count > 0) {
text += QString(" (%1)").arg(count);
}
tabs_->setTabText(eventIndex, text);
}
void QtMainWindow::handleChatCountUpdated(int count) {
QColor chatTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
int chatIndex = 1;
tabs_->tabBar()->setTabTextColor(chatIndex, chatTabColor);
QString text = tr("&Chats");
if (count > 0) {
text += QString(" (%1)").arg(count);
}
tabs_->setTabText(chatIndex, text);
}
void QtMainWindow::handleAddUserActionTriggered(bool /*checked*/) {
boost::shared_ptr<UIEvent> event(new RequestAddUserDialogUIEvent());
uiEventStream_->send(event);
}
void QtMainWindow::handleChatUserActionTriggered(bool /*checked*/) {
boost::shared_ptr<UIEvent> event(new RequestChatWithUserDialogUIEvent());
uiEventStream_->send(event);
}
+void QtMainWindow::handleOtherAdHocActionTriggered() {
+ new QtAdHocCommandWithJIDWindow(uiEventStream_);
+}
+
void QtMainWindow::handleSignOutAction() {
loginMenus_.generalMenu->removeAction(toggleRequestDeliveryReceipts_);
onSignOutRequest();
}
void QtMainWindow::handleEditProfileAction() {
uiEventStream_->send(boost::make_shared<RequestProfileEditorUIEvent>());
}
void QtMainWindow::handleJoinMUCAction() {
uiEventStream_->send(boost::make_shared<RequestJoinMUCUIEvent>());
}
void QtMainWindow::handleViewLogsAction() {
uiEventStream_->send(boost::make_shared<RequestHistoryUIEvent>());
}
void QtMainWindow::handleStatusChanged(StatusShow::Type showType, const QString &statusMessage) {
onChangeStatusRequest(showType, Q2PSTRING(statusMessage));
}
void QtMainWindow::handleSettingChanged(const std::string& settingPath) {
if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) {
handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
}
if (settingPath == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
}
if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
}
if (settingPath == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
}
}
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index f1f6900..84fab15 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -7,100 +7,102 @@
#pragma once
#include <vector>
#include <QWidget>
#include <QMenu>
#include <QList>
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
#include <Swift/QtUI/QtRosterHeader.h>
#include <Swift/QtUI/EventViewer/QtEventWindow.h>
#include <Swift/QtUI/ChatList/QtChatListWindow.h>
#include <Swift/QtUI/QtLoginWindow.h>
class QComboBox;
class QLineEdit;
class QPushButton;
class QToolBar;
class QAction;
class QMenu;
class QTabWidget;
namespace Swift {
class QtRosterWidget;
class TreeWidget;
class UIEventStream;
class QtTabWidget;
class SettingsProvider;
class QtUIPreferences;
class StatusCache;
class QtMainWindow : public QWidget, public MainWindow {
Q_OBJECT
public:
- QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist);
+ QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist, bool enableAdHocCommandOnJID);
virtual ~QtMainWindow();
std::vector<QMenu*> getMenus() {return menus_;}
void setMyNick(const std::string& name);
void setMyJID(const JID& jid);
void setMyAvatarPath(const std::string& path);
void setMyStatusText(const std::string& status);
void setMyStatusType(StatusShow::Type type);
void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact);
void setConnecting();
void setStreamEncryptionStatus(bool tlsInPlaceAndValid);
void openCertificateDialog(const std::vector<Certificate::ref>& chain);
static void openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent);
QtEventWindow* getEventWindow();
QtChatListWindow* getChatListWindow();
void setRosterModel(Roster* roster);
void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands);
void setBlockingCommandAvailable(bool isAvailable);
private slots:
void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
void handleSettingChanged(const std::string& settingPath);
void handleCompactRosterToggled(bool);
void handleShowOfflineToggled(bool);
void handleShowEmoticonsToggled(bool);
void handleJoinMUCAction();
void handleViewLogsAction();
void handleSignOutAction();
void handleEditProfileAction();
void handleAddUserActionTriggered(bool checked);
void handleChatUserActionTriggered(bool checked);
+ void handleOtherAdHocActionTriggered();
void handleAdHocActionTriggered(bool checked);
void handleEventCountUpdated(int count);
void handleChatCountUpdated(int count);
void handleEditProfileRequest();
void handleTabChanged(int index);
void handleToggleRequestDeliveryReceipts(bool enabled);
void handleShowCertificateInfo();
void handleEditBlockingList();
private:
SettingsProvider* settings_;
QtLoginWindow::QtMenus loginMenus_;
std::vector<QMenu*> menus_;
QtRosterWidget* treeWidget_;
QtRosterHeader* meView_;
QAction* addUserAction_;
QAction* editUserAction_;
QAction* chatUserAction_;
+ QAction* otherAdHocAction_;
QAction* showOfflineAction_;
QAction* compactRosterAction_;
QAction* showEmoticonsAction_;
QAction* openBlockingListEditor_;
QAction* toggleRequestDeliveryReceipts_;
QMenu* serverAdHocMenu_;
QtTabWidget* tabs_;
QComboBox* tabBarCombo_;
QWidget* contactsTabWidget_;
QWidget* eventsTabWidget_;
QtEventWindow* eventWindow_;
QtChatListWindow* chatListWindow_;
UIEventStream* uiEventStream_;
std::vector<DiscoItems::Item> serverAdHocCommands_;
QList<QAction*> serverAdHocCommandActions_;
};
}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index 183f64d..d2224ba 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -57,70 +57,71 @@
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <SwifTools/Dock/MacOSXDock.h>
#else
#include <SwifTools/Dock/NullDock.h>
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
#include <Swift/QtUI/QtURIHandler.h>
#elif defined(SWIFTEN_PLATFORM_WIN32)
#include <SwifTools/URIHandler/NullURIHandler.h>
#else
#include <Swift/QtUI/QtDBUSURIHandler.h>
#endif
namespace Swift{
#if defined(SWIFTEN_PLATFORM_MACOSX)
//#define SWIFT_APPCAST_URL "http://swift.im/appcast/swift-mac-dev.xml"
#else
//#define SWIFT_APPCAST_URL ""
#endif
po::options_description QtSwift::getOptionsDescription() {
po::options_description result("Options");
result.add_options()
("debug", "Turn on debug logging")
("help", "Show this help message")
("version", "Show version information")
("netbook-mode", "Use netbook mode display (unsupported)")
("no-tabs", "Don't manage chat windows in tabs (unsupported)")
("latency-debug", "Use latency debugging (unsupported)")
("multi-account", po::value<int>()->default_value(1), "Number of accounts to open windows for (unsupported)")
("start-minimized", "Don't show the login/roster window at startup")
+ ("enable-jid-adhocs", "Enable AdHoc commands to custom JID's.")
#if QT_VERSION >= 0x040800
("language", po::value<std::string>(), "Use a specific language, instead of the system-wide one")
#endif
;
return result;
}
XMLSettingsProvider* QtSwift::loadSettingsFile(const QString& fileName) {
QFile configFile(fileName);
if (configFile.exists() && configFile.open(QIODevice::ReadOnly)) {
QString xmlString;
while (!configFile.atEnd()) {
QByteArray line = configFile.readLine();
xmlString += line + "\n";
}
return new XMLSettingsProvider(Q2PSTRING(xmlString));
}
return new XMLSettingsProvider("");
}
void QtSwift::loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons) {
QFile file(fileName);
if (file.exists() && file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
QString line = file.readLine();
line.replace("\n", "");
line.replace("\r", "");
QStringList tokens = line.split(" ");
if (tokens.size() == 2) {
QString emoticonFile = tokens[1];
if (!emoticonFile.startsWith(":/") && !emoticonFile.startsWith("qrc:/")) {
emoticonFile = "file://" + emoticonFile;
}
emoticons[Q2PSTRING(tokens[0])] = Q2PSTRING(emoticonFile);
}
@@ -130,119 +131,120 @@ void QtSwift::loadEmoticonsFile(const QString& fileName, std::map<std::string, s
QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMainThreadCaller_), autoUpdater_(NULL), idleDetector_(&idleQuerier_, networkFactories_.getTimerFactory(), 1000) {
QCoreApplication::setApplicationName(SWIFT_APPLICATION_NAME);
QCoreApplication::setOrganizationName(SWIFT_ORGANIZATION_NAME);
QCoreApplication::setOrganizationDomain(SWIFT_ORGANIZATION_DOMAIN);
QCoreApplication::setApplicationVersion(buildVersion);
qtSettings_ = new QtSettingsProvider();
xmlSettings_ = loadSettingsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "system-settings.xml")));
settingsHierachy_ = new SettingsProviderHierachy();
settingsHierachy_->addProviderToTopOfStack(xmlSettings_);
settingsHierachy_->addProviderToTopOfStack(qtSettings_);
std::map<std::string, std::string> emoticons;
loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons);
loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons);
if (options.count("netbook-mode")) {
splitter_ = new QtSingleWindow(qtSettings_);
} else {
splitter_ = NULL;
}
int numberOfAccounts = 1;
try {
numberOfAccounts = options["multi-account"].as<int>();
} catch (...) {
/* This seems to fail on a Mac when the .app is launched directly (the usual path).*/
numberOfAccounts = 1;
}
if (options.count("debug")) {
Log::setLogLevel(Swift::Log::debug);
}
+ bool enableAdHocCommandOnJID = options.count("enable-jid-adhocs") > 0;
tabs_ = options.count("no-tabs") && !splitter_ ? NULL : new QtChatTabs(splitter_ != NULL);
bool startMinimized = options.count("start-minimized") > 0;
applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME);
storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider());
certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider());
chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, "");
soundPlayer_ = new QtSoundPlayer(applicationPathProvider_);
// Ugly, because the dock depends on the tray, but the temporary
// multi-account hack creates one tray per account.
QtSystemTray* systemTray = new QtSystemTray();
systemTrays_.push_back(systemTray);
#if defined(HAVE_GROWL)
notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME);
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon());
#elif defined(SWIFTEN_PLATFORM_LINUX)
notifier_ = new FreeDesktopNotifier(SWIFT_APPLICATION_NAME);
#else
notifier_ = new NullNotifier();
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
dock_ = new MacOSXDock(&cocoaApplication_);
#else
dock_ = new NullDock();
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
uriHandler_ = new QtURIHandler();
#elif defined(SWIFTEN_PLATFORM_WIN32)
uriHandler_ = new NullURIHandler();
#else
uriHandler_ = new QtDBUSURIHandler();
#endif
statusCache_ = new StatusCache(applicationPathProvider_);
if (splitter_) {
splitter_->show();
}
for (int i = 0; i < numberOfAccounts; i++) {
if (i > 0) {
// Don't add the first tray (see note above)
systemTrays_.push_back(new QtSystemTray());
}
- QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, startMinimized, !emoticons.empty());
+ QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, startMinimized, !emoticons.empty(), enableAdHocCommandOnJID);
uiFactories_.push_back(uiFactory);
MainController* mainController = new MainController(
&clientMainThreadCaller_,
&networkFactories_,
uiFactory,
settingsHierachy_,
systemTrays_[i],
soundPlayer_,
storagesFactory_,
certificateStorageFactory_,
dock_,
notifier_,
uriHandler_,
&idleDetector_,
emoticons,
options.count("latency-debug") > 0);
mainControllers_.push_back(mainController);
}
// PlatformAutoUpdaterFactory autoUpdaterFactory;
// if (autoUpdaterFactory.isSupported()) {
// autoUpdater_ = autoUpdaterFactory.createAutoUpdater(SWIFT_APPCAST_URL);
// autoUpdater_->checkForUpdates();
// }
}
QtSwift::~QtSwift() {
delete autoUpdater_;
foreach (QtUIFactory* factory, uiFactories_) {
delete factory;
}
foreach (MainController* controller, mainControllers_) {
delete controller;
}
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index afd2a9e..701170c 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -4,116 +4,116 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/QtUI/QtUIFactory.h>
#include <QSplitter>
#include <Swift/QtUI/QtXMLConsoleWidget.h>
#include <Swift/QtUI/QtChatTabs.h>
#include <Swift/QtUI/QtMainWindow.h>
#include <Swift/QtUI/QtLoginWindow.h>
#include <Swift/QtUI/QtSystemTray.h>
#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtMainWindow.h>
#include <Swift/QtUI/QtChatWindow.h>
#include <Swift/QtUI/QtJoinMUCWindow.h>
#include <Swift/QtUI/QtChatWindowFactory.h>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h>
#include <Swift/QtUI/UserSearch/QtUserSearchWindow.h>
#include <Swift/QtUI/QtProfileWindow.h>
#include <Swift/QtUI/QtContactEditWindow.h>
#include <Swift/QtUI/QtAdHocCommandWindow.h>
#include <Swift/QtUI/QtFileTransferListWidget.h>
#include <Swift/QtUI/QtHighlightEditorWidget.h>
#include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h>
#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtHistoryWindow.h>
#include <Swiften/Whiteboard/WhiteboardSession.h>
#include <Swift/QtUI/QtSingleWindow.h>
#include <Swift/QtUI/QtBlockListEditorWindow.h>
namespace Swift {
-QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist) {
+QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) {
chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE);
historyFontSize_ = settings->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE);
}
XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() {
QtXMLConsoleWidget* widget = new QtXMLConsoleWidget();
tabs->addTab(widget);
if (!tabs->isVisible()) {
tabs->show();
}
widget->show();
return widget;
}
HistoryWindow* QtUIFactory::createHistoryWindow(UIEventStream* uiEventStream) {
QtHistoryWindow* window = new QtHistoryWindow(settings, uiEventStream);
tabs->addTab(window);
if (!tabs->isVisible()) {
tabs->show();
}
connect(window, SIGNAL(fontResized(int)), this, SLOT(handleHistoryWindowFontResized(int)));
window->handleFontResized(historyFontSize_);
window->show();
return window;
}
void QtUIFactory::handleHistoryWindowFontResized(int size) {
historyFontSize_ = size;
settings->storeSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE, size);
}
FileTransferListWidget* QtUIFactory::createFileTransferListWidget() {
QtFileTransferListWidget* widget = new QtFileTransferListWidget();
tabs->addTab(widget);
if (!tabs->isVisible()) {
tabs->show();
}
widget->show();
return widget;
}
MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) {
- lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), statusCache, emoticonsExist_);
+ lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), statusCache, emoticonsExist_, enableAdHocCommandOnJID_);
return lastMainWindow;
}
LoginWindow* QtUIFactory::createLoginWindow(UIEventStream* eventStream) {
loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_);
if (netbookSplitter) {
netbookSplitter->insertAtFront(loginWindow);
}
connect(systemTray, SIGNAL(clicked()), loginWindow, SLOT(toggleBringToFront()));
#ifndef SWIFT_MOBILE
QVariant loginWindowGeometryVariant = qtOnlySettings->getQSettings()->value("loginWindowGeometry");
if (loginWindowGeometryVariant.isValid()) {
loginWindow->restoreGeometry(loginWindowGeometryVariant.toByteArray());
}
connect(loginWindow, SIGNAL(geometryChanged()), this, SLOT(handleLoginWindowGeometryChanged()));
if (startMinimized) loginWindow->hide();
#endif
return loginWindow;
}
void QtUIFactory::handleLoginWindowGeometryChanged() {
qtOnlySettings->getQSettings()->setValue("loginWindowGeometry", loginWindow->saveGeometry());
}
EventWindow* QtUIFactory::createEventWindow() {
return lastMainWindow->getEventWindow();
}
ChatListWindow* QtUIFactory::createChatListWindow(UIEventStream*) {
return lastMainWindow->getChatListWindow();
}
MUCSearchWindow* QtUIFactory::createMUCSearchWindow() {
return new QtMUCSearchWindow();
diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h
index 721aa76..4c50572 100644
--- a/Swift/QtUI/QtUIFactory.h
+++ b/Swift/QtUI/QtUIFactory.h
@@ -1,77 +1,78 @@
/*
* Copyright (c) 2010-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <QObject>
#include <QPointer>
#include <Swift/Controllers/UIInterfaces/UIFactory.h>
class QSplitter;
namespace Swift {
class QtSettingsProvider;
class SettingsProviderHierachy;
class QtChatTabs;
class QtSystemTray;
class QtLoginWindow;
class QtMainWindow;
class QtChatTheme;
class QtChatWindowFactory;
class QtChatWindow;
class TimerFactory;
class historyWindow_;
class WhiteboardSession;
class StatusCache;
class QtSingleWindow;
class QtUIFactory : public QObject, public UIFactory {
Q_OBJECT
public:
- QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist);
+ QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID);
virtual XMLConsoleWidget* createXMLConsoleWidget();
virtual HistoryWindow* createHistoryWindow(UIEventStream*);
virtual MainWindow* createMainWindow(UIEventStream* eventStream);
virtual LoginWindow* createLoginWindow(UIEventStream* eventStream);
virtual EventWindow* createEventWindow();
virtual ChatListWindow* createChatListWindow(UIEventStream*);
virtual MUCSearchWindow* createMUCSearchWindow();
virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups);
virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream);
virtual ProfileWindow* createProfileWindow();
virtual ContactEditWindow* createContactEditWindow();
virtual FileTransferListWidget* createFileTransferListWidget();
virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession);
virtual HighlightEditorWidget* createHighlightEditorWidget();
virtual BlockListEditorWidget* createBlockListEditorWidget();
virtual AdHocCommandWindow* createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command);
private slots:
void handleLoginWindowGeometryChanged();
void handleChatWindowFontResized(int);
void handleHistoryWindowFontResized(int);
private:
SettingsProviderHierachy* settings;
QtSettingsProvider* qtOnlySettings;
QtChatTabs* tabs;
QtSingleWindow* netbookSplitter;
QtSystemTray* systemTray;
QtChatWindowFactory* chatWindowFactory;
TimerFactory* timerFactory_;
QtMainWindow* lastMainWindow;
QtLoginWindow* loginWindow;
StatusCache* statusCache;
std::vector<QPointer<QtChatWindow> > chatWindows;
bool startMinimized;
int chatFontSize;
int historyFontSize_;
bool emoticonsExist_;
+ bool enableAdHocCommandOnJID_;
};
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index 53dbea9..dd7d0c3 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -87,70 +87,71 @@ myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateDefaultTheme(myenv.Dir("#
sources = [
"main.cpp",
"QtAboutWidget.cpp",
"QtSpellCheckerWindow.cpp",
"QtAvatarWidget.cpp",
"QtUIFactory.cpp",
"QtChatWindowFactory.cpp",
"QtClickableLabel.cpp",
"QtLoginWindow.cpp",
"QtMainWindow.cpp",
"QtProfileWindow.cpp",
"QtBlockListEditorWindow.cpp",
"QtNameWidget.cpp",
"QtSettingsProvider.cpp",
"QtStatusWidget.cpp",
"QtScaledAvatarCache.cpp",
"QtSwift.cpp",
"QtURIHandler.cpp",
"QtChatWindow.cpp",
"QtChatView.cpp",
"QtWebKitChatView.cpp",
"QtPlainChatView.cpp",
"QtChatTheme.cpp",
"QtChatTabs.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",
"QtContactEditWindow.cpp",
"QtContactEditWidget.cpp",
"QtSingleWindow.cpp",
"QtHighlightEditorWidget.cpp",
"QtHighlightRulesItemModel.cpp",
"QtHighlightRuleWidget.cpp",
"QtColorToolButton.cpp",
"QtClosableLineEdit.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/QtTreeWidgetItem.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",