_userInputHandler(new UserInputHandler(this)),
_ctcpHandler(new CtcpHandler(this)),
_autoReconnectCount(0),
+ _quitRequested(false),
_previousConnectionAttemptFailed(false),
_lastUsedServerlistIndex(0),
_autoWhoInterval(90),
_autoWhoNickLimit(0), // unlimited
_autoWhoDelay(3),
-
+
// TokenBucket to avaid sending too much at once
_messagesPerSecond(1),
_burstSize(5),
_tokenBucket(5) // init with a full bucket
{
_autoReconnectTimer.setSingleShot(true);
-
+ _socketCloseTimer.setSingleShot(true);
+ connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout()));
+
_autoWhoTimer.setInterval(_autoWhoDelay * 1000);
- _autoWhoTimer.setSingleShot(false);
_autoWhoCycleTimer.setInterval(_autoWhoInterval * 1000);
- _autoWhoCycleTimer.setSingleShot(false);
-
+
_tokenBucketTimer.start(_messagesPerSecond * 1000);
- _tokenBucketTimer.setSingleShot(false);
QHash<QString, QString> channels = coreSession()->persistentChannels(networkId());
foreach(QString chan, channels.keys()) {
setConnectionState(Network::Disconnected);
socketDisconnected();
} else {
- socket.disconnectFromHost();
+ _socketCloseTimer.start(10000); // the irc server has 10 seconds to close the socket
}
- if(requested) {
- emit quitRequested(networkId());
- }
+ // this flag triggers quitRequested() once the socket is closed
+ // it is needed to determine whether or not the connection needs to be
+ // in the automatic session restore.
+ _quitRequested = requested;
}
void NetworkConnection::socketHasData() {
setConnectionState(state);
}
+void NetworkConnection::socketCloseTimeout() {
+ socket.disconnectFromHost();
+}
+
void NetworkConnection::socketDisconnected() {
_autoWhoCycleTimer.stop();
_autoWhoTimer.stop();
_autoWhoQueue.clear();
_autoWhoInProgress.clear();
+ _socketCloseTimer.stop();
+
network()->setConnected(false);
emit disconnected(networkId());
if(_autoReconnectCount != 0) {
setConnectionState(Network::Reconnecting);
if(_autoReconnectCount == network()->autoReconnectRetries()) doAutoReconnect(); // first try is immediate
else _autoReconnectTimer.start();
+ } else if(_quitRequested) {
+ emit quitRequested(networkId());
}
}
void UserInputHandler::handleAway(const BufferInfo &bufferInfo, const QString &msg) {
Q_UNUSED(bufferInfo)
- putCmd("AWAY", serverEncode(msg));
+
+ QString awayMsg;
+ // if there is no message supplied we have to check if we are already away or not
+ if(msg.isEmpty()) {
+ IrcUser *me = network()->me();
+ if(me && !me->isAway())
+ awayMsg = networkConnection()->identity()->awayReason();
+ }
+
+ putCmd("AWAY", serverEncode(awayMsg));
}
void UserInputHandler::handleBan(const BufferInfo &bufferInfo, const QString &msg) {
void UserInputHandler::handleKick(const BufferInfo &bufferInfo, const QString &msg) {
QString nick = msg.section(' ', 0, 0, QString::SectionSkipEmpty);
QString reason = msg.section(' ', 1, -1, QString::SectionSkipEmpty).trimmed();
- if(reason.isEmpty()) reason = networkConnection()->identity()->kickReason();
+ if(reason.isEmpty())
+ reason = networkConnection()->identity()->kickReason();
+
QList<QByteArray> params;
params << serverEncode(bufferInfo.bufferName()) << serverEncode(nick) << channelEncode(bufferInfo.bufferName(), reason);
emit putCmd("KICK", params);
}
void UserInputHandler::handleKill(const BufferInfo &bufferInfo, const QString &msg) {
+ Q_UNUSED(bufferInfo)
QString nick = msg.section(' ', 0, 0, QString::SectionSkipEmpty);
QString pass = msg.section(' ', 1, -1, QString::SectionSkipEmpty);
QList<QByteArray> params;
}
void UserInputHandler::handleOper(const BufferInfo &bufferInfo, const QString &msg) {
+ Q_UNUSED(bufferInfo)
emit putRawLine(serverEncode(QString("OPER %1").arg(msg)));
}
void UserInputHandler::handlePart(const BufferInfo &bufferInfo, const QString &msg) {
QList<QByteArray> params;
- params << serverEncode(bufferInfo.bufferName()) << channelEncode(bufferInfo.bufferName(), msg);
+ QString partReason;
+
+ // msg might contain either a channel name and/or a reaon, so we have to check if the first word is a known channel
+ QString channelName = msg.section(' ', 0, 0);
+ if(channelName.isEmpty() || !network()->ircChannel(channelName)) {
+ channelName = bufferInfo.bufferName();
+ partReason = msg;
+ } else {
+ partReason = msg.mid(channelName.length() + 1);
+ }
+
+ if(partReason.isEmpty())
+ partReason = networkConnection()->identity()->partReason();
+
+ params << serverEncode(channelName) << channelEncode(bufferInfo.bufferName(), partReason);
emit putCmd("PART", params);
}
void UserInputHandler::handleQuit(const BufferInfo &bufferInfo, const QString &msg) {
Q_UNUSED(bufferInfo)
- emit putCmd("QUIT", serverEncode(msg));
+
+ QString quitReason;
+ if(msg.isEmpty())
+ quitReason = networkConnection()->identity()->quitReason();
+ else
+ quitReason = msg;
+
+ emit putCmd("QUIT", serverEncode(quitReason));
+ networkConnection()->disconnectFromIrc();
}
void UserInputHandler::handleQuote(const BufferInfo &bufferInfo, const QString &msg) {
<string>...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/edit-rename.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/22x22/actions/oxygen/22x22/actions/edit-rename.png</normaloff>:/22x22/actions/oxygen/22x22/actions/edit-rename.png</iconset>
</property>
<property name="iconSize" >
<size>
<string>Add...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/list-add-user.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/22x22/actions/oxygen/22x22/actions/list-add-user.png</normaloff>:/22x22/actions/oxygen/22x22/actions/list-add-user.png</iconset>
</property>
<property name="iconSize" >
<size>
<string>...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/list-remove-user.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/22x22/actions/oxygen/22x22/actions/list-remove-user.png</normaloff>:/22x22/actions/oxygen/22x22/actions/list-remove-user.png</iconset>
</property>
<property name="iconSize" >
<size>
<item>
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
- <number>0</number>
+ <number>2</number>
</property>
<widget class="QWidget" name="generalTab" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>463</width>
+ <height>314</height>
+ </rect>
+ </property>
<attribute name="title" >
<string>General</string>
</attribute>
<string>&Add...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/16x16/actions/oxygen/16x16/actions/list-add.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/16x16/actions/oxygen/16x16/actions/list-add.png</normaloff>:/16x16/actions/oxygen/16x16/actions/list-add.png</iconset>
</property>
<property name="iconSize" >
<size>
<string>Remove</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/16x16/actions/oxygen/16x16/actions/edit-delete.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/16x16/actions/oxygen/16x16/actions/edit-delete.png</normaloff>:/16x16/actions/oxygen/16x16/actions/edit-delete.png</iconset>
</property>
</widget>
</item>
<string>Re&name...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/16x16/actions/oxygen/16x16/actions/edit-rename.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/16x16/actions/oxygen/16x16/actions/edit-rename.png</normaloff>:/16x16/actions/oxygen/16x16/actions/edit-rename.png</iconset>
</property>
</widget>
</item>
<property name="spacing" >
<number>6</number>
</property>
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>0</number>
- </property>
- <property name="rightMargin" >
- <number>0</number>
- </property>
- <property name="bottomMargin" >
+ <property name="margin" >
<number>0</number>
</property>
<item>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>0</width>
<height>20</height>
<string>...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/16x16/actions/oxygen/16x16/actions/go-up.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/16x16/actions/oxygen/16x16/actions/go-up.png</normaloff>:/16x16/actions/oxygen/16x16/actions/go-up.png</iconset>
</property>
</widget>
</item>
<string>...</string>
</property>
<property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/16x16/actions/oxygen/16x16/actions/go-down.png</iconset>
+ <iconset resource="../../icons/icons.qrc" >
+ <normaloff>:/16x16/actions/oxygen/16x16/actions/go-down.png</normaloff>:/16x16/actions/oxygen/16x16/actions/go-down.png</iconset>
</property>
</widget>
</item>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>0</width>
<height>20</height>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>124</width>
<height>76</height>
</layout>
</widget>
<widget class="QWidget" name="awayTab" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>100</width>
+ <height>30</height>
+ </rect>
+ </property>
<attribute name="title" >
<string>A&way</string>
</attribute>
<layout class="QVBoxLayout" >
<item>
<layout class="QGridLayout" >
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>0</number>
- </property>
- <property name="rightMargin" >
- <number>0</number>
- </property>
- <property name="bottomMargin" >
+ <property name="margin" >
<number>0</number>
</property>
- <property name="horizontalSpacing" >
- <number>6</number>
- </property>
- <property name="verticalSpacing" >
+ <property name="spacing" >
<number>6</number>
</property>
<item row="0" column="1" >
<property name="spacing" >
<number>6</number>
</property>
- <property name="leftMargin" >
- <number>8</number>
- </property>
- <property name="topMargin" >
- <number>8</number>
- </property>
- <property name="rightMargin" >
- <number>8</number>
- </property>
- <property name="bottomMargin" >
+ <property name="margin" >
<number>8</number>
</property>
<item>
<property name="spacing" >
<number>6</number>
</property>
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>0</number>
- </property>
- <property name="rightMargin" >
- <number>0</number>
- </property>
- <property name="bottomMargin" >
+ <property name="margin" >
<number>0</number>
</property>
<item>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>40</width>
<height>20</height>
</item>
<item>
<layout class="QGridLayout" >
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
+ <property name="margin" >
<number>0</number>
</property>
- <property name="rightMargin" >
- <number>0</number>
- </property>
- <property name="bottomMargin" >
- <number>0</number>
- </property>
- <property name="horizontalSpacing" >
- <number>6</number>
- </property>
- <property name="verticalSpacing" >
+ <property name="spacing" >
<number>6</number>
</property>
<item row="1" column="0" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</layout>
</widget>
<widget class="QWidget" name="advancedTab" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>463</width>
+ <height>314</height>
+ </rect>
+ </property>
<attribute name="title" >
<string>Advanced</string>
</attribute>
<layout class="QVBoxLayout" >
<item>
<layout class="QGridLayout" >
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>0</number>
- </property>
- <property name="rightMargin" >
+ <property name="margin" >
<number>0</number>
</property>
- <property name="bottomMargin" >
- <number>0</number>
- </property>
- <property name="horizontalSpacing" >
- <number>6</number>
- </property>
- <property name="verticalSpacing" >
+ <property name="spacing" >
<number>6</number>
</property>
<item row="1" column="0" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>20</width>
<height>40</height>
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>identityList</tabstop>
+ <tabstop>renameIdentity</tabstop>
+ <tabstop>addIdentity</tabstop>
+ <tabstop>deleteIdentity</tabstop>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>realName</tabstop>
+ <tabstop>nicknameList</tabstop>
+ <tabstop>addNick</tabstop>
+ <tabstop>deleteNick</tabstop>
+ <tabstop>renameNick</tabstop>
+ <tabstop>nickUp</tabstop>
+ <tabstop>nickDown</tabstop>
+ <tabstop>awayNick</tabstop>
+ <tabstop>awayReasonEnabled</tabstop>
+ <tabstop>awayReason</tabstop>
+ <tabstop>returnMessageEnabled</tabstop>
+ <tabstop>returnMessage</tabstop>
+ <tabstop>awayNickEnabled</tabstop>
+ <tabstop>autoAwayEnabled</tabstop>
+ <tabstop>autoAwayTime</tabstop>
+ <tabstop>autoReturnMessageEnabled</tabstop>
+ <tabstop>autoAwayReasonEnabled</tabstop>
+ <tabstop>autoReturnMessage</tabstop>
+ <tabstop>autoAwayReason</tabstop>
+ <tabstop>ident</tabstop>
+ <tabstop>kickReason</tabstop>
+ <tabstop>partReason</tabstop>
+ <tabstop>quitReason</tabstop>
+ </tabstops>
<resources>
<include location="../../icons/icons.qrc" />
</resources>