+/******** IRCv3 Capability Negotiation ********/
+
+void CoreNetwork::addCap(const QString &capability, const QString &value)
+{
+ // Clear from pending list, add to supported list
+ if (!_capsSupported.contains(capability)) {
+ if (value != "") {
+ // Value defined, just use it
+ _capsSupported[capability] = value;
+ } else if (_capsPending.contains(capability)) {
+ // Value not defined, but a pending capability had a value.
+ // E.g. CAP * LS :sasl=PLAIN multi-prefix
+ // Preserve the capability value for later use.
+ _capsSupported[capability] = _capsPending[capability];
+ } else {
+ // No value ever given, assign to blank
+ _capsSupported[capability] = QString();
+ }
+ }
+ if (_capsPending.contains(capability))
+ _capsPending.remove(capability);
+
+ // Handle special cases here
+ // TODO Use events if it makes sense
+ if (capability == "away-notify") {
+ // away-notify enabled, stop the automatic timers, handle manually
+ setAutoWhoEnabled(false);
+ }
+}
+
+void CoreNetwork::removeCap(const QString &capability)
+{
+ // Clear from pending list, remove from supported list
+ if (_capsPending.contains(capability))
+ _capsPending.remove(capability);
+ if (_capsSupported.contains(capability))
+ _capsSupported.remove(capability);
+
+ // Handle special cases here
+ // TODO Use events if it makes sense
+ if (capability == "away-notify") {
+ // away-notify disabled, enable autowho according to configuration
+ setAutoWhoEnabled(networkConfig()->autoWhoEnabled());
+ }
+}
+
+QString CoreNetwork::capValue(const QString &capability) const
+{
+ // If a supported capability exists, good; if not, return pending value.
+ // If capability isn't supported after all, the pending entry will be removed.
+ if (_capsSupported.contains(capability))
+ return _capsSupported[capability];
+ else if (_capsPending.contains(capability))
+ return _capsPending[capability];
+ else
+ return QString();
+}
+
+void CoreNetwork::queuePendingCap(const QString &capability, const QString &value)
+{
+ if (!_capsQueued.contains(capability)) {
+ _capsQueued.append(capability);
+ // Some capabilities may have values attached, preserve them as pending
+ _capsPending[capability] = value;
+ }
+}
+
+QString CoreNetwork::takeQueuedCap()
+{
+ if (!_capsQueued.empty()) {
+ return _capsQueued.takeFirst();
+ } else {
+ return QString();
+ }
+}