summaryrefslogtreecommitdiffstats
path: root/libcommuni/src/core/ircconnection.cpp
diff options
context:
space:
mode:
authorMarkus Mittendrein <git@maxmitti.tk>2015-09-09 19:00:56 +0200
committerMarkus Mittendrein <git@maxmitti.tk>2015-09-09 19:02:23 +0200
commit8a6d4b06f2291c363f3dea17837ed20893852453 (patch)
treec091375499e35eaa1810586454e0834c06e6c9b2 /libcommuni/src/core/ircconnection.cpp
parentf554a27046f203e56a07baaf214d90834942e3f5 (diff)
downloadmanager-8a6d4b06f2291c363f3dea17837ed20893852453.tar.gz
manager-8a6d4b06f2291c363f3dea17837ed20893852453.zip
Cleanup repo with some directories
Diffstat (limited to 'libcommuni/src/core/ircconnection.cpp')
-rw-r--r--libcommuni/src/core/ircconnection.cpp1508
1 files changed, 0 insertions, 1508 deletions
diff --git a/libcommuni/src/core/ircconnection.cpp b/libcommuni/src/core/ircconnection.cpp
deleted file mode 100644
index 837aa16..0000000
--- a/libcommuni/src/core/ircconnection.cpp
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- Copyright (C) 2008-2014 The Communi Project
-
- You may use this file under the terms of BSD license as follows:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include "ircconnection.h"
-#include "ircconnection_p.h"
-#include "ircnetwork_p.h"
-#include "ircprotocol.h"
-#include "ircnetwork.h"
-#include "irccommand.h"
-#include "ircmessage.h"
-#include "ircfilter.h"
-#include "irc.h"
-#include <QLocale>
-#include <QDateTime>
-#include <QTcpSocket>
-#include <QTextCodec>
-#include <QStringList>
-#include <QMetaObject>
-#include <QMetaMethod>
-#include <QMetaEnum>
-#ifndef QT_NO_OPENSSL
-#include <QSslSocket>
-#include <QSslError>
-#endif // QT_NO_OPENSSL
-#include <QDataStream>
-#include <QVariantMap>
-
-IRC_BEGIN_NAMESPACE
-
-/*!
- \file ircconnection.h
- \brief \#include &lt;IrcConnection&gt;
- */
-
-/*!
- \class IrcConnection ircconnection.h IrcConnection
- \ingroup core
- \brief Provides means to establish a connection to an IRC server.
-
- \section connection-management Connection management
-
- Before \ref open() "opening" a connection, it must be first initialized
- with \ref host, \ref userName, \ref nickName and \ref realName.
-
- The connection status may be queried at any time via status(). Also
- \ref active "isActive()" and \ref connected "isConnected()" are provided
- for convenience. In addition to the \ref status "statusChanged()" signal,
- the most important statuses are informed via the following convenience
- signals:
- \li connecting() -
- The connection is being established.
- \li \ref connected "connected()" -
- The IRC connection has been established, and the server is ready to receive commands.
- \li disconnected() -
- The connection has been lost.
-
- \section receiving-messages Receiving messages
-
- Whenever a message is received from the server, the messageReceived()
- signal is emitted. Also message type specific signals are provided
- for convenience. See messageReceived() and IrcMessage and its
- subclasses for more details.
-
- \section sending-commands Sending commands
-
- Sending commands to a server is most conveniently done by creating
- them via the various static \ref IrcCommand "IrcCommand::createXxx()"
- methods and passing them to sendCommand(). Also sendData() is provided
- for more low-level access. See IrcCommand for more details.
-
- \section example Example
-
- \code
- IrcConnection* connection = new IrcConnection(this);
- connect(connection, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(onMessageReceived(IrcMessage*)));
- connection->setHost("irc.server.com");
- connection->setUserName("me");
- connection->setNickName("myself");
- connection->setRealName("And I");
- connection->sendCommand(IrcCommand::createJoin("#mine"));
- connection->open();
- \endcode
-
- \sa IrcNetwork, IrcMessage, IrcCommand
- */
-
-/*!
- \enum IrcConnection::Status
- This enum describes the connection status.
- */
-
-/*!
- \var IrcConnection::Inactive
- \brief The connection is inactive.
- */
-
-/*!
- \var IrcConnection::Waiting
- \brief The connection is waiting for a reconnect.
- */
-
-/*!
- \var IrcConnection::Connecting
- \brief The connection is being established.
- */
-
-/*!
- \var IrcConnection::Connected
- \brief The connection has been established.
- */
-
-/*!
- \var IrcConnection::Closing
- \brief The connection is being closed.
- */
-
-/*!
- \var IrcConnection::Closed
- \brief The connection has been closed.
- */
-
-/*!
- \var IrcConnection::Error
- \brief The connection has encountered an error.
- */
-
-/*!
- \fn void IrcConnection::connecting()
-
- This signal is emitted when the connection is being established.
-
- The underlying \ref socket has connected, but the IRC handshake is
- not yet finished and the server is not yet ready to receive commands.
- */
-
-/*!
- \fn void IrcConnection::nickNameRequired(const QString& reserved, QString* alternate)
-
- This signal is emitted when the requested nick name is \a reserved
- and an \a alternate nick name should be provided.
-
- An alternate nick name may be set via the provided argument, by changing
- the \ref nickName property, or by sending a nick command directly.
-
- \sa IrcCommand::createNick(), Irc::ERR_NICKNAMEINUSE, Irc::ERR_NICKCOLLISION
- */
-
-/*!
- \fn void IrcConnection::channelKeyRequired(const QString& channel, QString* key)
-
- This signal is emitted when joining a \a channel requires a \a key.
- The key may be set via the provided argument, or by sending a new
- join command directly.
-
- \sa IrcCommand::createJoin(), Irc::ERR_BADCHANNELKEY
- */
-
-/*!
- \fn void IrcConnection::disconnected()
-
- This signal is emitted when the connection has been lost.
- */
-
-/*!
- \fn void IrcConnection::socketError(QAbstractSocket::SocketError error)
-
- This signal is emitted when a \ref socket \a error occurs.
-
- \sa QAbstractSocket::error()
- */
-
-/*!
- \fn void IrcConnection::socketStateChanged(QAbstractSocket::SocketState state)
-
- This signal is emitted when the \a state of the underlying \ref socket changes.
-
- \sa QAbstractSocket::stateChanged()
- */
-
-/*!
- \since 3.2
- \fn void IrcConnection::secureError()
-
- This signal is emitted when SSL socket error occurs.
-
- Either QSslSocket::sslErrors() was emitted, or the remote host closed
- the connection without QSslSocket::sslErrors() being emitted meaning
- that the server is not SSL-enabled.
- */
-
-/*!
- \fn void IrcConnection::messageReceived(IrcMessage* message)
-
- This signal is emitted when a \a message is received.
-
- In addition, message type specific signals are provided for convenience:
- \li void <b>capabilityMessageReceived</b>(\ref IrcCapabilityMessage* message)
- \li void <b>errorMessageReceived</b>(\ref IrcErrorMessage* message)
- \li void <b>inviteMessageReceived</b>(\ref IrcInviteMessage* message)
- \li void <b>joinMessageReceived</b>(\ref IrcJoinMessage* message)
- \li void <b>kickMessageReceived</b>(\ref IrcKickMessage* message)
- \li void <b>modeMessageReceived</b>(\ref IrcModeMessage* message)
- \li void <b>namesMessageReceived</b>(\ref IrcNamesMessage* message)
- \li void <b>nickMessageReceived</b>(\ref IrcNickMessage* message)
- \li void <b>noticeMessageReceived</b>(\ref IrcNoticeMessage* message)
- \li void <b>numericMessageReceived</b>(\ref IrcNumericMessage* message)
- \li void <b>motdMessageReceived</b>(\ref IrcMotdMessage* message)
- \li void <b>partMessageReceived</b>(\ref IrcPartMessage* message)
- \li void <b>pingMessageReceived</b>(\ref IrcPingMessage* message)
- \li void <b>pongMessageReceived</b>(\ref IrcPongMessage* message)
- \li void <b>privateMessageReceived</b>(\ref IrcPrivateMessage* message)
- \li void <b>quitMessageReceived</b>(\ref IrcQuitMessage* message)
- \li void <b>topicMessageReceived</b>(\ref IrcTopicMessage* message)
- */
-
-#ifndef IRC_DOXYGEN
-template<typename T>
-static void irc_debug(IrcConnection* connection, const char* msg, const T& arg)
-{
- static bool dbg = qgetenv("IRC_DEBUG").toInt();
- if (dbg) {
- const QString desc = QString::fromLatin1("IrcConnection(%1)").arg(connection->displayName());
- qDebug() << qPrintable(desc) << msg << arg;
- }
-}
-
-IrcConnectionPrivate::IrcConnectionPrivate() :
- q_ptr(0),
- encoding("ISO-8859-15"),
- network(0),
- protocol(0),
- socket(0),
- host(),
- port(6667),
- userName(),
- nickName(),
- realName(),
- enabled(true),
- status(IrcConnection::Inactive),
- sslErrors(false),
- closed(false)
-{
-}
-
-void IrcConnectionPrivate::init(IrcConnection* connection)
-{
- q_ptr = connection;
- network = IrcNetworkPrivate::create(connection);
- connection->setSocket(new QTcpSocket(connection));
- connection->setProtocol(new IrcProtocol(connection));
- QObject::connect(&reconnecter, SIGNAL(timeout()), connection, SLOT(_irc_reconnect()));
-}
-
-void IrcConnectionPrivate::_irc_connected()
-{
- Q_Q(IrcConnection);
- closed = false;
- sslErrors = false;
- emit q->connecting();
- if (q->isSecure())
- QMetaObject::invokeMethod(socket, "startClientEncryption");
- protocol->open();
-}
-
-void IrcConnectionPrivate::_irc_disconnected()
-{
- Q_Q(IrcConnection);
- protocol->close();
- emit q->disconnected();
- if (enabled && !sslErrors && (status != IrcConnection::Closed || !closed) && !reconnecter.isActive() && reconnecter.interval() > 0) {
- reconnecter.start();
- setStatus(IrcConnection::Waiting);
- }
-}
-
-void IrcConnectionPrivate::_irc_error(QAbstractSocket::SocketError error)
-{
- Q_Q(IrcConnection);
- if (!closed && !sslErrors && error == QAbstractSocket::RemoteHostClosedError && q->isSecure()) {
- irc_debug(q, "SSL error:", "no SSL available");
- setStatus(IrcConnection::Error);
- sslErrors = true;
- emit q->secureError();
- } else if (!closed || (error != QAbstractSocket::RemoteHostClosedError && error != QAbstractSocket::UnknownSocketError)) {
- irc_debug(q, "socket error:", error);
- emit q->socketError(error);
- setStatus(IrcConnection::Error);
- }
-}
-
-void IrcConnectionPrivate::_irc_sslErrors()
-{
- Q_Q(IrcConnection);
- QStringList errors;
-#ifndef QT_NO_OPENSSL
- QSslSocket* ssl = qobject_cast<QSslSocket*>(socket);
- if (ssl) {
- foreach (const QSslError& error, ssl->sslErrors())
- errors += error.errorString();
- }
-#endif
- irc_debug(q, "SSL handshake errors:", errors);
- sslErrors = true;
- emit q->secureError();
-}
-
-void IrcConnectionPrivate::_irc_state(QAbstractSocket::SocketState state)
-{
- Q_Q(IrcConnection);
- switch (state) {
- case QAbstractSocket::UnconnectedState:
- if (closed)
- setStatus(IrcConnection::Closed);
- break;
- case QAbstractSocket::ClosingState:
- if (status != IrcConnection::Error)
- setStatus(IrcConnection::Closing);
- break;
- case QAbstractSocket::HostLookupState:
- case QAbstractSocket::ConnectingState:
- case QAbstractSocket::ConnectedState:
- default:
- setStatus(IrcConnection::Connecting);
- break;
- }
- emit q->socketStateChanged(state);
-}
-
-void IrcConnectionPrivate::_irc_reconnect()
-{
- Q_Q(IrcConnection);
- if (!q->isActive()) {
- reconnecter.stop();
- q->open();
- }
-}
-
-void IrcConnectionPrivate::_irc_readData()
-{
- protocol->read();
-}
-
-void IrcConnectionPrivate::_irc_filterDestroyed(QObject* filter)
-{
- messageFilters.removeAll(filter);
- commandFilters.removeAll(filter);
-}
-
-void IrcConnectionPrivate::setNick(const QString& nick)
-{
- Q_Q(IrcConnection);
- if (nickName != nick) {
- nickName = nick;
- emit q->nickNameChanged(nick);
- }
-}
-
-void IrcConnectionPrivate::setStatus(IrcConnection::Status value)
-{
- Q_Q(IrcConnection);
- if (status != value) {
- const bool wasConnected = q->isConnected();
- status = value;
- emit q->statusChanged(value);
-
- if (!wasConnected && q->isConnected()) {
- emit q->connected();
- foreach (IrcCommand* cmd, pendingCommands)
- q->sendCommand(cmd);
- pendingCommands.clear();
- }
- irc_debug(q, "status:", status);
- }
-}
-
-void IrcConnectionPrivate::setInfo(const QHash<QString, QString>& info)
-{
- Q_Q(IrcConnection);
- const QString oldName = q->displayName();
- IrcNetworkPrivate* priv = IrcNetworkPrivate::get(network);
- priv->setInfo(info);
- const QString newName = q->displayName();
- if (oldName != newName)
- emit q->displayNameChanged(newName);
-}
-
-void IrcConnectionPrivate::receiveMessage(IrcMessage* msg)
-{
- Q_Q(IrcConnection);
- bool filtered = false;
- for (int i = messageFilters.count() - 1; !filtered && i >= 0; --i) {
- IrcMessageFilter* filter = qobject_cast<IrcMessageFilter*>(messageFilters.at(i));
- if (filter)
- filtered |= filter->messageFilter(msg);
- }
-
- if (!filtered) {
- emit q->messageReceived(msg);
-
- switch (msg->type()) {
- case IrcMessage::Nick:
- emit q->nickMessageReceived(static_cast<IrcNickMessage*>(msg));
- break;
- case IrcMessage::Quit:
- emit q->quitMessageReceived(static_cast<IrcQuitMessage*>(msg));
- break;
- case IrcMessage::Join:
- emit q->joinMessageReceived(static_cast<IrcJoinMessage*>(msg));
- break;
- case IrcMessage::Part:
- emit q->partMessageReceived(static_cast<IrcPartMessage*>(msg));
- break;
- case IrcMessage::Topic:
- emit q->topicMessageReceived(static_cast<IrcTopicMessage*>(msg));
- break;
- case IrcMessage::WhoReply:
- emit q->whoReplyMessageReceived(static_cast<IrcWhoReplyMessage*>(msg));
- break;
- case IrcMessage::Invite:
- emit q->inviteMessageReceived(static_cast<IrcInviteMessage*>(msg));
- break;
- case IrcMessage::Kick:
- emit q->kickMessageReceived(static_cast<IrcKickMessage*>(msg));
- break;
- case IrcMessage::Mode:
- emit q->modeMessageReceived(static_cast<IrcModeMessage*>(msg));
- break;
- case IrcMessage::Private:
- emit q->privateMessageReceived(static_cast<IrcPrivateMessage*>(msg));
- break;
- case IrcMessage::Notice:
- emit q->noticeMessageReceived(static_cast<IrcNoticeMessage*>(msg));
- break;
- case IrcMessage::Ping:
- emit q->pingMessageReceived(static_cast<IrcPingMessage*>(msg));
- break;
- case IrcMessage::Pong:
- emit q->pongMessageReceived(static_cast<IrcPongMessage*>(msg));
- break;
- case IrcMessage::Error:
- emit q->errorMessageReceived(static_cast<IrcErrorMessage*>(msg));
- break;
- case IrcMessage::Numeric:
- emit q->numericMessageReceived(static_cast<IrcNumericMessage*>(msg));
- break;
- case IrcMessage::Capability:
- emit q->capabilityMessageReceived(static_cast<IrcCapabilityMessage*>(msg));
- break;
- case IrcMessage::Motd:
- emit q->motdMessageReceived(static_cast<IrcMotdMessage*>(msg));
- break;
- case IrcMessage::Names:
- emit q->namesMessageReceived(static_cast<IrcNamesMessage*>(msg));
- break;
- case IrcMessage::Unknown:
- default:
- break;
- }
- }
- msg->deleteLater();
-}
-
-IrcCommand* IrcConnectionPrivate::createCtcpReply(IrcPrivateMessage* request)
-{
- Q_Q(IrcConnection);
- IrcCommand* reply = 0;
- const QMetaObject* metaObject = q->metaObject();
- int idx = metaObject->indexOfMethod("createCtcpReply(QVariant)");
- if (idx != -1) {
- // QML: QVariant createCtcpReply(QVariant)
- QVariant ret;
- QMetaMethod method = metaObject->method(idx);
- method.invoke(q, Q_RETURN_ARG(QVariant, ret), Q_ARG(QVariant, QVariant::fromValue(request)));
- reply = ret.value<IrcCommand*>();
- } else {
- // C++: IrcCommand* createCtcpReply(IrcPrivateMessage*)
- idx = metaObject->indexOfMethod("createCtcpReply(IrcPrivateMessage*)");
- QMetaMethod method = metaObject->method(idx);
- method.invoke(q, Q_RETURN_ARG(IrcCommand*, reply), Q_ARG(IrcPrivateMessage*, request));
- }
- return reply;
-}
-#endif // IRC_DOXYGEN
-
-/*!
- Constructs a new IRC connection with \a parent.
- */
-IrcConnection::IrcConnection(QObject* parent) : QObject(parent), d_ptr(new IrcConnectionPrivate)
-{
- Q_D(IrcConnection);
- d->init(this);
-}
-
-/*!
- Constructs a new IRC connection with \a host and \a parent.
- */
-IrcConnection::IrcConnection(const QString& host, QObject* parent) : QObject(parent), d_ptr(new IrcConnectionPrivate)
-{
- Q_D(IrcConnection);
- d->init(this);
- setHost(host);
-}
-
-/*!
- Destructs the IRC connection.
- */
-IrcConnection::~IrcConnection()
-{
- close();
- emit destroyed(this);
-}
-
-/*!
- This property holds the FALLBACK encoding for received messages.
-
- The fallback encoding is used when the message is detected not
- to be valid \c UTF-8 and the consequent auto-detection of message
- encoding fails. See QTextCodec::availableCodecs() for the list of
- supported encodings.
-
- The default value is \c ISO-8859-15.
-
- \par Access functions:
- \li QByteArray <b>encoding</b>() const
- \li void <b>setEncoding</b>(const QByteArray& encoding)
-
- \sa QTextCodec::availableCodecs(), QTextCodec::codecForLocale()
- */
-QByteArray IrcConnection::encoding() const
-{
- Q_D(const IrcConnection);
- return d->encoding;
-}
-
-void IrcConnection::setEncoding(const QByteArray& encoding)
-{
- Q_D(IrcConnection);
- extern bool irc_is_supported_encoding(const QByteArray& encoding); // ircmessagedecoder.cpp
- if (!irc_is_supported_encoding(encoding)) {
- qWarning() << "IrcConnection::setEncoding(): unsupported encoding" << encoding;
- return;
- }
- d->encoding = encoding;
-}
-
-/*!
- This property holds the server host.
-
- \par Access functions:
- \li QString <b>host</b>() const
- \li void <b>setHost</b>(const QString& host)
-
- \par Notifier signal:
- \li void <b>hostChanged</b>(const QString& host)
- */
-QString IrcConnection::host() const
-{
- Q_D(const IrcConnection);
- return d->host;
-}
-
-void IrcConnection::setHost(const QString& host)
-{
- Q_D(IrcConnection);
- if (d->host != host) {
- if (isActive())
- qWarning("IrcConnection::setHost() has no effect until re-connect");
- const QString oldName = displayName();
- d->host = host;
- emit hostChanged(host);
- const QString newName = displayName();
- if (oldName != newName)
- emit displayNameChanged(newName);
- }
-}
-
-/*!
- This property holds the server port.
-
- The default value is \c 6667.
-
- \par Access functions:
- \li int <b>port</b>() const
- \li void <b>setPort</b>(int port)
-
- \par Notifier signal:
- \li void <b>portChanged</b>(int port)
- */
-int IrcConnection::port() const
-{
- Q_D(const IrcConnection);
- return d->port;
-}
-
-void IrcConnection::setPort(int port)
-{
- Q_D(IrcConnection);
- if (d->port != port) {
- if (isActive())
- qWarning("IrcConnection::setPort() has no effect until re-connect");
- d->port = port;
- emit portChanged(port);
- }
-}
-
-/*!
- This property holds the user name.
-
- \note Changing the user name has no effect until the connection is re-established.
-
- \par Access functions:
- \li QString <b>userName</b>() const
- \li void <b>setUserName</b>(const QString& name)
-
- \par Notifier signal:
- \li void <b>userNameChanged</b>(const QString& name)
- */
-QString IrcConnection::userName() const
-{
- Q_D(const IrcConnection);
- return d->userName;
-}
-
-void IrcConnection::setUserName(const QString& name)
-{
- Q_D(IrcConnection);
- QString user = name.split(" ", QString::SkipEmptyParts).value(0).trimmed();
- if (d->userName != user) {
- if (isActive())
- qWarning("IrcConnection::setUserName() has no effect until re-connect");
- d->userName = user;
- emit userNameChanged(user);
- }
-}
-
-/*!
- This property holds the nick name.
-
- \par Access functions:
- \li QString <b>nickName</b>() const
- \li void <b>setNickName</b>(const QString& name)
-
- \par Notifier signal:
- \li void <b>nickNameChanged</b>(const QString& name)
- */
-QString IrcConnection::nickName() const
-{
- Q_D(const IrcConnection);
- return d->nickName;
-}
-
-void IrcConnection::setNickName(const QString& name)
-{
- Q_D(IrcConnection);
- QString nick = name.split(" ", QString::SkipEmptyParts).value(0).trimmed();
- if (d->nickName != nick) {
- if (isActive())
- sendCommand(IrcCommand::createNick(nick));
- else
- d->setNick(nick);
- }
-}
-
-/*!
- This property holds the real name.
-
- \note Changing the real name has no effect until the connection is re-established.
-
- \par Access functions:
- \li QString <b>realName</b>() const
- \li void <b>setRealName</b>(const QString& name)
-
- \par Notifier signal:
- \li void <b>realNameChanged</b>(const QString& name)
- */
-QString IrcConnection::realName() const
-{
- Q_D(const IrcConnection);
- return d->realName;
-}
-
-void IrcConnection::setRealName(const QString& name)
-{
- Q_D(IrcConnection);
- if (d->realName != name) {
- if (isActive())
- qWarning("IrcConnection::setRealName() has no effect until re-connect");
- d->realName = name;
- emit realNameChanged(name);
- }
-}
-
-/*!
- This property holds the password.
-
- \par Access functions:
- \li QString <b>password</b>() const
- \li void <b>setPassword</b>(const QString& password)
-
- \par Notifier signal:
- \li void <b>passwordChanged</b>(const QString& password)
- */
-QString IrcConnection::password() const
-{
- Q_D(const IrcConnection);
- return d->password;
-}
-
-void IrcConnection::setPassword(const QString& password)
-{
- Q_D(IrcConnection);
- if (d->password != password) {
- if (isActive())
- qWarning("IrcConnection::setPassword() has no effect until re-connect");
- d->password = password;
- emit passwordChanged(password);
- }
-}
-
-/*!
- This property holds the display name.
-
- Unless explicitly set, display name resolves to IrcNetwork::name
- or IrcConnection::host while the former is not known.
-
- \par Access functions:
- \li QString <b>displayName</b>() const
- \li void <b>setDisplayName</b>(const QString& name)
-
- \par Notifier signal:
- \li void <b>displayNameChanged</b>(const QString& name)
- */
-QString IrcConnection::displayName() const
-{
- Q_D(const IrcConnection);
- QString name = d->displayName;
- if (name.isEmpty())
- name = d->network->name();
- if (name.isEmpty())
- name = d->host;
- return name;
-}
-
-void IrcConnection::setDisplayName(const QString& name)
-{
- Q_D(IrcConnection);
- if (d->displayName != name) {
- d->displayName = name;
- emit displayNameChanged(name);
- }
-}
-
-/*!
- \since 3.1
-
- This property holds arbitrary user data.
-
- \par Access functions:
- \li QVariantMap <b>userData</b>() const
- \li void <b>setUserData</b>(const QVariantMap& data)
-
- \par Notifier signal:
- \li void <b>userDataChanged</b>(const QVariantMap& data)
- */
-QVariantMap IrcConnection::userData() const
-{
- Q_D(const IrcConnection);
- return d->userData;
-}
-
-void IrcConnection::setUserData(const QVariantMap& data)
-{
- Q_D(IrcConnection);
- if (d->userData != data) {
- d->userData = data;
- emit userDataChanged(data);
- }
-}
-
-/*!
- \property Status IrcConnection::status
- This property holds the connection status.
-
- \par Access function:
- \li Status <b>status</b>() const
-
- \par Notifier signal:
- \li void <b>statusChanged</b>(Status status)
- */
-IrcConnection::Status IrcConnection::status() const
-{
- Q_D(const IrcConnection);
- return d->status;
-}
-
-/*!
- \property bool IrcConnection::active
- This property holds whether the connection is active.
-
- The connection is considered active when its either connecting, connected or closing.
-
- \par Access function:
- \li bool <b>isActive</b>() const
- */
-bool IrcConnection::isActive() const
-{
- Q_D(const IrcConnection);
- return d->status == Connecting || d->status == Connected || d->status == Closing;
-}
-
-/*!
- \property bool IrcConnection::connected
- This property holds whether the connection has been established.
-
- The connection has been established when the welcome message
- has been received and the server is ready to receive commands.
-
- \sa Irc::RPL_WELCOME
-
- \par Access function:
- \li bool <b>isConnected</b>() const
-
- \par Notifier signal:
- \li void <b>connected</b>()
- */
-bool IrcConnection::isConnected() const
-{
- Q_D(const IrcConnection);
- return d->status == Connected;
-}
-
-/*!
- \property bool IrcConnection::enabled
- This property holds whether the connection is enabled.
-
- The default value is \c true.
-
- When set to \c false, a disabled connection does nothing when open() is called.
-
- \par Access functions:
- \li bool <b>isEnabled</b>() const
- \li void <b>setEnabled</b>(bool enabled) [slot]
- \li void <b>setDisabled</b>(bool disabled) [slot]
-
- \par Notifier signal:
- \li void <b>enabledChanged</b>(bool enabled)
- */
-bool IrcConnection::isEnabled() const
-{
- Q_D(const IrcConnection);
- return d->enabled;
-}
-
-void IrcConnection::setEnabled(bool enabled)
-{
- Q_D(IrcConnection);
- if (d->enabled != enabled) {
- d->enabled = enabled;
- emit enabledChanged(enabled);
- }
-}
-
-void IrcConnection::setDisabled(bool disabled)
-{
- setEnabled(!disabled);
-}
-
-/*!
- \property int IrcConnection::reconnectDelay
- This property holds the reconnect delay in seconds.
-
- A positive (greater than zero) value enables automatic reconnect.
- When the connection is lost due to a socket error, IrcConnection
- will automatically attempt to reconnect after the specified delay.
-
- The default value is \c 0 (automatic reconnect disabled).
-
- \par Access functions:
- \li int <b>reconnectDelay</b>() const
- \li void <b>setReconnectDelay</b>(int seconds)
-
- \par Notifier signal:
- \li void <b>reconnectDelayChanged</b>(int seconds)
- */
-int IrcConnection::reconnectDelay() const
-{
- Q_D(const IrcConnection);
- return d->reconnecter.interval() / 1000;
-}
-
-void IrcConnection::setReconnectDelay(int seconds)
-{
- Q_D(IrcConnection);
- const int interval = qMax(0, seconds) * 1000;
- if (d->reconnecter.interval() != interval) {
- d->reconnecter.setInterval(interval);
- emit reconnectDelayChanged(interval);
- }
-}
-
-/*!
- This property holds the socket. The default value is an instance of QTcpSocket.
-
- The previously set socket is deleted if its parent is \c this.
-
- \note IrcConnection supports QSslSocket in the way that it automatically
- calls QSslSocket::startClientEncryption() while connecting.
-
- \par Access functions:
- \li \ref QAbstractSocket* <b>socket</b>() const
- \li void <b>setSocket</b>(\ref QAbstractSocket* socket)
-
- \sa IrcConnection::secure
- */
-QAbstractSocket* IrcConnection::socket() const
-{
- Q_D(const IrcConnection);
- return d->socket;
-}
-
-void IrcConnection::setSocket(QAbstractSocket* socket)
-{
- Q_D(IrcConnection);
- if (d->socket != socket) {
- if (d->socket) {
- d->socket->disconnect(this);
- if (d->socket->parent() == this)
- d->socket->deleteLater();
- }
-
- d->socket = socket;
- if (socket) {
- connect(socket, SIGNAL(connected()), this, SLOT(_irc_connected()));
- connect(socket, SIGNAL(disconnected()), this, SLOT(_irc_disconnected()));
- connect(socket, SIGNAL(readyRead()), this, SLOT(_irc_readData()));
- connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_irc_error(QAbstractSocket::SocketError)));
- connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(_irc_state(QAbstractSocket::SocketState)));
- if (isSecure())
- connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(_irc_sslErrors()));
- }
- }
-}
-
-/*!
- \property bool IrcConnection::secure
- This property holds whether the socket is an SSL socket.
-
- This property is provided for convenience. Calling
- \code
- connection->setSecure(true);
- \endcode
-
- is equivalent to:
-
- \code
- QSslSocket* socket = new QSslSocket(socket);
- socket->setPeerVerifyMode(QSslSocket::QueryPeer);
- connection->setSocket(socket);
- \endcode
-
- \note IrcConnection does not handle SSL errors, see
- QSslSocket::sslErrors() for more details on the subject.
-
- \par Access functions:
- \li bool <b>isSecure</b>() const
- \li void <b>setSecure</b>(bool secure)
-
- \par Notifier signal:
- \li void <b>secureChanged</b>(bool secure)
-
- \sa secureSupported, IrcConnection::socket
- */
-bool IrcConnection::isSecure() const
-{
-#ifdef QT_NO_OPENSSL
- return false;
-#else
- return qobject_cast<QSslSocket*>(socket());
-#endif // QT_NO_OPENSSL
-}
-
-void IrcConnection::setSecure(bool secure)
-{
-#ifdef QT_NO_OPENSSL
- if (secure) {
- qWarning("IrcConnection::setSecure(): the Qt build does not support SSL");
- return;
- }
-#else
- if (secure && !QSslSocket::supportsSsl()) {
- qWarning("IrcConnection::setSecure(): the platform does not support SSL - try installing OpenSSL");
- return;
- }
-
- QSslSocket* sslSocket = qobject_cast<QSslSocket*>(socket());
- if (secure && !sslSocket) {
- sslSocket = new QSslSocket(this);
- sslSocket->setPeerVerifyMode(QSslSocket::QueryPeer);
- setSocket(sslSocket);
- emit secureChanged(true);
- } else if (!secure && sslSocket) {
- setSocket(new QTcpSocket(this));
- emit secureChanged(false);
- }
-#endif // !QT_NO_OPENSSL
-}
-
-/*!
- \since 3.2
- \property bool IrcConnection::secureSupported
- This property holds whether SSL is supported.
-
- The value may be \c false for the following reasons:
- \li Qt was built without SSL support (\c QT_NO_SSL is defined), or
- \li The platform does not support SSL (QSslSocket::supportsSsl() returns \c false).
-
- \par Access function:
- \li static bool <b>isSecureSupported</b>()
-
- \sa secure, QSslSocket::supportsSsl()
- */
-
-bool IrcConnection::isSecureSupported()
-{
-#ifdef QT_NO_OPENSSL
- return false;
-#else
- return QSslSocket::supportsSsl();
-#endif
-}
-
-/*!
- This property holds the used SASL (Simple Authentication and Security Layer) mechanism.
-
- \par Access functions:
- \li QString <b>saslMechanism</b>() const
- \li void <b>setSaslMechanism</b>(const QString& mechanism)
-
- \par Notifier signal:
- \li void <b>saslMechanismChanged</b>(const QString& mechanism)
-
- \sa supportedSaslMechanisms
- */
-QString IrcConnection::saslMechanism() const
-{
- Q_D(const IrcConnection);
- return d->saslMechanism;
-}
-
-void IrcConnection::setSaslMechanism(const QString& mechanism)
-{
- Q_D(IrcConnection);
- if (!mechanism.isEmpty() && !supportedSaslMechanisms().contains(mechanism.toUpper())) {
- qWarning("IrcConnection::setSaslMechanism(): unsupported mechanism: '%s'", qPrintable(mechanism));
- return;
- }
- if (d->saslMechanism != mechanism) {
- if (isActive())
- qWarning("IrcConnection::setSaslMechanism() has no effect until re-connect");
- d->saslMechanism = mechanism.toUpper();
- emit saslMechanismChanged(mechanism);
- }
-}
-
-/*!
- This property holds the list of supported SASL (Simple Authentication and Security Layer) mechanisms.
-
- \par Access function:
- \li static QStringList <b>supportedSaslMechanisms</b>()
-
- \sa saslMechanism
- */
-QStringList IrcConnection::supportedSaslMechanisms()
-{
- return QStringList() << QLatin1String("PLAIN");
-}
-
-/*!
- This property holds the network information.
-
- \par Access function:
- \li IrcNetwork* <b>network</b>() const
- */
-IrcNetwork* IrcConnection::network() const
-{
- Q_D(const IrcConnection);
- return d->network;
-}
-
-/*!
- Opens a connection to the server.
-
- The function does nothing when the connection is already \ref active
- or explicitly \ref enabled "disabled".
-
- \note The function merely outputs a warnings and returns immediately if
- either \ref host, \ref userName, \ref nickName or \ref realName is empty.
- */
-void IrcConnection::open()
-{
- Q_D(IrcConnection);
- if (d->host.isEmpty()) {
- qWarning("IrcConnection::open(): host is empty!");
- return;
- }
- if (d->userName.isEmpty()) {
- qWarning("IrcConnection::open(): userName is empty!");
- return;
- }
- if (d->nickName.isEmpty()) {
- qWarning("IrcConnection::open(): nickName is empty!");
- return;
- }
- if (d->realName.isEmpty()) {
- qWarning("IrcConnection::open(): realName is empty!");
- return;
- }
- if (d->enabled && d->socket && !isActive())
- d->socket->connectToHost(d->host, d->port);
-}
-
-/*!
- Immediately closes the connection to the server.
-
- Calling close() makes the connection close immediately and thus might lead to
- "remote host closed the connection". In order to quit gracefully, call quit()
- first. This function attempts to flush the underlying socket, but this does
- not guarantee that the server ever receives the QUIT command if the connection
- is closed immediately after sending the command. In order to ensure a graceful
- quit, let the server handle closing the connection.
-
- C++ example:
- \code
- connection->quit(reason);
- QTimer::singleShot(timeout, connection, SLOT(deleteLater()));
- \endcode
-
- QML example:
- \code
- connection.quit(reason);
- connection.destroy(timeout);
- \endcode
-
- \sa quit()
- */
-void IrcConnection::close()
-{
- Q_D(IrcConnection);
- if (d->socket) {
- d->closed = true;
- d->socket->flush();
- d->socket->abort();
- d->socket->disconnectFromHost();
- if (d->socket->state() == QAbstractSocket::UnconnectedState)
- d->setStatus(Closed);
- d->reconnecter.stop();
- }
-}
-
-/*!
- Sends a quit command with an optionally specified \a reason.
-
- This method is provided for convenience. It is equal to:
- \code
- IrcCommand* command = IrcCommand::createQuit(reason);
- connection->sendCommand(command);
- \endcode
-
- \sa IrcCommand::createQuit()
- */
-void IrcConnection::quit(const QString& reason)
-{
- sendCommand(IrcCommand::createQuit(reason));
-}
-
-/*!
- Sends a \a command to the server.
-
- If the connection is not active, the \a command is queued and sent
- later when the connection has been established.
-
- \note If the command has a valid parent, it is an indication that
- the caller of this method is be responsible for freeing the command.
- If the command does not have a valid parent (like the commands
- created via various IrcCommand::createXxx() methods) the connection
- will take ownership of the command and delete it once it has been
- sent. Thus, the command must have been allocated on the heap and
- it is not safe to access the command after it has been sent.
-
- \sa sendData()
- */
-bool IrcConnection::sendCommand(IrcCommand* command)
-{
- Q_D(IrcConnection);
- bool res = false;
- if (command) {
- bool filtered = false;
- for (int i = d->commandFilters.count() - 1; !filtered && i >= 0; --i) {
- QObject* filter = d->commandFilters.at(i);
- IrcCommandFilter* commandFilter = qobject_cast<IrcCommandFilter*>(filter);
- if (commandFilter && !d->activeCommandFilters.contains(filter)) {
- d->activeCommandFilters.push(filter);
- filtered |= commandFilter->commandFilter(command);
- d->activeCommandFilters.pop();
- }
- }
- if (filtered)
- return false;
-
- if (isActive()) {
- QTextCodec* codec = QTextCodec::codecForName(command->encoding());
- Q_ASSERT(codec);
- res = sendData(codec->fromUnicode(command->toString()));
- if (!command->parent())
- command->deleteLater();
- } else {
- Q_D(IrcConnection);
- d->pendingCommands += command;
- }
- }
- return res;
-}
-
-/*!
- Sends raw \a data to the server.
-
- \sa sendCommand()
- */
-bool IrcConnection::sendData(const QByteArray& data)
-{
- Q_D(IrcConnection);
- if (d->socket) {
- static bool dbg = qgetenv("IRC_DEBUG").toInt();
- if (dbg) qDebug() << "->" << data;
- if (!d->closed && data.length() >= 4) {
- const QByteArray cmd = data.left(5).toUpper();
- if (cmd.startsWith("QUIT") && (data.length() == 4 || QChar(data.at(4)).isSpace()))
- d->closed = true;
- }
- return d->protocol->write(data);
- }
- return false;
-}
-
-/*!
- Sends raw \a message to the server using UTF-8 encoding.
-
- \sa sendData(), sendCommand()
- */
-bool IrcConnection::sendRaw(const QString& message)
-{
- return sendData(message.toUtf8());
-}
-
-/*!
- Installs a message \a filter on the connection. The \a filter must implement the IrcMessageFilter interface.
-
- A message filter receives all messages that are sent to the connection. The filter
- receives messages via the \ref IrcMessageFilter::messageFilter() "messageFilter()"
- function. The function must return \c true if the message should be filtered,
- (i.e. stopped); otherwise it must return \c false.
-
- If multiple message filters are installed on the same connection, the filter
- that was installed last is activated first.
-
- \sa removeMessageFilter()
- */
-void IrcConnection::installMessageFilter(QObject* filter)
-{
- Q_D(IrcConnection);
- IrcMessageFilter* msgFilter = qobject_cast<IrcMessageFilter*>(filter);
- if (msgFilter) {
- d->messageFilters += filter;
- connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)), Qt::UniqueConnection);
- }
-}
-
-/*!
- Removes a message \a filter from the connection.
-
- The request is ignored if such message filter has not been installed.
- All message filters for a connection are automatically removed
- when the connection is destroyed.
-
- \sa installMessageFilter()
- */
-void IrcConnection::removeMessageFilter(QObject* filter)
-{
- Q_D(IrcConnection);
- IrcMessageFilter* msgFilter = qobject_cast<IrcMessageFilter*>(filter);
- if (msgFilter) {
- d->messageFilters.removeAll(filter);
- disconnect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)));
- }
-}
-
-/*!
- Installs a command \a filter on the connection. The \a filter must implement the IrcCommandFilter interface.
-
- A command filter receives all commands that are sent from the connection. The filter
- receives commands via the \ref IrcCommandFilter::commandFilter() "commandFilter()"
- function. The function must return \c true if the command should be filtered,
- (i.e. stopped); otherwise it must return \c false.
-
- If multiple command filters are installed on the same connection, the filter
- that was installed last is activated first.
-
- \sa removeCommandFilter()
- */
-void IrcConnection::installCommandFilter(QObject* filter)
-{
- Q_D(IrcConnection);
- IrcCommandFilter* cmdFilter = qobject_cast<IrcCommandFilter*>(filter);
- if (cmdFilter) {
- d->commandFilters += filter;
- connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)), Qt::UniqueConnection);
- }
-}
-
-/*!
- Removes a command \a filter from the connection.
-
- The request is ignored if such command filter has not been installed.
- All command filters for a connection are automatically removed when
- the connection is destroyed.
-
- \sa installCommandFilter()
- */
-void IrcConnection::removeCommandFilter(QObject* filter)
-{
- Q_D(IrcConnection);
- IrcCommandFilter* cmdFilter = qobject_cast<IrcCommandFilter*>(filter);
- if (cmdFilter) {
- d->commandFilters.removeAll(filter);
- disconnect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)));
- }
-}
-
-/*!
- \since 3.1
-
- Saves the state of the connection. The \a version number is stored as part of the state data.
-
- To restore the saved state, pass the return value and \a version number to restoreState().
- */
-QByteArray IrcConnection::saveState(int version) const
-{
- QVariantMap args;
- args.insert("version", version);
- args.insert("host", host());
- args.insert("port", port());
- args.insert("userName", userName());
- args.insert("nickName", nickName());
- args.insert("realName", realName());
- args.insert("password", password());
- args.insert("displayName", displayName());
- args.insert("userData", userData());
- args.insert("encoding", encoding());
- args.insert("enabled", isEnabled());
- args.insert("reconnectDelay", reconnectDelay());
- args.insert("secure", isSecure());
- args.insert("saslMechanism", saslMechanism());
-
- QByteArray state;
- QDataStream out(&state, QIODevice::WriteOnly);
- out << args;
- return state;
-}
-
-/*!
- \since 3.1
-
- Restores the \a state of the connection. The \a version number is compared with that stored in \a state.
- If they do not match, the connection state is left unchanged, and this function returns \c false; otherwise,
- the state is restored, and \c true is returned.
-
- \sa saveState()
- */
-bool IrcConnection::restoreState(const QByteArray& state, int version)
-{
- if (isActive())
- return false;
-
- QVariantMap args;
- QDataStream in(state);
- in >> args;
- if (in.status() != QDataStream::Ok || args.value("version", -1).toInt() != version)
- return false;
-
- setHost(args.value("host", host()).toString());
- setPort(args.value("port", port()).toInt());
- setUserName(args.value("userName", userName()).toString());
- setNickName(args.value("nickName", nickName()).toString());
- setRealName(args.value("realName", realName()).toString());
- setPassword(args.value("password", password()).toString());
- setDisplayName(args.value("displayName").toString());
- setUserData(args.value("userData", userData()).toMap());
- setEncoding(args.value("encoding", encoding()).toByteArray());
- setEnabled(args.value("enabled", isEnabled()).toBool());
- setReconnectDelay(args.value("reconnectDelay", reconnectDelay()).toInt());
- setSecure(args.value("secure", isSecure()).toBool());
- setSaslMechanism(args.value("saslMechanism", saslMechanism()).toString());
- return true;
-}
-
-/*!
- Creates a reply command for the CTCP \a request.
-
- The default implementation handles the following CTCP requests: CLIENTINFO, PING, SOURCE, TIME and VERSION.
-
- Reimplement this function in order to alter or omit the default replies.
- */
-IrcCommand* IrcConnection::createCtcpReply(IrcPrivateMessage* request) const
-{
- QString reply;
- QString type = request->content().split(" ", QString::SkipEmptyParts).value(0).toUpper();
- if (type == "PING")
- reply = request->content();
- else if (type == "TIME")
- reply = QLatin1String("TIME ") + QLocale().toString(QDateTime::currentDateTime(), QLocale::ShortFormat);
- else if (type == "VERSION")
- reply = QLatin1String("VERSION Using libcommuni ") + Irc::version() + QLatin1String(" - http://communi.github.com");
- else if (type == "SOURCE")
- reply = QLatin1String("SOURCE http://communi.github.com");
- else if (type == "CLIENTINFO")
- reply = QLatin1String("CLIENTINFO PING SOURCE TIME VERSION");
- if (!reply.isEmpty())
- return IrcCommand::createCtcpReply(request->nick(), reply);
- return 0;
-}
-
-/*!
- \since 3.2
-
- This property holds the protocol.
-
- The previously set protocol is deleted if its parent is \c this.
-
- \par Access functions:
- \li \ref IrcProtocol* <b>protocol</b>() const
- \li void <b>setProtocol</b>(\ref IrcProtocol* protocol)
- */
-IrcProtocol* IrcConnection::protocol() const
-{
- Q_D(const IrcConnection);
- return d->protocol;
-}
-
-void IrcConnection::setProtocol(IrcProtocol* proto)
-{
- Q_D(IrcConnection);
- if (d->protocol != proto) {
- if (d->protocol && d->protocol->parent() == this)
- delete d->protocol;
- d->protocol = proto;
- }
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, IrcConnection::Status status)
-{
- const int index = IrcConnection::staticMetaObject.indexOfEnumerator("Status");
- QMetaEnum enumerator = IrcConnection::staticMetaObject.enumerator(index);
- const char* key = enumerator.valueToKey(status);
- debug << (key ? key : "Unknown");
- return debug;
-}
-
-QDebug operator<<(QDebug debug, const IrcConnection* connection)
-{
- if (!connection)
- return debug << "IrcConnection(0x0) ";
- debug.nospace() << connection->metaObject()->className() << '(' << (void*) connection;
- if (!connection->displayName().isEmpty())
- debug.nospace() << ", " << qPrintable(connection->displayName());
- debug.nospace() << ')';
- return debug.space();
-}
-#endif // QT_NO_DEBUG_STREAM
-
-#include "moc_ircconnection.cpp"
-
-IRC_END_NAMESPACE