it using a specified text codec. Except the input data is utf8, in which case this function detects
utf8 and takes appropriate measures to get a correctly decoded QString regardless of the specified coded.
I'd like to use this function for decoding incoming server messages, but we need to change things quite
a bit in the Server to do this correctly. See my comment in server.cpp.
MESSAGE(FATAL_ERROR "\nYou have not selected which parts of Quassel I should build. Aborting.\nRun 'cmake <path> -DBUILD=<part>', where <part> contains one or more of 'core', 'gui' or 'monolithic', or 'all' to build everything.\n")
ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_QTGUI)
-IF(BUILD_CORE OR BUILD_QTGUI)
- MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n")
-ENDIF(BUILD_CORE OR BUILD_QTGUI)
+#IF(BUILD_CORE OR BUILD_QTGUI)
+# MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n")
+#ENDIF(BUILD_CORE OR BUILD_QTGUI)
SET(CMAKE_BUILD_TYPE Debug)
***************************************************************************/
#include "util.h"
+#include <QDebug>
+#include <QTextCodec>
QString nickFromMask(QString mask) {
return mask.section('!', 0, 0);
return QString("#&!+").contains(str[0]);
}
+QString decodeString(QByteArray input, QString encoding) {
+ // First, we check if it's utf8. It is very improbable to encounter a string that looks like
+ // valid utf8, but in fact is not. This means that if the input string passes as valid utf8, it
+ // is safe to assume that it is.
+ Q_ASSERT(sizeof(const char) == sizeof(quint8)); // just to make sure
+ bool isUtf8 = true;
+ int cnt = 0;
+ for(int i = 0; i < input.size(); i++) {
+ if(cnt) {
+ if((input[i] & 0xc0) != 0x80) { isUtf8 = false; break; } // Following byte does not start with 10
+ cnt--;
+ continue;
+ }
+ if(!(input[i] & 0x80)) continue; // 7 bit is ok
+ if((input[i] & 0xf8) == 0xf0) { cnt = 3; continue; }
+ if((input[i] & 0xf0) == 0xe0) { cnt = 2; continue; }
+ if((input[i] & 0xe0) == 0xc0) { cnt = 1; continue; }
+ isUtf8 = false; break; // 8 bit char, but not utf8!
+ }
+ if(isUtf8 && cnt == 0) {
+ QString s = QString::fromUtf8(input);
+ qDebug() << "Detected utf8:" << s;
+ return s;
+ }
+ QTextCodec *codec = QTextCodec::codecForName(encoding.toAscii());
+ if(!codec) {
+ qWarning() << QString("Invalid encoding: %1").arg(encoding);
+ return QString::fromAscii(input);
+ }
+ return codec->toUnicode(input);
+}
+
void writeDataToDevice(QIODevice *dev, const QVariant &item) {
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
QString userFromMask(QString mask);
QString hostFromMask(QString mask);
+//! Take a string and decode it using the specified text codec, recognizing utf8.
+/** This function takes a string and first checks if it is encoded in utf8, in which case it is
+ * decoded appropriately. Otherwise, the specified text codec is used to transform the string.
+ * \param input The input string containing encoded data
+ * \param encoding The text encoding we assume if it's not utf8
+ * \return The decoded string.
+ */
+QString decodeString(QByteArray input, QString encoding = "ISO-8859-15");
+
bool isChannelName(QString str);
/**
void Server::socketHasData() {
while(socket.canReadLine()) {
- QString s = socket.readLine().trimmed();
+ QByteArray s = socket.readLine().trimmed();
//qDebug() << "Read" << s;
- emit recvRawServerMsg(s);
+ //emit recvRawServerMsg(s); // signal not needed, and we should make sure we consider encodings where we need them
//Message *msg = Message::createFromServerString(this, s);
handleServerMsg(s);
}
socket.write(m.toAscii());
}
-/** Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */
-void Server::handleServerMsg(QString msg) {
+/*! Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */
+void Server::handleServerMsg(QByteArray rawmsg) {
try {
- if(msg.isEmpty()) {
+ if(rawmsg.isEmpty()) {
qWarning() << "Received empty string from server!";
return;
}
+ // TODO Implement encoding conversion
+ /* At this point, we have a raw message as a byte array. This needs to be converted to a QString somewhere.
+ * Problem is, that at this point we don't know which encoding to use for the various parts of the message.
+ * This is something the command handler needs to take care of (e.g. PRIVMSG needs to first parse for CTCP,
+ * and then convert the raw strings into the correct encoding.
+ * We _can_ safely assume Server encoding for prefix and cmd, but not for the params. Therefore, we need to
+ * change from a QStringList to a QList<QByteArray> in all the handlers, and have the handlers call decodeString
+ * where needed...
+ */
+ QString msg = QString::fromLatin1(rawmsg);
+
// OK, first we split the raw message into its various parts...
QString prefix = "";
QString cmd;
QHash<QString, QString> topics; // stores topics for each buffer
VarMap serverSupports; // stores results from RPL_ISUPPORT
- void handleServerMsg(QString rawMsg);
+ void handleServerMsg(QByteArray rawMsg);
void handleUserInput(QString buffer, QString usrMsg);
// CTCP Stuff
MainWin::MainWin(QtGui *_gui, QWidget *parent) : QMainWindow(parent), gui(_gui) {
ui.setupUi(this);
- setWindowTitle("Quassel IRC");
- //setWindowTitle("Κυασελ Εγαρζη");
+ //setWindowTitle("Quassel IRC");
+ setWindowTitle(QString::fromUtf8("Κυασελ Εγαρζη"));
setWindowIcon(QIcon(":/qirc-icon.png"));
setWindowIconText("Quassel IRC");