#include "settingspagedlg.h"
#include "util.h"
+// IRCv3 capabilities
+#include "irccap.h"
+
#include "settingspages/identitiessettingspage.h"
NetworksSettingsPage::NetworksSettingsPage(QWidget *parent)
connect(ui.identityList, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
//connect(ui.randomServer, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
connect(ui.performEdit, SIGNAL(textChanged()), this, SLOT(widgetHasChanged()));
- connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
- connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
- connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
connect(ui.sasl, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
connect(ui.saslAccount, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged()));
connect(ui.saslPassword, SIGNAL(textEdited(QString)), this, SLOT(widgetHasChanged()));
+ connect(ui.autoIdentify, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
+ connect(ui.autoIdentifyService, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
+ connect(ui.autoIdentifyPassword, SIGNAL(textEdited(const QString &)), this, SLOT(widgetHasChanged()));
connect(ui.useCustomEncodings, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
connect(ui.sendEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
connect(ui.recvEncoding, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
connect(ui.reconnectRetries, SIGNAL(valueChanged(int)), this, SLOT(widgetHasChanged()));
connect(ui.unlimitedRetries, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
connect(ui.rejoinOnReconnect, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
+
+ // Core features can change during a reconnect. Always connect these here, delaying testing for
+ // the core feature flag in load().
+ connect(ui.useCustomMessageRate, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
+ connect(ui.messageRateBurstSize, SIGNAL(valueChanged(int)), this, SLOT(widgetHasChanged()));
+ connect(ui.messageRateDelay, SIGNAL(valueChanged(double)), this, SLOT(widgetHasChanged()));
+ connect(ui.unlimitedMessageRate, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
+
+ // Add additional widgets here
//connect(ui., SIGNAL(), this, SLOT(widgetHasChanged()));
//connect(ui., SIGNAL(), this, SLOT(widgetHasChanged()));
void NetworksSettingsPage::load()
{
reset();
+
+ // Handle UI dependent on core feature flags here
+ if (Client::coreFeatures() & Quassel::CustomRateLimits) {
+ // Custom rate limiting supported, allow toggling
+ ui.useCustomMessageRate->setEnabled(true);
+ // Reset tooltip to default.
+ ui.useCustomMessageRate->setToolTip(QString("%1").arg(
+ tr("<p>Override default message rate limiting.</p>"
+ "<p><b>Setting limits too low may get you disconnected"
+ " from the server!</b></p>")));
+ // If changed, update the message below!
+ } else {
+ // Custom rate limiting not supported, disallow toggling
+ ui.useCustomMessageRate->setEnabled(false);
+ // Split up the message to allow re-using translations:
+ // [Original tool-tip]
+ // [Bold 'does not support feature' message]
+ // [Specific version needed and feature details]
+ ui.useCustomMessageRate->setToolTip(QString("%1<br/><b>%2</b><br/>%3").arg(
+ tr("<p>Override default message rate limiting.</p>"
+ "<p><b>Setting limits too low may get you disconnected"
+ " from the server!</b></p>"),
+ tr("Your Quassel core does not support this feature"),
+ tr("You need a Quassel core v0.13.0 or newer in order to "
+ "modify message rate limits.")));
+ }
+
+#ifdef HAVE_SSL
+ // Hide the SASL EXTERNAL notice until a network's shown. Stops it from showing while loading
+ // backlog from the core.
+ sslUpdated();
+#endif
+
foreach(NetworkId netid, Client::networkIds()) {
clientNetworkAdded(netid);
}
ui.networkList->setCurrentRow(0);
+
setChangedState(false);
}
}
+void NetworksSettingsPage::setNetworkCapStates(NetworkId id)
+{
+ const Network *net = Client::network(id);
+ if ((Client::coreFeatures() & Quassel::CapNegotiation)
+ && net && net->connectionState() != Network::Disconnected) {
+ // If Capability Negotiation isn't supported by the core, no capabilities are active.
+ // If we're here, the network exists and is connected, check available capabilities...
+ // Don't use net->isConnected() as that won't be true during capability negotiation when
+ // capabilities are added and removed.
+
+ // [SASL]
+ if (net->saslMaybeSupports(IrcCap::SaslMech::PLAIN)) {
+ // The network advertises support for SASL PLAIN. Encourage using it! Unfortunately we
+ // don't know for sure if it's desired or functional.
+ ui.sasl->setTitle(QString("%1 (%2)").arg(tr("Use SASL Authentication"),
+ tr("preferred")));
+ } else {
+ // The network doesn't advertise support for SASL PLAIN. Here be dragons.
+ ui.sasl->setTitle(QString("%1 (%2)").arg(tr("Use SASL Authentication"),
+ tr("might not work")));
+ }
+ // Split up the messages to ease translation and re-use existing "Use SASL Authentication"
+ // translations. If some languages rearrange phrases such that this would not make sense,
+ // these strings can be merged into one.
+
+ // Add additional capability-dependent interface updates here
+ } else {
+ // We're not connected or the network doesn't yet exist. Don't assume anything and reset
+ // all capability-dependent interface elements to neutral.
+ // [SASL]
+ ui.sasl->setTitle(tr("Use SASL Authentication"));
+
+ // Add additional capability-dependent interface updates here
+ }
+}
+
+
void NetworksSettingsPage::coreConnectionStateChanged(bool state)
{
this->setEnabled(state);
connect(Client::network(id), SIGNAL(connectionStateSet(Network::ConnectionState)), this, SLOT(networkConnectionStateChanged(Network::ConnectionState)));
connect(Client::network(id), SIGNAL(connectionError(const QString &)), this, SLOT(networkConnectionError(const QString &)));
+
+ // Handle capability changes in case a server dis/connects with the settings window open.
+ connect(Client::network(id), SIGNAL(capAdded(const QString &)), this, SLOT(clientNetworkCapsUpdated()));
+ connect(Client::network(id), SIGNAL(capRemoved(const QString &)), this, SLOT(clientNetworkCapsUpdated()));
}
}
*/
setItemState(net->networkId());
+ if (net->networkId() == currentId) {
+ // Network is currently shown. Update the capability-dependent UI in case capabilities have
+ // changed.
+ setNetworkCapStates(currentId);
+ }
setWidgetStates();
}
}
//setItemState(id);
//ui.randomServer->setChecked(info.useRandomServer);
+ // Update the capability-dependent UI in case capabilities have changed.
+ setNetworkCapStates(id);
ui.performEdit->setPlainText(info.perform.join("\n"));
ui.autoIdentify->setChecked(info.useAutoIdentify);
ui.autoIdentifyService->setText(info.autoIdentifyService);
ui.reconnectRetries->setValue(info.autoReconnectRetries);
ui.unlimitedRetries->setChecked(info.unlimitedReconnectRetries);
ui.rejoinOnReconnect->setChecked(info.rejoinChannels);
+ // Custom rate limiting
+ ui.unlimitedMessageRate->setChecked(info.unlimitedMessageRate);
+ // Set 'ui.useCustomMessageRate' after 'ui.unlimitedMessageRate' so if the latter is
+ // disabled, 'ui.messageRateDelayFrame' will remain disabled.
+ ui.useCustomMessageRate->setChecked(info.useCustomMessageRate);
+ ui.messageRateBurstSize->setValue(info.messageRateBurstSize);
+ // Convert milliseconds (integer) into seconds (double)
+ ui.messageRateDelay->setValue(info.messageRateDelay / 1000.0f);
}
else {
// just clear widgets
info.autoReconnectRetries = ui.reconnectRetries->value();
info.unlimitedReconnectRetries = ui.unlimitedRetries->isChecked();
info.rejoinChannels = ui.rejoinOnReconnect->isChecked();
+ // Custom rate limiting
+ info.useCustomMessageRate = ui.useCustomMessageRate->isChecked();
+ info.messageRateBurstSize = ui.messageRateBurstSize->value();
+ // Convert seconds (double) into milliseconds (integer)
+ info.messageRateDelay = static_cast<quint32>((ui.messageRateDelay->value() * 1000));
+ info.unlimitedMessageRate = ui.unlimitedMessageRate->isChecked();
+}
+
+
+void NetworksSettingsPage::clientNetworkCapsUpdated()
+{
+ // Grab the updated network
+ const Network *net = qobject_cast<const Network *>(sender());
+ if (!net) {
+ qWarning() << "Update request for unknown network received!";
+ return;
+ }
+ if (net->networkId() == currentId) {
+ // Network is currently shown. Update the capability-dependent UI in case capabilities have
+ // changed.
+ setNetworkCapStates(currentId);
+ }
}