diff options
| author | Richard Maudsley <richard.maudsley@isode.com> | 2014-05-19 11:18:52 (GMT) |
|---|---|---|
| committer | Swift Review <review@swift.im> | 2014-07-09 10:19:41 (GMT) |
| commit | 05d9e618e4c756e50b633448f0546614a645a13d (patch) | |
| tree | 5a05e5c2c939c240a58c4aa468af0806a7ed8822 /Swift/QtUI | |
| parent | acac7962ba04c083377f62f4265ecc754176f74e (diff) | |
| download | swift-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
Diffstat (limited to 'Swift/QtUI')
| -rw-r--r-- | Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp | 61 | ||||
| -rw-r--r-- | Swift/QtUI/QtAdHocCommandWithJIDWindow.h | 32 | ||||
| -rw-r--r-- | Swift/QtUI/QtFormWidget.cpp | 55 | ||||
| -rw-r--r-- | Swift/QtUI/QtFormWidget.h | 4 | ||||
| -rw-r--r-- | Swift/QtUI/QtMainWindow.cpp | 12 | ||||
| -rw-r--r-- | Swift/QtUI/QtMainWindow.h | 4 | ||||
| -rw-r--r-- | Swift/QtUI/QtSwift.cpp | 4 | ||||
| -rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 4 | ||||
| -rw-r--r-- | Swift/QtUI/QtUIFactory.h | 3 | ||||
| -rw-r--r-- | Swift/QtUI/SConscript | 1 |
10 files changed, 155 insertions, 25 deletions
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,216 +1,237 @@ /* - * 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) { QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]); QString string = widget->toPlainText(); if (!string.isEmpty()) { QStringList lines = string.split("\n"); foreach (QString line, lines) { resultField->addValue(Q2PSTRING(line)); } } } if (field->getType() == FormField::ListMultiType) { QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]); foreach (QListWidgetItem* item, listWidget->selectedItems()) { resultField->addValue(field->getOptions()[listWidget->row(item)].value); } } resultField->setName(field->getName()); result->addField(resultField); } return result; } template<class T> void QtFormWidget::setEnabled(QWidget* rawWidget, bool editable) { T* widget = qobject_cast<T*>(rawWidget); if (widget) { widget->setEnabled(editable); } } template<class T> void QtFormWidget::setEditable(QWidget* rawWidget, bool editable) { T* widget = qobject_cast<T*>(rawWidget); if (widget) { widget->setReadOnly(!editable); } } void QtFormWidget::setEditable(bool editable) { if (!form_) { return; } foreach (boost::shared_ptr<FormField> field, form_->getFields()) { QWidget* widget = NULL; if (field) { widget = fields_[field->getName()]; } setEnabled<QCheckBox>(widget, editable); setEnabled<QListWidget>(widget, editable); setEditable<QTextEdit>(widget, editable); setEditable<QLineEdit>(widget, editable); } } } 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 @@ -1,402 +1,412 @@ /* * Copyright (c) 2010-2011 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/QtUI/QtMainWindow.h> #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))); chatListWindow_ = new QtChatListWindow(uiEventStream_, settings_); connect(chatListWindow_, SIGNAL(onCountUpdated(int)), this, SLOT(handleChatCountUpdated(int))); tabs_->addTab(chatListWindow_, tr("C&hats")); tabs_->addTab(eventWindow_, tr("&Notices")); tabs_->setCurrentIndex(settings_->getSetting(QtUISettingConstants::CURRENT_ROSTER_TAB)); connect(tabs_, SIGNAL(currentChanged(int)), this, SLOT(handleTabChanged(int))); tabBarCombo_ = NULL; if (settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) { tabs_->tabBar()->hide(); tabBarCombo_ = new QComboBox(this); tabBarCombo_->setAccessibleName("Current View"); tabBarCombo_->addItem(tr("Contacts")); tabBarCombo_->addItem(tr("Chats")); tabBarCombo_->addItem(tr("Notices")); tabBarCombo_->setCurrentIndex(tabs_->currentIndex()); mainLayout->addWidget(tabBarCombo_); connect(tabBarCombo_, SIGNAL(currentIndexChanged(int)), tabs_, SLOT(setCurrentIndex(int))); } this->setLayout(mainLayout); QMenu* viewMenu = new QMenu(tr("&View"), this); menus_.push_back(viewMenu); compactRosterAction_ = new QAction(tr("&Compact Roster"), this); compactRosterAction_->setCheckable(true); compactRosterAction_->setChecked(false); connect(compactRosterAction_, SIGNAL(toggled(bool)), SLOT(handleCompactRosterToggled(bool))); viewMenu->addAction(compactRosterAction_); handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER)); showOfflineAction_ = new QAction(tr("&Show offline contacts"), this); showOfflineAction_->setCheckable(true); showOfflineAction_->setChecked(false); connect(showOfflineAction_, SIGNAL(toggled(bool)), SLOT(handleShowOfflineToggled(bool))); viewMenu->addAction(showOfflineAction_); handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); if (emoticonsExist) { showEmoticonsAction_ = new QAction(tr("&Show Emoticons"), this); showEmoticonsAction_->setCheckable(true); showEmoticonsAction_->setChecked(false); connect(showEmoticonsAction_, SIGNAL(toggled(bool)), SLOT(handleShowEmoticonsToggled(bool))); viewMenu->addAction(showEmoticonsAction_); handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); } //QAction* compactRosterAction_ = new QAction(tr("&Compact Roster"), this); //compactRosterAction_->setCheckable(true); //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) { settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, enabled); } void QtMainWindow::handleShowCertificateInfo() { onShowCertificateRequest(); } void QtMainWindow::handleEditBlockingList() { uiEventStream_->send(boost::make_shared<RequestBlockListDialogUIEvent>()); } QtEventWindow* QtMainWindow::getEventWindow() { return eventWindow_; } QtChatListWindow* QtMainWindow::getChatListWindow() { return chatListWindow_; } void QtMainWindow::setRosterModel(Roster* roster) { treeWidget_->setRosterModel(roster); } 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)); } } void QtMainWindow::handleCompactRosterToggled(bool state) { settings_->storeSetting(QtUISettingConstants::COMPACT_ROSTER, state); compactRosterAction_->setChecked(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER)); } void QtMainWindow::handleShowOfflineToggled(bool state) { settings_->storeSetting(SettingConstants::SHOW_OFFLINE, state); showOfflineAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); } void QtMainWindow::handleShowEmoticonsToggled(bool state) { settings_->storeSetting(QtUISettingConstants::SHOW_EMOTICONS, state); showEmoticonsAction_->setChecked(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS)); } void QtMainWindow::setMyNick(const std::string& nick) { meView_->setNick(P2QSTRING(nick)); } void QtMainWindow::setMyJID(const JID& jid) { meView_->setJID(P2QSTRING(jid.toBare().toString())); } void QtMainWindow::setMyAvatarPath(const std::string& path) { meView_->setAvatar(P2QSTRING(path)); } void QtMainWindow::setMyStatusText(const std::string& status) { meView_->setStatusText(P2QSTRING(status)); } void QtMainWindow::setMyStatusType(StatusShow::Type type) { meView_->setStatusType(type); } void QtMainWindow::setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) { meView_->setContactRosterItem(contact); } void QtMainWindow::setConnecting() { meView_->setConnecting(); } void QtMainWindow::setStreamEncryptionStatus(bool tlsInPlaceAndValid) { meView_->setStreamEncryptionStatus(tlsInPlaceAndValid); } void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain) { openCertificateDialog(chain, this); } void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent) { #if defined(SWIFTEN_PLATFORM_MACOSX) CocoaUIHelpers::displayCertificateChainAsSheet(parent, chain); #elif defined(SWIFTEN_PLATFORM_WINDOWS) WinUIHelpers::displayCertificateChainAsSheet(parent, chain); #else QtCertificateViewerDialog::displayCertificateChainAsSheet(parent, chain); #endif } void QtMainWindow::handleAdHocActionTriggered(bool /*checked*/) { QAction* action = qobject_cast<QAction*>(sender()); assert(action); DiscoItems::Item command = serverAdHocCommands_[serverAdHocCommandActions_.indexOf(action)]; uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestAdHocUIEvent(command))); } void QtMainWindow::setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) { serverAdHocCommands_ = commands; foreach (QAction* action, serverAdHocCommandActions_) { delete action; } serverAdHocMenu_->clear(); serverAdHocCommandActions_.clear(); foreach (DiscoItems::Item command, commands) { QAction* action = new QAction(P2QSTRING(command.getName()), this); connect(action, SIGNAL(triggered(bool)), this, SLOT(handleAdHocActionTriggered(bool))); serverAdHocMenu_->addAction(action); serverAdHocCommandActions_.append(action); } if (serverAdHocCommandActions_.isEmpty()) { QAction* action = new QAction(tr("No Available Commands"), this); action->setEnabled(false); serverAdHocMenu_->addAction(action); serverAdHocCommandActions_.append(action); } } void QtMainWindow::setBlockingCommandAvailable(bool isAvailable) { openBlockingListEditor_->setVisible(isAvailable); } } 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 @@ -1,106 +1,108 @@ /* * Copyright (c) 2010-2011 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #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 @@ -1,267 +1,269 @@ /* * Copyright (c) 2010-2013 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include <Swift/QtUI/QtSwift.h> #include <string> #include <map> #include <boost/bind.hpp> #include <QFile> #include <QMessageBox> #include <QApplication> #include <QMap> #include <qdebug.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/Path.h> #include <Swiften/Base/Platform.h> #include <Swiften/Elements/Presence.h> #include <Swiften/Client/Client.h> #include <Swiften/Base/Paths.h> #include <SwifTools/Application/PlatformApplicationPathProvider.h> #include <SwifTools/AutoUpdater/AutoUpdater.h> #include <SwifTools/AutoUpdater/PlatformAutoUpdaterFactory.h> #include <Swift/Controllers/Storages/CertificateFileStorageFactory.h> #include <Swift/Controllers/Storages/FileStoragesFactory.h> #include <Swift/Controllers/Settings/XMLSettingsProvider.h> #include <Swift/Controllers/Settings/SettingsProviderHierachy.h> #include <Swift/Controllers/MainController.h> #include <Swift/Controllers/ApplicationInfo.h> #include <Swift/Controllers/BuildVersion.h> #include <Swift/Controllers/StatusCache.h> #include <Swift/QtUI/QtLoginWindow.h> #include <Swift/QtUI/QtChatTabs.h> #include <Swift/QtUI/QtSystemTray.h> #include <Swift/QtUI/QtSoundPlayer.h> #include <Swift/QtUI/QtSwiftUtil.h> #include <Swift/QtUI/QtUIFactory.h> #include <Swift/QtUI/QtChatWindowFactory.h> #include <Swift/QtUI/QtSingleWindow.h> #if defined(SWIFTEN_PLATFORM_WINDOWS) #include <Swift/QtUI/WindowsNotifier.h> #elif defined(HAVE_GROWL) #include <SwifTools/Notifier/GrowlNotifier.h> #elif defined(SWIFTEN_PLATFORM_LINUX) #include <Swift/QtUI/FreeDesktopNotifier.h> #else #include <SwifTools/Notifier/NullNotifier.h> #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); } } } } 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; } delete notifier_; foreach (QtSystemTray* tray, systemTrays_) { delete tray; } delete tabs_; delete splitter_; delete settingsHierachy_; delete qtSettings_; delete xmlSettings_; delete statusCache_; delete uriHandler_; delete dock_; delete soundPlayer_; delete chatWindowFactory_; delete certificateStorageFactory_; delete storagesFactory_; } } 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 @@ -1,179 +1,179 @@ /* * Copyright (c) 2010-2014 Remko Tronçon * Licensed under the GNU General Public License v3. * 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(); } ChatWindow* QtUIFactory::createChatWindow(const JID& contact, UIEventStream* eventStream) { QtChatWindow* window = dynamic_cast<QtChatWindow*>(chatWindowFactory->createChatWindow(contact, eventStream)); chatWindows.push_back(window); std::vector<QPointer<QtChatWindow> > deletions; foreach (QPointer<QtChatWindow> existingWindow, chatWindows) { if (existingWindow.isNull()) { deletions.push_back(existingWindow); } else { connect(window, SIGNAL(fontResized(int)), existingWindow, SLOT(handleFontResized(int))); connect(existingWindow, SIGNAL(fontResized(int)), window, SLOT(handleFontResized(int))); } } foreach (QPointer<QtChatWindow> deletedWindow, deletions) { chatWindows.erase(std::remove(chatWindows.begin(), chatWindows.end(), deletedWindow), chatWindows.end()); } connect(window, SIGNAL(fontResized(int)), this, SLOT(handleChatWindowFontResized(int))); window->handleFontResized(chatFontSize); return window; } void QtUIFactory::handleChatWindowFontResized(int size) { chatFontSize = size; settings->storeSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE, size); } UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) { return new QtUserSearchWindow(eventStream, type, groups, qtOnlySettings); } JoinMUCWindow* QtUIFactory::createJoinMUCWindow(UIEventStream* uiEventStream) { return new QtJoinMUCWindow(uiEventStream); } ProfileWindow* QtUIFactory::createProfileWindow() { return new QtProfileWindow(); } ContactEditWindow* QtUIFactory::createContactEditWindow() { return new QtContactEditWindow(); } WhiteboardWindow* QtUIFactory::createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) { return new QtWhiteboardWindow(whiteboardSession); } HighlightEditorWidget* QtUIFactory::createHighlightEditorWidget() { return new QtHighlightEditorWidget(); } BlockListEditorWidget *QtUIFactory::createBlockListEditorWidget() { return new QtBlockListEditorWindow(); } AdHocCommandWindow* QtUIFactory::createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) { return new QtAdHocCommandWindow(command); } } 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 @@ -1,443 +1,444 @@ import os, shutil, datetime, re, time import Version def generateDefaultTheme(dir) : sourceDir = dir.abspath result = "<!-- WARNING: This file is automatically generated. Any changes will be overwritten. -->\n" result += "<RCC version =\"1.0\">" result += "<qresource prefix=\"/themes/Default\">" for (path, dirs, files) in os.walk(sourceDir) : for file in files : filePath = os.path.join(path,file) result += "<file alias=\"%(alias)s\">%(path)s</file>" % { "alias": filePath[len(sourceDir)+1:], "path": filePath } result += "</qresource>" result += "</RCC>" return result Import("env") myenv = env.Clone() # Disable warnings that affect Qt myenv["CXXFLAGS"] = filter(lambda x : x != "-Wfloat-equal", myenv["CXXFLAGS"]) if "clang" in env["CC"] : myenv.Append(CXXFLAGS = ["-Wno-float-equal", "-Wno-shorten-64-to-32", "-Wno-missing-prototypes", "-Wno-unreachable-code", "-Wno-disabled-macro-expansion", "-Wno-unused-private-field", "-Wno-extra-semi", "-Wno-duplicate-enum", "-Wno-missing-variable-declarations", "-Wno-conversion", "-Wno-undefined-reinterpret-cast"]) myenv.UseFlags(env["SWIFT_CONTROLLERS_FLAGS"]) myenv.UseFlags(env["SWIFTOOLS_FLAGS"]) if myenv["HAVE_XSS"] : myenv.UseFlags(env["XSS_FLAGS"]) if env["PLATFORM"] == "posix" : myenv.Append(LIBS = ["X11"]) if myenv["HAVE_SPARKLE"] : myenv.UseFlags(env["SPARKLE_FLAGS"]) myenv.UseFlags(env["SWIFTEN_FLAGS"]) myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"]) if myenv.get("HAVE_BREAKPAD") : myenv.UseFlags(env["BREAKPAD_FLAGS"]) if myenv.get("HAVE_GROWL", False) : myenv.UseFlags(myenv["GROWL_FLAGS"]) myenv.Append(CPPDEFINES = ["HAVE_GROWL"]) if myenv["swift_mobile"] : myenv.Append(CPPDEFINES = ["SWIFT_MOBILE"]) if myenv.get("HAVE_SNARL", False) : myenv.UseFlags(myenv["SNARL_FLAGS"]) myenv.Append(CPPDEFINES = ["HAVE_SNARL"]) if myenv.get("HAVE_HUNSPELL", True): myenv.Append(CPPDEFINES = ["HAVE_HUNSPELL"]) myenv.UseFlags(myenv["HUNSPELL_FLAGS"]) if env["PLATFORM"] == "win32" : myenv.Append(LIBS = ["cryptui"]) myenv.UseFlags(myenv["PLATFORM_FLAGS"]) myenv.Tool("qt4", toolpath = ["#/BuildTools/SCons/Tools"]) myenv.Tool("nsis", toolpath = ["#/BuildTools/SCons/Tools"]) myenv.Tool("wix", toolpath = ["#/BuildTools/SCons/Tools"]) myenv.Tool("textfile", toolpath = ["#/BuildTools/SCons/Tools"]) qt4modules = ['QtCore', 'QtWebKit', 'QtGui'] if myenv["qt5"] : qt_version = '5' qt4modules += ['QtWidgets', 'QtWebKitWidgets', 'QtMultimedia'] else : qt_version = '4' if env["PLATFORM"] == "posix" : qt4modules += ["QtDBus"] if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" : qt4modules += ["QtNetwork"] myenv.EnableQt4Modules(qt4modules, debug = False, version = qt_version) myenv.Append(CPPPATH = ["."]) if env["PLATFORM"] == "win32" : #myenv.Append(LINKFLAGS = ["/SUBSYSTEM:CONSOLE"]) myenv.Append(LINKFLAGS = ["/SUBSYSTEM:WINDOWS"]) myenv.Append(LIBS = "qtmain") if myenv.get("HAVE_SCHANNEL", 0) : myenv.Append(LIBS = "Cryptui") myenv.Append(CPPDEFINES = "HAVE_SCHANNEL") if env["debug"] and not env["optimize"]: myenv.Append(LINKFLAGS = ["/NODEFAULTLIB:msvcrt"]) myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateDefaultTheme(myenv.Dir("#/Swift/resources/themes/Default")))) 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", "EventViewer/QtEvent.cpp", "ChatList/QtChatListWindow.cpp", "ChatList/ChatListModel.cpp", "ChatList/ChatListDelegate.cpp", "ChatList/ChatListMUCItem.cpp", "ChatList/ChatListRecentItem.cpp", "ChatList/ChatListWhiteboardItem.cpp", "MUCSearch/QtMUCSearchWindow.cpp", "MUCSearch/MUCSearchModel.cpp", "MUCSearch/MUCSearchRoomItem.cpp", "MUCSearch/MUCSearchEmptyItem.cpp", "MUCSearch/MUCSearchDelegate.cpp", "UserSearch/ContactListDelegate.cpp", "UserSearch/ContactListModel.cpp", "UserSearch/QtContactListWidget.cpp", "UserSearch/QtSuggestingJIDInput.cpp", "UserSearch/QtUserSearchFirstPage.cpp", "UserSearch/QtUserSearchFirstMultiJIDPage.cpp", "UserSearch/QtUserSearchFieldsPage.cpp", "UserSearch/QtUserSearchResultsPage.cpp", "UserSearch/QtUserSearchDetailsPage.cpp", "UserSearch/QtUserSearchWindow.cpp", "UserSearch/UserSearchModel.cpp", "UserSearch/UserSearchDelegate.cpp", "Whiteboard/FreehandLineItem.cpp", "Whiteboard/GView.cpp", "Whiteboard/TextDialog.cpp", "Whiteboard/QtWhiteboardWindow.cpp", "Whiteboard/ColorWidget.cpp", "QtSubscriptionRequestWindow.cpp", "QtRosterHeader.cpp", "QtWebView.cpp", "qrc_DefaultTheme.cc", "qrc_Swift.cc", "QtChatWindowJSBridge.cpp", "QtMUCConfigurationWindow.cpp", "QtAffiliationEditor.cpp", "QtUISettingConstants.cpp", "QtURLValidator.cpp", "QtResourceHelper.cpp" ] # QtVCardWidget sources.extend([ "QtVCardWidget/QtCloseButton.cpp", "QtVCardWidget/QtRemovableItemDelegate.cpp", "QtVCardWidget/QtResizableLineEdit.cpp", "QtVCardWidget/QtTagComboBox.cpp", "QtVCardWidget/QtVCardHomeWork.cpp", "QtVCardWidget/QtVCardAddressField.cpp", "QtVCardWidget/QtVCardAddressLabelField.cpp", "QtVCardWidget/QtVCardBirthdayField.cpp", "QtVCardWidget/QtVCardDescriptionField.cpp", "QtVCardWidget/QtVCardInternetEMailField.cpp", "QtVCardWidget/QtVCardJIDField.cpp", "QtVCardWidget/QtVCardOrganizationField.cpp", "QtVCardWidget/QtVCardPhotoAndNameFields.cpp", "QtVCardWidget/QtVCardRoleField.cpp", "QtVCardWidget/QtVCardTelephoneField.cpp", "QtVCardWidget/QtVCardTitleField.cpp", "QtVCardWidget/QtVCardURLField.cpp", "QtVCardWidget/QtVCardGeneralField.cpp", "QtVCardWidget/QtVCardWidget.cpp" ]) myenv.Uic4("QtVCardWidget/QtVCardPhotoAndNameFields.ui") myenv.Uic4("QtVCardWidget/QtVCardWidget.ui") myenv.Uic4("QtProfileWindow.ui") # Determine the version myenv["SWIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift") if env["PLATFORM"] == "win32" : swift_windows_version = Version.convertToWindowsVersion(myenv["SWIFT_VERSION"]) myenv["SWIFT_VERSION_MAJOR"] = swift_windows_version[0] myenv["SWIFT_VERSION_MINOR"] = swift_windows_version[1] myenv["SWIFT_VERSION_PATCH"] = swift_windows_version[2] if env["PLATFORM"] == "win32" : res_env = myenv.Clone() res_env.Append(CPPDEFINES = [ ("SWIFT_COPYRIGHT_YEAR", "\"\\\"2010-%s\\\"\"" % str(time.localtime()[0])), ("SWIFT_VERSION_MAJOR", "${SWIFT_VERSION_MAJOR}"), ("SWIFT_VERSION_MINOR", "${SWIFT_VERSION_MINOR}"), ("SWIFT_VERSION_PATCH", "${SWIFT_VERSION_PATCH}"), ]) res = res_env.RES("#/Swift/resources/Windows/Swift.rc") # For some reason, SCons isn't picking up the dependency correctly # Adding it explicitly until i figure out why myenv.Depends(res, "../Controllers/BuildVersion.h") sources += [ "WinUIHelpers.cpp", "CAPICertificateSelector.cpp", "WindowsNotifier.cpp", "#/Swift/resources/Windows/Swift.res" ] if env["PLATFORM"] == "posix" : sources += [ "FreeDesktopNotifier.cpp", "QtDBUSURIHandler.cpp", ] if env["PLATFORM"] == "darwin" : sources += ["CocoaApplicationActivateHelper.mm"] sources += ["CocoaUIHelpers.mm"] if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" : swiftProgram = myenv.Program("Swift", sources) else : sources += ["QtCertificateViewerDialog.cpp"]; myenv.Uic4("QtCertificateViewerDialog.ui"); swiftProgram = myenv.Program("swift-im", sources) if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" : openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp") else : openURIProgram = [] myenv.Uic4("MUCSearch/QtMUCSearchWindow.ui") myenv.Uic4("UserSearch/QtUserSearchWizard.ui") myenv.Uic4("UserSearch/QtUserSearchFirstPage.ui") myenv.Uic4("UserSearch/QtUserSearchFirstMultiJIDPage.ui") myenv.Uic4("UserSearch/QtUserSearchFieldsPage.ui") myenv.Uic4("UserSearch/QtUserSearchResultsPage.ui") myenv.Uic4("QtBookmarkDetailWindow.ui") myenv.Uic4("QtAffiliationEditor.ui") myenv.Uic4("QtJoinMUCWindow.ui") myenv.Uic4("QtHistoryWindow.ui") myenv.Uic4("QtConnectionSettings.ui") myenv.Uic4("QtHighlightRuleWidget.ui") myenv.Uic4("QtHighlightEditorWidget.ui") myenv.Uic4("QtBlockListEditorWindow.ui") myenv.Uic4("QtSpellCheckerWindow.ui") myenv.Qrc("DefaultTheme.qrc") myenv.Qrc("Swift.qrc") # Resources commonResources = { "": ["#/Swift/resources/sounds"] } myenv["TEXTFILESUFFIX"] = "" myenv.MyTextfile(target = "COPYING", source = [myenv.File("../../COPYING.gpl"), myenv.File("../../COPYING.thirdparty")], LINESEPARATOR = "\n\n========\n\n\n") ################################################################################ # Translation ################################################################################ # Collect available languages translation_languages = [] for file in os.listdir(Dir("#/Swift/Translations").abspath) : if file.startswith("swift_") and file.endswith(".ts") : translation_languages.append(file[6:-3]) # Generate translation modules translation_sources = [env.File("#/Swift/Translations/swift.ts").abspath] translation_modules = [] for lang in translation_languages : translation_resource = "#/Swift/resources/translations/swift_" + lang + ".qm" translation_source = "#/Swift/Translations/swift_" + lang + ".ts" translation_sources.append(env.File(translation_source).abspath) translation_modules.append(env.File(translation_resource).abspath) myenv.Qm(translation_resource, translation_source) commonResources["translations"] = commonResources.get("translations", []) + [translation_resource] # LUpdate translation (if requested) if ARGUMENTS.get("update_translations", False) : myenv.Precious(translation_sources) remove_obsolete_option = "" if ARGUMENTS.get("remove_obsolete_translations", False) : remove_obsolete_option = " -no-obsolete" for translation_source in filter(lambda x: not x.endswith("_en.ts"), translation_sources) : t = myenv.Command([translation_source], [], [myenv.Action("$QT4_LUPDATE -I " + env.Dir("#").abspath + remove_obsolete_option + " -silent -codecfortr utf-8 -recursive Swift -ts " + translation_source, cmdstr = "$QT4_LUPDATECOMSTR")]) myenv.AlwaysBuild(t) # NSIS installation script if env["PLATFORM"] == "win32" : nsis_translation_install_script = "" nsis_translation_uninstall_script = "" for lang in translation_languages : nsis_translation_install_script += "File \"..\\..\\QtUI\\Swift\\translations\\swift_" + lang + ".qm\"\n" nsis_translation_uninstall_script += "delete $INSTDIR\\translations\\swift_" + lang + ".qm\n" myenv.WriteVal("../Packaging/nsis/translations-install.nsh", myenv.Value(nsis_translation_install_script)) myenv.WriteVal("../Packaging/nsis/translations-uninstall.nsh", myenv.Value(nsis_translation_uninstall_script)) ################################################################################ if env["PLATFORM"] == "darwin" : frameworks = [] if env["HAVE_SPARKLE"] : frameworks.append(env["SPARKLE_FRAMEWORK"]) if env["HAVE_GROWL"] : frameworks.append(env["GROWL_FRAMEWORK"]) commonResources[""] = commonResources.get("", []) + ["#/Swift/resources/MacOSX/Swift.icns"] app = myenv.AppBundle("Swift", version = myenv["SWIFT_VERSION"], resources = commonResources, frameworks = frameworks, handlesXMPPURIs = True) if env["DIST"] : myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dmg"], [app], ["Swift/Packaging/MacOSX/package.sh " + app.path + " Swift/Packaging/MacOSX/Swift.dmg.gz $TARGET $QTDIR"]) dsym = myenv.Command(["Swift-${SWIFT_VERSION}.dSYM"], ["Swift"], ["dsymutil -o ${TARGET} ${SOURCE}"]) myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dSYM.zip"], dsym, ["cd ${SOURCE.dir} && zip -r ${TARGET.abspath} ${SOURCE.name}"]) if env.get("SWIFT_INSTALLDIR", "") : env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "bin"), swiftProgram + openURIProgram) env.InstallAs(os.path.join(env["SWIFT_INSTALLDIR"], "share", "pixmaps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm") icons_path = os.path.join(env["SWIFT_INSTALLDIR"], "share", "icons", "hicolor") env.InstallAs(os.path.join(icons_path, "32x32", "apps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm") env.InstallAs(os.path.join(icons_path, "scalable", "apps", "swift.svg"), "#/Swift/resources/logo/logo-icon.svg") for i in ["16", "22", "24", "64", "128"] : env.InstallAs(os.path.join(icons_path, i + "x" + i, "apps", "swift.png"), "#/Swift/resources/logo/logo-icon-" + i + ".png") env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "applications"), "#/Swift/resources/swift.desktop") for dir, resource in commonResources.items() : env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "swift", dir), resource) if env["PLATFORM"] == "win32" : if env["DIST"] or ARGUMENTS.get("dump_trace") : commonResources[""] = commonResources.get("", []) + [ #os.path.join(env["OPENSSL_DIR"], "bin", "ssleay32.dll"), #os.path.join(env["OPENSSL_DIR"], "bin", "libeay32.dll"), "#/Swift/resources/images", ] if env["SWIFTEN_DLL"] : commonResources[""] = commonResources.get("", []) + ["#/Swiften/${SWIFTEN_LIBRARY_FILE}"] qtplugins = {} qtplugins["imageformats"] = ["gif", "ico", "jpeg", "mng", "svg", "tiff"] qtlibs = ["QtCore", "QtGui", "QtNetwork", "QtWebKit", "QtXMLPatterns"] if qt_version == '4' : qtlibs.append("phonon") qtlibs = [lib + '4' for lib in qtlibs] else : qtlibs += ['QtQuick', 'QtQml', 'QtPositioning', 'QtMultimedia', 'QtSql', 'QtSensors', 'QtWidgets', 'QtWebKitWidgets', 'QtMultimediaWidgets', 'QtOpenGL', 'QtPrintSupport'] qtlibs = [lib.replace('Qt', 'Qt5') for lib in qtlibs] qtlibs += ['icuin51', 'icuuc51', 'icudt51', 'libGLESv2', 'libEGL'] qtplugins["platforms"] = ['windows'] qtplugins["accessible"] = ["taccessiblewidgets"] windowsBundleFiles = myenv.WindowsBundle("Swift", resources = commonResources, qtplugins = qtplugins, qtlibs = qtlibs, qtversion = qt_version) if env["DIST"] : #myenv.Append(NSIS_OPTIONS = [ # "/DmsvccRedistributableDir=\"" + env["vcredist"] + "\"", # "/DbuildVersion=" + myenv["SWIFT_VERSION"] # ]) #myenv.Nsis("../Packaging/nsis/swift.nsi") if env["SCONS_STAGE"] == "build" and env.get("wix_bindir", None): def convertToRTF(env, target, source) : infile = open(source[0].abspath, 'r') outfile = open(target[0].abspath, 'w') outfile.write('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\fs16\\f0\\pard\n') for line in infile: for char in line.decode("utf-8") : if ord(char) > 127 : # FIXME: This is incorrect, because it only works for latin1. # The correct way is \u<decimal utf16 point>? , but this is more # work outfile.write("\\'%X" % ord(char)) else : outfile.write(char) outfile.write('\\par ') outfile.write('}') outfile.close() infile.close() copying = env.Command(["Swift/COPYING.rtf"], ["COPYING"], convertToRTF) wixvariables = { 'VCCRTFile': env["vcredist"], 'Version': str(myenv["SWIFT_VERSION_MAJOR"]) + "." + str(myenv["SWIFT_VERSION_MINOR"]) + "." + str(myenv["SWIFT_VERSION_PATCH"]) } wixincludecontent = "<Include>" for key in wixvariables: wixincludecontent += "<?define %s = \"%s\" ?>" % (key, wixvariables[key]) wixincludecontent += "</Include>" myenv.WriteVal("..\\Packaging\\Wix\\variables.wxs", env.Value(wixincludecontent)) myenv["WIX_SOURCE_OBJECT_DIR"] = "Swift\\QtUI\\Swift" myenv.WiX_Heat('..\\Packaging\\WiX\\gen_files.wxs', windowsBundleFiles + copying) myenv.WiX_Candle('..\\Packaging\\WiX\\Swift.wixobj', '..\\Packaging\\WiX\\Swift.wxs') myenv.WiX_Candle('..\\Packaging\\WiX\\gen_files.wixobj', '..\\Packaging\\WiX\\gen_files.wxs') myenv.WiX_Light('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.msi', ['..\\Packaging\\WiX\\gen_files.wixobj','..\\Packaging\\WiX\\Swift.wixobj']) if myenv["debug"] : myenv.InstallAs('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.pdb', "Swift.pdb") |
Swift