summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
@@ -15,6 +15,7 @@
#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>
@@ -81,6 +82,13 @@ void AdHocManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
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,5 +1,5 @@
/*
- * 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.
*/
@@ -37,11 +37,27 @@ QtFormWidget::QtFormWidget(Form::ref form, QWidget* parent) : QWidget(parent), f
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);
@@ -83,50 +99,55 @@ QListWidget* QtFormWidget::createList(FormField::ref field) {
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;
}
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,5 +1,5 @@
/*
- * 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.
*/
@@ -23,7 +23,7 @@ class QtFormWidget : public QWidget {
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);
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
@@ -40,6 +40,7 @@
#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)
@@ -50,7 +51,7 @@
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));
@@ -175,6 +176,11 @@ QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStr
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();
@@ -269,6 +275,10 @@ void QtMainWindow::handleChatUserActionTriggered(bool /*checked*/) {
uiEventStream_->send(event);
}
+void QtMainWindow::handleOtherAdHocActionTriggered() {
+ new QtAdHocCommandWithJIDWindow(uiEventStream_);
+}
+
void QtMainWindow::handleSignOutAction() {
loginMenus_.generalMenu->removeAction(toggleRequestDeliveryReceipts_);
onSignOutRequest();
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
@@ -39,7 +39,7 @@ namespace Swift {
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);
@@ -69,6 +69,7 @@ namespace Swift {
void handleEditProfileAction();
void handleAddUserActionTriggered(bool checked);
void handleChatUserActionTriggered(bool checked);
+ void handleOtherAdHocActionTriggered();
void handleAdHocActionTriggered(bool checked);
void handleEventCountUpdated(int count);
void handleChatCountUpdated(int count);
@@ -87,6 +88,7 @@ namespace Swift {
QAction* addUserAction_;
QAction* editUserAction_;
QAction* chatUserAction_;
+ QAction* otherAdHocAction_;
QAction* showOfflineAction_;
QAction* compactRosterAction_;
QAction* showEmoticonsAction_;
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
@@ -89,6 +89,7 @@ po::options_description QtSwift::getOptionsDescription() {
("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
@@ -162,6 +163,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa
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);
@@ -210,7 +212,7 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa
// 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_,
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
@@ -36,7 +36,7 @@
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);
}
@@ -81,7 +81,7 @@ FileTransferListWidget* QtUIFactory::createFileTransferListWidget() {
}
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;
}
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
@@ -32,7 +32,7 @@ namespace Swift {
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*);
@@ -73,5 +73,6 @@ namespace Swift {
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
@@ -119,6 +119,7 @@ sources = [
"QtFileTransferListWidget.cpp",
"QtFileTransferListItemModel.cpp",
"QtAdHocCommandWindow.cpp",
+ "QtAdHocCommandWithJIDWindow.cpp",
"QtUtilities.cpp",
"QtBookmarkDetailWindow.cpp",
"QtAddBookmarkWindow.cpp",