#include "settingspages/connectionsettingspage.h"
#include "settingspages/coreaccountsettingspage.h"
#include "settingspages/coreconnectionsettingspage.h"
+#include "settingspages/dccsettingspage.h"
#include "settingspages/highlightsettingspage.h"
#include "settingspages/identitiessettingspage.h"
#include "settingspages/ignorelistsettingspage.h"
dlg->registerSettingsPage(new NetworksSettingsPage(dlg));
dlg->registerSettingsPage(new AliasesSettingsPage(dlg));
dlg->registerSettingsPage(new IgnoreListSettingsPage(dlg));
+ dlg->registerSettingsPage(new DccSettingsPage(dlg));
// Category: Remote Cores
if (Quassel::runMode() != Quassel::Monolithic) {
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-2016 by the Quassel Project *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "dccsettingspage.h"
+
+#include "client.h"
+#include "clienttransfermanager.h"
+
+DccSettingsPage::DccSettingsPage(QWidget *parent)
+ : SettingsPage(tr("IRC"), tr("DCC"), parent)
+{
+ ui.setupUi(this);
+ initAutoWidgets();
+ connect(ui.ipDetectionMode, SIGNAL(currentIndexChanged(int)), SLOT(updateWidgetStates()));
+ connect(ui.portSelectionMode, SIGNAL(currentIndexChanged(int)), SLOT(updateWidgetStates()));
+ updateWidgetStates();
+
+ connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), SLOT(onClientConfigChanged()));
+ setClientConfig(Client::dccConfig());
+}
+
+
+bool DccSettingsPage::isClientConfigValid() const
+{
+ return _clientConfig != nullptr;
+}
+
+
+void DccSettingsPage::setClientConfig(DccConfig *config)
+{
+ if (_clientConfig) {
+ disconnect(_clientConfig, 0, this, 0);
+ }
+ if (config && !isClientConfigValid()) {
+ qWarning() << "Client DCC config is not valid/synchronized!";
+ _clientConfig = nullptr;
+ ui.dccEnabled->setEnabled(false);
+ return;
+ }
+ _clientConfig = config;
+ if (_clientConfig) {
+ connect(_clientConfig, SIGNAL(updated()), SLOT(load()));
+ load();
+ ui.dccEnabled->setEnabled(true);
+ }
+ else {
+ ui.dccEnabled->setEnabled(false);
+ }
+}
+
+
+void DccSettingsPage::onClientConfigChanged()
+{
+ if (Client::isConnected() && Client::dccConfig() && !Client::dccConfig()->isInitialized()) {
+ connect(Client::dccConfig(), SIGNAL(initDone()), SLOT(onClientConfigChanged()));
+ }
+ else {
+ setClientConfig(Client::isConnected() ? Client::dccConfig() : nullptr);
+ }
+}
+
+
+bool DccSettingsPage::hasDefaults() const
+{
+ return true;
+}
+
+
+void DccSettingsPage::defaults()
+{
+ _localConfig = DccConfig();
+ SettingsPage::load();
+ widgetHasChanged();
+}
+
+
+void DccSettingsPage::load()
+{
+ _localConfig = isClientConfigValid() ? *_clientConfig : DccConfig{};
+ SettingsPage::load();
+ widgetHasChanged();
+}
+
+
+void DccSettingsPage::save()
+{
+ SettingsPage::save();
+ if (isClientConfigValid()) {
+ Client::dccConfig()->requestUpdate(_localConfig.toVariantMap());
+ }
+ setChangedState(false);
+}
+
+
+QVariant DccSettingsPage::loadAutoWidgetValue(const QString& widgetName)
+{
+ if (widgetName == "dccEnabled")
+ return _localConfig.isDccEnabled();
+ if (widgetName == "ipDetectionMode")
+ // NOTE: Use mapping if item order differs from enum order
+ return static_cast<int>(_localConfig.ipDetectionMode());
+ if (widgetName == "portSelectionMode")
+ // NOTE: Use mapping if item order differs from enum order
+ return static_cast<int>(_localConfig.portSelectionMode());
+ if (widgetName == "minPort")
+ return _localConfig.minPort();
+ if (widgetName == "maxPort")
+ return _localConfig.maxPort();
+ if (widgetName == "chunkSize")
+ return _localConfig.chunkSize();
+ if (widgetName == "sendTimeout")
+ return _localConfig.sendTimeout();
+ if (widgetName == "usePassiveDcc")
+ return _localConfig.usePassiveDcc();
+ if (widgetName == "useFastSend")
+ return _localConfig.useFastSend();
+ if (widgetName == "outgoingIp")
+ return _localConfig.outgoingIp().toString();
+
+ qWarning() << "Unknown auto widget" << widgetName;
+ return {};
+}
+
+
+void DccSettingsPage::saveAutoWidgetValue(const QString& widgetName, const QVariant& value)
+{
+ if (widgetName == "dccEnabled")
+ _localConfig.setDccEnabled(value.toBool());
+ else if (widgetName == "ipDetectionMode")
+ // NOTE: Use mapping if item order differs from enum order
+ _localConfig.setIpDetectionMode(static_cast<DccConfig::IpDetectionMode>(value.toInt()));
+ else if (widgetName == "portSelectionMode")
+ // NOTE: Use mapping if item order differs from enum order
+ _localConfig.setPortSelectionMode(static_cast<DccConfig::PortSelectionMode>(value.toInt()));
+ else if (widgetName == "minPort")
+ _localConfig.setMinPort(value.toInt());
+ else if (widgetName == "maxPort")
+ _localConfig.setMaxPort(value.toInt());
+ else if (widgetName == "chunkSize")
+ _localConfig.setChunkSize(value.toInt());
+ else if (widgetName == "sendTimeout")
+ _localConfig.setSendTimeout(value.toInt());
+ else if (widgetName == "usePassiveDcc")
+ _localConfig.setUsePassiveDcc(value.toBool());
+ else if (widgetName == "useFastSend")
+ _localConfig.setUseFastSend(value.toBool());
+ else if (widgetName == "outgoingIp") {
+ QHostAddress address {QHostAddress::LocalHost};
+ if (!address.setAddress(value.toString())) {
+ qWarning() << "Invalid IP address!";
+ address = QHostAddress{QHostAddress::LocalHost};
+ }
+ _localConfig.setOutgoingIp(std::move(address));
+ }
+ else {
+ qWarning() << "Unknown auto widget" << widgetName;
+ }
+}
+
+
+void DccSettingsPage::widgetHasChanged()
+{
+ bool same = isClientConfigValid() && (_localConfig == *_clientConfig);
+ setChangedState(!same);
+}
+
+
+void DccSettingsPage::updateWidgetStates()
+{
+ ui.outgoingIp->setEnabled(ui.ipDetectionMode->currentIndex() != 0);
+ bool enablePorts = ui.portSelectionMode->currentIndex() != 0;
+ ui.minPort->setEnabled(enablePorts);
+ ui.maxPort->setEnabled(enablePorts);
+ ui.portsToLabel->setEnabled(enablePorts);
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-2016 by the Quassel Project *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#pragma once
+
+#include "dccconfig.h"
+#include "settingspage.h"
+#include "ui_dccsettingspage.h"
+
+/**
+ * A settingspage for configuring DCC.
+ */
+class DccSettingsPage : public SettingsPage
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor.
+ *
+ * @param[in] parent QObject parent
+ */
+ DccSettingsPage(QWidget *parent = nullptr);
+
+ /// See base class docs
+ bool hasDefaults() const override;
+
+public slots:
+ // See base class docs
+ void save() override;
+ void load() override;
+ void defaults() override;
+
+private:
+ /**
+ * Whether the client's DccConfig is valid
+ *
+ * @returns true if the client is connected and its DccConfig instance synchronized
+ */
+ bool isClientConfigValid() const;
+
+ /**
+ * Set the client config
+ *
+ * @param[in] config The client's config. Must be be valid or a nullptr.
+ */
+ void setClientConfig(DccConfig *config);
+
+ // See base class docs
+ QVariant loadAutoWidgetValue(const QString &widgetName) override;
+ void saveAutoWidgetValue(const QString &widgetName, const QVariant &value) override;
+
+private slots:
+ /**
+ * Updates the enabled state according to the current config.
+ */
+ void updateWidgetStates();
+
+ /**
+ * Checks if the current unsaved config differs from the client's and sets state accordingly.
+ */
+ void widgetHasChanged();
+
+ /**
+ * Called if the client's config was changed (e.g. if the connection state changed).
+ */
+ void onClientConfigChanged();
+
+private:
+ Ui::DccSettingsPage ui; ///< The UI object
+ DccConfig *_clientConfig {nullptr}; ///< Pointer to the client's config (nullptr if not synchronized/available)
+ DccConfig _localConfig; ///< Local config reflecting the widget states
+};
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DccSettingsPage</class>
+ <widget class="QWidget" name="DccSettingsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>736</width>
+ <height>559</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QGroupBox" name="dccEnabled">
+ <property name="title">
+ <string>Enable DCC</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <bool>false</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Ports:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="portSelectionMode">
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Automatic</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Manual</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="minPort">
+ <property name="minimum">
+ <number>1024</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>1024</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="portsToLabel">
+ <property name="text">
+ <string>to</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="maxPort">
+ <property name="minimum">
+ <number>1024</number>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ <property name="value">
+ <number>65535</number>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>32767</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Outgoing IP:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLineEdit" name="outgoingIp">
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <string notr="true">localhost</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="ipDetectionMode">
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Automatic</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Manual</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>DCC send timeout:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sendTimeout">
+ <property name="suffix">
+ <string> seconds</string>
+ </property>
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="maximum">
+ <number>3600</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>180</number>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>180</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Chunk size:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="chunkSize">
+ <property name="suffix">
+ <string> KiB</string>
+ </property>
+ <property name="prefix">
+ <string/>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1024</number>
+ </property>
+ <property name="singleStep">
+ <number>16</number>
+ </property>
+ <property name="value">
+ <number>16</number>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <number>16</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="usePassiveDcc">
+ <property name="text">
+ <string>Use passive/reverse DCC</string>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="useFastSend">
+ <property name="text">
+ <string>Use fast sending (might not work with all peers)</string>
+ </property>
+ <property name="settingsKey" stdset="0">
+ <string notr="true"/>
+ </property>
+ <property name="defaultValue" stdset="0">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="enableFileTransfers">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>File transfers</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Default download folder:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="downloadPath"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="browseButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="createSenderDirectory">
+ <property name="text">
+ <string>Create folder per sender</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="prefixFilenames">
+ <property name="text">
+ <string>Prefix filenames with sender</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>ipDetectionMode</tabstop>
+ <tabstop>outgoingIp</tabstop>
+ <tabstop>portSelectionMode</tabstop>
+ <tabstop>minPort</tabstop>
+ <tabstop>maxPort</tabstop>
+ <tabstop>sendTimeout</tabstop>
+ <tabstop>chunkSize</tabstop>
+ <tabstop>usePassiveDcc</tabstop>
+ <tabstop>useFastSend</tabstop>
+ <tabstop>downloadPath</tabstop>
+ <tabstop>browseButton</tabstop>
+ <tabstop>createSenderDirectory</tabstop>
+ <tabstop>prefixFilenames</tabstop>
+ <tabstop>dccEnabled</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
connection
coreconnection
coreaccount
+ dcc
highlight
identities
ignorelist