From 28f1a9d9d96645757691cdea19500aefce4bcdac Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Mon, 18 Feb 2008 18:56:05 +0000 Subject: [PATCH] Finally here: the long awaited auto reconnect! Your auto reconnect settings should now be honored - if they are not, please report :) --- src/common/network.cpp | 15 ++- src/common/network.h | 5 +- src/core/coresession.cpp | 9 +- src/core/networkconnection.cpp | 61 ++++++++++++- src/core/networkconnection.h | 10 +- .../settingspages/networkssettingspage.cpp | 31 +++++-- src/qtui/settingspages/networkssettingspage.h | 1 + .../settingspages/networkssettingspage.ui | 91 +++++++++++-------- 8 files changed, 158 insertions(+), 65 deletions(-) diff --git a/src/common/network.cpp b/src/common/network.cpp index b565a78e..7fa2a2ae 100644 --- a/src/common/network.cpp +++ b/src/common/network.cpp @@ -860,11 +860,16 @@ QDataStream &operator>>(QDataStream &in, NetworkInfo &info) { return in; } - - - - - +QDebug operator<<(QDebug dbg, const NetworkInfo &i) { + dbg.nospace() << "(id = " << i.networkId << " name = " << i.networkName << " identity = " << i.identity + << " codecForServer = " << i.codecForServer << " codecForEncoding = " << i.codecForEncoding << " codecForDecoding = " << i.codecForDecoding + << " serverList = " << i.serverList << " useRandomServer = " << i.useRandomServer << " perform = " << i.perform + << " useAutoIdentify = " << i.useAutoIdentify << " autoIdentifyService = " << i.autoIdentifyService << " autoIdentifyPassword = " << i.autoIdentifyPassword + << " useAutoReconnect = " << i.useAutoReconnect << " autoReconnectInterval = " << i.autoReconnectInterval + << " autoReconnectRetries = " << i.autoReconnectRetries << " unlimitedReconnectRetries = " << i.unlimitedReconnectRetries + << " rejoinChannels = " << i.rejoinChannels << ")"; + return dbg.space(); +} diff --git a/src/common/network.h b/src/common/network.h index a64fb088..c52cd594 100644 --- a/src/common/network.h +++ b/src/common/network.h @@ -68,7 +68,7 @@ class Network : public SyncableObject { Q_PROPERTY(bool rejoinChannels READ rejoinChannels WRITE setRejoinChannels STORED false) public: - enum ConnectionState { Disconnected, Connecting, Initializing, Initialized, Disconnecting }; + enum ConnectionState { Disconnected, Connecting, Initializing, Initialized, Reconnecting, Disconnecting }; Network(const NetworkId &networkid, QObject *parent = 0); ~Network(); @@ -234,7 +234,7 @@ signals: void autoIdentifyPasswordSet(const QString &); void useAutoReconnectSet(bool); void autoReconnectIntervalSet(quint32); - void autoReconnectRetriesSet(qint16); + void autoReconnectRetriesSet(quint16); void unlimitedReconnectRetriesSet(bool); void rejoinChannelsSet(bool); @@ -340,6 +340,7 @@ struct NetworkInfo { QDataStream &operator<<(QDataStream &out, const NetworkInfo &info); QDataStream &operator>>(QDataStream &in, NetworkInfo &info); +QDebug operator<<(QDebug dbg, const NetworkInfo &i); Q_DECLARE_METATYPE(NetworkInfo); diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 22ed2121..23456ab3 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -230,7 +230,7 @@ void CoreSession::connectToNetwork(NetworkId id, const QVariant &previousState) void CoreSession::attachNetworkConnection(NetworkConnection *conn) { connect(conn, SIGNAL(connected(NetworkId)), this, SLOT(networkConnected(NetworkId))); - connect(conn, SIGNAL(disconnected(NetworkId)), this, SLOT(networkDisconnected(NetworkId))); + connect(conn, SIGNAL(quitRequested(NetworkId)), this, SLOT(networkDisconnected(NetworkId))); // I guess we don't need these anymore, client-side can just connect the network's signals directly //signalProxy()->attachSignal(conn, SIGNAL(connected(NetworkId)), SIGNAL(networkConnected(NetworkId))); @@ -272,11 +272,8 @@ void CoreSession::networkConnected(NetworkId networkid) { Core::bufferInfo(user(), networkid, BufferInfo::StatusBuffer); // create status buffer } +// called now only on /quit and requested disconnects, not on normal disconnects! void CoreSession::networkDisconnected(NetworkId networkid) { - // FIXME - // connection should only go away on explicit /part, and handle reconnections etcpp internally otherwise - - //Q_ASSERT(_connections.contains(networkid)); if(_connections.contains(networkid)) _connections.take(networkid)->deleteLater(); } @@ -448,7 +445,7 @@ void CoreSession::updateNetwork(const NetworkInfo &info) { qWarning() << "Update request for unknown network received!"; return; } - _networks[info.networkId]->setNetworkInfo(info); qDebug() << "unlim" << info.unlimitedReconnectRetries << _networks[info.networkId]->unlimitedReconnectRetries(); + _networks[info.networkId]->setNetworkInfo(info); Core::updateNetwork(user(), info); } diff --git a/src/core/networkconnection.cpp b/src/core/networkconnection.cpp index 3799e03d..24238def 100644 --- a/src/core/networkconnection.cpp +++ b/src/core/networkconnection.cpp @@ -43,9 +43,16 @@ NetworkConnection::NetworkConnection(Network *network, CoreSession *session, con _ircServerHandler(new IrcServerHandler(this)), _userInputHandler(new UserInputHandler(this)), _ctcpHandler(new CtcpHandler(this)), - _previousState(state) + _previousState(state), + _autoReconnectCount(0) { + _autoReconnectTimer.setSingleShot(true); + connect(&_autoReconnectTimer, SIGNAL(timeout()), this, SLOT(doAutoReconnect())); + connect(network, SIGNAL(currentServerSet(const QString &)), this, SLOT(networkInitialized(const QString &))); + connect(network, SIGNAL(useAutoReconnectSet(bool)), this, SLOT(autoReconnectSettingsChanged())); + connect(network, SIGNAL(autoReconnectIntervalSet(quint32)), this, SLOT(autoReconnectSettingsChanged())); + connect(network, SIGNAL(autoReconnectRetriesSet(quint16)), this, SLOT(autoReconnectSettingsChanged())); connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected())); connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); @@ -56,7 +63,8 @@ NetworkConnection::NetworkConnection(Network *network, CoreSession *session, con } NetworkConnection::~NetworkConnection() { - disconnectFromIrc(); + if(connectionState() != Network::Disconnected && connectionState() != Network::Reconnecting) + disconnectFromIrc(); delete _ircServerHandler; delete _userInputHandler; delete _ctcpHandler; @@ -145,8 +153,25 @@ QByteArray NetworkConnection::userEncode(const QString &userNick, const QString return network()->encodeString(string); } +void NetworkConnection::autoReconnectSettingsChanged() { + if(!network()->useAutoReconnect()) { + _autoReconnectTimer.stop(); + _autoReconnectCount = 0; + } else { + _autoReconnectTimer.setInterval(network()->autoReconnectInterval() * 1000); + if(_autoReconnectCount != 0) { + if(network()->unlimitedReconnectRetries()) _autoReconnectCount = -1; + else _autoReconnectCount = network()->autoReconnectRetries(); + } + } +} -void NetworkConnection::connectToIrc() { +void NetworkConnection::connectToIrc(bool reconnecting) { + if(!reconnecting && network()->useAutoReconnect() && _autoReconnectCount == 0) { + _autoReconnectTimer.setInterval(network()->autoReconnectInterval() * 1000); + if(network()->unlimitedReconnectRetries()) _autoReconnectCount = -1; + else _autoReconnectCount = network()->autoReconnectRetries(); + } QVariantList serverList = network()->serverList(); Identity *identity = coreSession()->identity(network()->identity()); if(!serverList.count()) { @@ -160,13 +185,18 @@ void NetworkConnection::connectToIrc() { // TODO implement cycling / random servers QString host = serverList[0].toMap()["Host"].toString(); quint16 port = serverList[0].toMap()["Port"].toUInt(); - displayStatusMsg(QString("Connecting to %1:%2...").arg(host).arg(port)); + displayStatusMsg(tr("Connecting to %1:%2...").arg(host).arg(port)); + displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Connecting to %1:%2...").arg(host).arg(port)); socket.connectToHost(host, port); } void NetworkConnection::networkInitialized(const QString ¤tServer) { if(currentServer.isEmpty()) return; + if(network()->useAutoReconnect() && !network()->unlimitedReconnectRetries()) { + _autoReconnectCount = network()->autoReconnectRetries(); // reset counter + } + sendPerform(); // rejoin channels we've been in @@ -204,6 +234,9 @@ QVariant NetworkConnection::state() const { } void NetworkConnection::disconnectFromIrc() { + _autoReconnectTimer.stop(); + _autoReconnectCount = 0; + displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting.")); if(socket.state() < QAbstractSocket::ConnectedState) { setConnectionState(Network::Disconnected); socketDisconnected(); @@ -222,6 +255,10 @@ void NetworkConnection::socketError(QAbstractSocket::SocketError) { emit connectionError(socket.errorString()); emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString())); network()->emitConnectionError(socket.errorString()); + if(socket.state() < QAbstractSocket::ConnectedState) { + setConnectionState(Network::Disconnected); + socketDisconnected(); + } } void NetworkConnection::socketConnected() { @@ -261,6 +298,22 @@ void NetworkConnection::socketStateChanged(QAbstractSocket::SocketState socketSt void NetworkConnection::socketDisconnected() { network()->setConnected(false); emit disconnected(networkId()); + if(_autoReconnectCount == 0) emit quitRequested(networkId()); + else { + setConnectionState(Network::Reconnecting); + qDebug() << "trying to reconnect... " << _autoReconnectTimer.interval(); + if(_autoReconnectCount == network()->autoReconnectRetries()) doAutoReconnect(); // first try is immediate + else _autoReconnectTimer.start(); + } +} + +void NetworkConnection::doAutoReconnect() { + if(connectionState() != Network::Disconnected && connectionState() != Network::Reconnecting) { + qWarning() << "NetworkConnection::doAutoReconnect(): Cannot reconnect while not being disconnected!"; + return; + } + if(_autoReconnectCount > 0) _autoReconnectCount--; + connectToIrc(true); } // FIXME switch to BufferId diff --git a/src/core/networkconnection.h b/src/core/networkconnection.h index 745afc77..ace1e4ea 100644 --- a/src/core/networkconnection.h +++ b/src/core/networkconnection.h @@ -82,7 +82,7 @@ public: public slots: // void setServerOptions(); - void connectToIrc(); + void connectToIrc(bool reconnecting = false); void disconnectFromIrc(); void userInput(BufferInfo bufferInfo, QString msg); @@ -92,6 +92,8 @@ public slots: private slots: void sendPerform(); + void autoReconnectSettingsChanged(); + void doAutoReconnect(); signals: // #void networkState(QString net, QVariantMap data); @@ -105,6 +107,8 @@ signals: void connectionInitialized(); ///< Emitted after receipt of 001 to indicate that we can now send data to the IRC server void connectionError(const QString &errorMsg); + void quitRequested(NetworkId networkId); + //void queryRequested(QString network, QString nick); @@ -130,6 +134,9 @@ private: QVariant _previousState; + QTimer _autoReconnectTimer; + int _autoReconnectCount; + class ParseError : public Exception { public: ParseError(QString cmd, QString prefix, QStringList params); @@ -139,7 +146,6 @@ private: public: UnknownCmdError(QString cmd, QString prefix, QStringList params); }; - }; #endif diff --git a/src/qtui/settingspages/networkssettingspage.cpp b/src/qtui/settingspages/networkssettingspage.cpp index 573a033d..614de279 100644 --- a/src/qtui/settingspages/networkssettingspage.cpp +++ b/src/qtui/settingspages/networkssettingspage.cpp @@ -32,6 +32,7 @@ NetworksSettingsPage::NetworksSettingsPage(QWidget *parent) : SettingsPage(tr("General"), tr("Networks"), parent) { ui.setupUi(this); + _ignoreWidgetChanges = false; connectedIcon = QIcon(":/22x22/actions/network-connect"); connectingIcon = QIcon(":/22x22/actions/gear"); @@ -145,6 +146,7 @@ bool NetworksSettingsPage::aboutToSave() { } void NetworksSettingsPage::widgetHasChanged() { + if(_ignoreWidgetChanges) return; bool changed = testHasChanged(); if(changed != hasChanged()) setChangedState(changed); } @@ -165,18 +167,25 @@ void NetworksSettingsPage::setWidgetStates() { // network list if(ui.networkList->selectedItems().count()) { NetworkId id = ui.networkList->selectedItems()[0]->data(Qt::UserRole).value(); + const Network *net = 0; + if(id > 0) net = Client::network(id); ui.detailsBox->setEnabled(true); ui.renameNetwork->setEnabled(true); ui.deleteNetwork->setEnabled(true); - ui.connectNow->setEnabled(id > 0 - && (Client::network(id)->connectionState() == Network::Initialized - || Client::network(id)->connectionState() == Network::Disconnected)); - if(Client::network(id) && Client::network(id)->isConnected()) { - ui.connectNow->setIcon(disconnectedIcon); - ui.connectNow->setText(tr("Disconnect")); + ui.connectNow->setEnabled(net); + // && (Client::network(id)->connectionState() == Network::Initialized + // || Client::network(id)->connectionState() == Network::Disconnected)); + if(net) { + if(net->connectionState() == Network::Disconnected) { + ui.connectNow->setIcon(connectedIcon); + ui.connectNow->setText(tr("Connect")); + } else { + ui.connectNow->setIcon(disconnectedIcon); + ui.connectNow->setText(tr("Disconnect")); + } } else { - ui.connectNow->setIcon(connectedIcon); - ui.connectNow->setText(tr("Connect")); + ui.connectNow->setIcon(QIcon()); + ui.connectNow->setText(tr("Apply first!")); } } else { ui.renameNetwork->setEnabled(false); @@ -386,6 +395,7 @@ QListWidgetItem *NetworksSettingsPage::insertNetwork(const NetworkInfo &info) { } void NetworksSettingsPage::displayNetwork(NetworkId id) { + _ignoreWidgetChanges = true; if(id != 0) { NetworkInfo info = networkInfos[id]; ui.identityList->setCurrentIndex(ui.identityList->findData(info.identity.toInt())); @@ -418,8 +428,11 @@ void NetworksSettingsPage::displayNetwork(NetworkId id) { ui.identityList->setCurrentIndex(-1); ui.serverList->clear(); ui.performEdit->clear(); + ui.autoIdentifyService->clear(); + ui.autoIdentifyPassword->clear(); setWidgetStates(); } + _ignoreWidgetChanges = false; currentId = id; } @@ -529,7 +542,7 @@ void NetworksSettingsPage::on_connectNow_clicked() { NetworkId id = ui.networkList->selectedItems()[0]->data(Qt::UserRole).value(); const Network *net = Client::network(id); if(!net) return; - if(!net->isConnected()) net->requestConnect(); + if(net->connectionState() == Network::Disconnected) net->requestConnect(); else net->requestDisconnect(); } diff --git a/src/qtui/settingspages/networkssettingspage.h b/src/qtui/settingspages/networkssettingspage.h index bb6499f0..22a9e337 100644 --- a/src/qtui/settingspages/networkssettingspage.h +++ b/src/qtui/settingspages/networkssettingspage.h @@ -81,6 +81,7 @@ class NetworksSettingsPage : public SettingsPage { NetworkId currentId; QHash networkInfos; + bool _ignoreWidgetChanges; QIcon connectedIcon, connectingIcon, disconnectedIcon; diff --git a/src/qtui/settingspages/networkssettingspage.ui b/src/qtui/settingspages/networkssettingspage.ui index eaf1a8c1..c635afc8 100644 --- a/src/qtui/settingspages/networkssettingspage.ui +++ b/src/qtui/settingspages/networkssettingspage.ui @@ -13,16 +13,7 @@ Form - - 0 - - - 0 - - - 0 - - + 0 @@ -53,7 +44,8 @@ Re&name... - :/16x16/actions/oxygen/16x16/actions/edit-rename.png + + :/16x16/actions/oxygen/16x16/actions/edit-rename.png:/16x16/actions/oxygen/16x16/actions/edit-rename.png @@ -69,7 +61,8 @@ &Add... - :/16x16/actions/oxygen/16x16/actions/list-add.png + + :/16x16/actions/oxygen/16x16/actions/list-add.png:/16x16/actions/oxygen/16x16/actions/list-add.png @@ -91,7 +84,8 @@ De&lete - :/16x16/actions/oxygen/16x16/actions/edit-delete.png + + :/16x16/actions/oxygen/16x16/actions/edit-delete.png:/16x16/actions/oxygen/16x16/actions/edit-delete.png @@ -100,7 +94,7 @@ Qt::Vertical - + 20 40 @@ -123,7 +117,9 @@ Connect now - + + + @@ -170,12 +166,20 @@ true - 2 + 1 true + + + 0 + 0 + 800 + 480 + + Servers @@ -208,7 +212,9 @@ &Edit... - + + + @@ -224,7 +230,8 @@ &Add... - :/16x16/actions/oxygen/16x16/actions/list-add.png + + :/16x16/actions/oxygen/16x16/actions/list-add.png:/16x16/actions/oxygen/16x16/actions/list-add.png @@ -240,7 +247,8 @@ De&lete - :/16x16/actions/oxygen/16x16/actions/edit-delete.png + + :/16x16/actions/oxygen/16x16/actions/edit-delete.png:/16x16/actions/oxygen/16x16/actions/edit-delete.png @@ -249,16 +257,7 @@ 6 - - 0 - - - 0 - - - 0 - - + 0 @@ -266,7 +265,7 @@ Qt::Horizontal - + 0 20 @@ -283,7 +282,8 @@ ... - :/16x16/actions/oxygen/16x16/actions/go-up.png + + :/16x16/actions/oxygen/16x16/actions/go-up.png:/16x16/actions/oxygen/16x16/actions/go-up.png @@ -296,7 +296,8 @@ ... - :/16x16/actions/oxygen/16x16/actions/go-down.png + + :/16x16/actions/oxygen/16x16/actions/go-down.png:/16x16/actions/oxygen/16x16/actions/go-down.png @@ -305,7 +306,7 @@ Qt::Horizontal - + 0 20 @@ -320,7 +321,7 @@ Qt::Vertical - + 20 40 @@ -347,6 +348,14 @@ + + + 0 + 0 + 394 + 340 + + Perform @@ -434,6 +443,14 @@ + + + 0 + 0 + 394 + 340 + + Advanced @@ -504,7 +521,7 @@ Qt::Horizontal - + 40 20 @@ -603,7 +620,7 @@ Qt::Horizontal - + 40 20 @@ -631,7 +648,7 @@ Qt::Vertical - + 386 31 -- 2.20.1