summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp2
-rw-r--r--src/corelib/tools/qbytearraymatcher.h8
-rw-r--r--src/corelib/tools/qringbuffer_p.h27
-rw-r--r--src/corelib/tools/qstring.h1
-rw-r--r--src/corelib/tools/qstringbuilder.cpp24
-rw-r--r--src/corelib/tools/qstringbuilder.h58
-rw-r--r--src/corelib/tools/qstringmatcher.h6
-rw-r--r--src/dbus/qdbusservicewatcher.cpp4
-rw-r--r--src/gui/text/qtextcontrol.cpp4
-rw-r--r--src/network/socket/qlocalsocket_win.cpp3
-rw-r--r--tests/auto/linguist/lrelease/tst_lrelease.cpp13
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp49
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h51
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result24
-rw-r--r--tests/auto/qstringbuilder1/stringbuilder.cpp26
-rw-r--r--tools/assistant/lib/lib.pro3
-rw-r--r--tools/assistant/lib/qhelp_global.cpp112
-rw-r--r--tools/assistant/lib/qhelp_global.h58
-rw-r--r--tools/assistant/lib/qhelpgenerator.cpp2
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp4
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_default.cpp2
-rw-r--r--tools/assistant/tools/assistant/assistant.pro2
-rw-r--r--tools/assistant/tools/assistant/helpviewer.cpp32
-rw-r--r--tools/assistant/tools/assistant/main.cpp10
-rw-r--r--tools/assistant/tools/assistant/searchwidget.cpp3
-rw-r--r--tools/linguist/lrelease/main.cpp83
-rw-r--r--tools/linguist/lupdate/cpp.cpp76
-rw-r--r--tools/linguist/shared/qm.cpp35
-rw-r--r--tools/linguist/shared/translator.h1
29 files changed, 535 insertions, 188 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 29b7568..f2e66c5 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -551,7 +551,7 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t)
Q_Q(QEventDispatcherWin32);
int ok = 0;
- if (t->interval > 15 || !t->interval || !qtimeSetEvent) {
+ if (t->interval > 20 || !t->interval || !qtimeSetEvent) {
ok = 1;
if (!t->interval) // optimization for single-shot-zero-timer
QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId));
diff --git a/src/corelib/tools/qbytearraymatcher.h b/src/corelib/tools/qbytearraymatcher.h
index ef46d34..3d951cf 100644
--- a/src/corelib/tools/qbytearraymatcher.h
+++ b/src/corelib/tools/qbytearraymatcher.h
@@ -79,17 +79,21 @@ private:
QByteArray q_pattern;
#ifdef Q_CC_RVCT
// explicitely allow anonymous unions for RVCT to prevent compiler warnings
-#pragma anon_unions
+# pragma push
+# pragma anon_unions
#endif
struct Data {
uchar q_skiptable[256];
const uchar *p;
int l;
- };
+ };
union {
uint dummy[256];
Data p;
};
+#ifdef Q_CC_RVCT
+# pragma pop
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index c44346c..7c766cb 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -287,6 +287,33 @@ public:
return -1;
}
+ inline int indexOf(char c, int maxLength) const {
+ int index = 0;
+ int remain = qMin(size(), maxLength);
+ for (int i = 0; remain && i < buffers.size(); ++i) {
+ int start = 0;
+ int end = buffers.at(i).size();
+
+ if (i == 0)
+ start = head;
+ if (i == tailBuffer)
+ end = tail;
+ if (remain < end - start) {
+ end = start + remain;
+ remain = 0;
+ } else {
+ remain -= end - start;
+ }
+ const char *ptr = buffers.at(i).data() + start;
+ for (int j = start; j < end; ++j) {
+ if (*ptr++ == c)
+ return index;
+ ++index;
+ }
+ }
+ return -1;
+ }
+
inline int read(char *data, int maxLength) {
int bytesToRead = qMin(size(), maxLength);
int readSoFar = 0;
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 6c9a3ca..74f93a4 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -631,6 +631,7 @@ private:
friend class QCharRef;
friend class QTextCodec;
friend class QStringRef;
+ friend struct QAbstractConcatenable;
friend inline bool qStringComparisonHelper(const QString &s1, const char *s2);
friend inline bool qStringComparisonHelper(const QStringRef &s1, const char *s2);
public:
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 0a13218..4a16488 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -41,6 +41,8 @@
#include "qstringbuilder.h"
+QT_BEGIN_NAMESPACE
+
/*!
\class QLatin1Literal
\internal
@@ -143,3 +145,25 @@
Converts the \c QLatin1Literal into a \c QString object.
*/
+
+/*! \internal */
+void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out)
+{
+#ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings) {
+ QString tmp = QString::fromAscii(a);
+ memcpy(out, reinterpret_cast<const char *>(tmp.constData()), sizeof(QChar) * tmp.size());
+ out += tmp.length();
+ return;
+ }
+#endif
+ if (len == -1) {
+ while (*a)
+ *out++ = QLatin1Char(*a++);
+ } else {
+ for (int i = 0; i < len - 1; ++i)
+ *out++ = QLatin1Char(a[i]);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index efa39b5..798d097 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -66,7 +66,7 @@ public:
const char *data() const { return m_data; }
template <int N>
- QLatin1Literal(const char (&str)[N])
+ QLatin1Literal(const char (&str)[N])
: m_size(N - 1), m_data(str) {}
private:
@@ -74,6 +74,21 @@ private:
const char *m_data;
};
+struct Q_CORE_EXPORT QAbstractConcatenable
+{
+protected:
+ static void convertFromAscii(const char *a, int len, QChar *&out);
+
+ static inline void convertFromAscii(char a, QChar *&out)
+ {
+#ifndef QT_NO_TEXTCODEC
+ if (QString::codecForCStrings)
+ *out++ = QChar::fromAscii(a);
+ else
+#endif
+ *out++ = QLatin1Char(a);
+ }
+};
template <typename T> struct QConcatenable {};
@@ -87,9 +102,12 @@ public:
{
QString s(QConcatenable< QStringBuilder<A, B> >::size(*this),
Qt::Uninitialized);
-
+
QChar *d = s.data();
QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
+ // this resize is necessary since we allocate a bit too much
+ // when dealing with variable sized 8-bit encodings
+ s.resize(d - s.data());
return s;
}
QByteArray toLatin1() const { return QString(*this).toLatin1(); }
@@ -99,13 +117,13 @@ public:
};
-template <> struct QConcatenable<char>
+template <> struct QConcatenable<char> : private QAbstractConcatenable
{
typedef char type;
static int size(const char) { return 1; }
static inline void appendTo(const char c, QChar *&out)
{
- *out++ = QLatin1Char(c);
+ QAbstractConcatenable::convertFromAscii(c, out);
}
};
@@ -170,7 +188,7 @@ template <> struct QConcatenable<QString>
{
const int n = a.size();
memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
- out += n;
+ out += n;
}
};
@@ -182,53 +200,51 @@ template <> struct QConcatenable<QStringRef>
{
const int n = a.size();
memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n);
- out += n;
+ out += n;
}
};
#ifndef QT_NO_CAST_FROM_ASCII
-template <int N> struct QConcatenable<char[N]>
+template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
{
typedef char type[N];
- static int size(const char[N]) { return N - 1; }
+ static int size(const char[N])
+ {
+ return N - 1;
+ }
static inline void appendTo(const char a[N], QChar *&out)
{
- for (int i = 0; i < N - 1; ++i)
- *out++ = QLatin1Char(a[i]);
+ QAbstractConcatenable::convertFromAscii(a, N, out);
}
};
-template <int N> struct QConcatenable<const char[N]>
+template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
{
typedef const char type[N];
static int size(const char[N]) { return N - 1; }
static inline void appendTo(const char a[N], QChar *&out)
{
- for (int i = 0; i < N - 1; ++i)
- *out++ = QLatin1Char(a[i]);
+ QAbstractConcatenable::convertFromAscii(a, N, out);
}
};
-template <> struct QConcatenable<const char *>
+template <> struct QConcatenable<const char *> : private QAbstractConcatenable
{
typedef char const *type;
static int size(const char *a) { return qstrlen(a); }
static inline void appendTo(const char *a, QChar *&out)
{
- while (*a)
- *out++ = QLatin1Char(*a++);
+ QAbstractConcatenable::convertFromAscii(a, -1, out);
}
};
-template <> struct QConcatenable<QByteArray>
+template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
{
typedef QByteArray type;
static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
static inline void appendTo(const QByteArray &ba, QChar *&out)
{
- const char *data = ba.constData();
- while (*data)
- *out++ = QLatin1Char(*data++);
+ QAbstractConcatenable::convertFromAscii(ba.constData(), -1, out);
}
};
#endif
@@ -237,7 +253,7 @@ template <typename A, typename B>
struct QConcatenable< QStringBuilder<A, B> >
{
typedef QStringBuilder<A, B> type;
- static int size(const type &p)
+ static int size(const type &p)
{
return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
}
diff --git a/src/corelib/tools/qstringmatcher.h b/src/corelib/tools/qstringmatcher.h
index 0cb1312..8076098 100644
--- a/src/corelib/tools/qstringmatcher.h
+++ b/src/corelib/tools/qstringmatcher.h
@@ -79,7 +79,8 @@ private:
Qt::CaseSensitivity q_cs;
#ifdef Q_CC_RVCT
// explicitely allow anonymous unions for RVCT to prevent compiler warnings
-#pragma anon_unions
+# pragma push
+# pragma anon_unions
#endif
struct Data {
uchar q_skiptable[256];
@@ -90,6 +91,9 @@ private:
uint q_data[256];
Data p;
};
+#ifdef Q_CC_RVCT
+# pragma pop
+#endif
};
QT_END_NAMESPACE
diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp
index 115fe3e..1557b47 100644
--- a/src/dbus/qdbusservicewatcher.cpp
+++ b/src/dbus/qdbusservicewatcher.cpp
@@ -47,6 +47,8 @@
#include <private/qobject_p.h>
+QT_BEGIN_NAMESPACE
+
Q_GLOBAL_STATIC_WITH_ARGS(QString, busService, (QLatin1String(DBUS_SERVICE_DBUS)))
Q_GLOBAL_STATIC_WITH_ARGS(QString, busPath, (QLatin1String(DBUS_PATH_DBUS)))
Q_GLOBAL_STATIC_WITH_ARGS(QString, busInterface, (QLatin1String(DBUS_INTERFACE_DBUS)))
@@ -371,4 +373,6 @@ void QDBusServiceWatcher::setConnection(const QDBusConnection &connection)
d->setConnection(d->servicesWatched, connection, d->watchMode);
}
+QT_END_NAMESPACE
+
#include "moc_qdbusservicewatcher.cpp"
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 175b6b1..2bfe33c 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1296,7 +1296,9 @@ QVariant QTextControl::loadResource(int type, const QUrl &name)
void QTextControlPrivate::_q_updateBlock(const QTextBlock &block)
{
Q_Q(QTextControl);
- emit q->updateRequest(q->blockBoundingRect(block));
+ QRectF br = q->blockBoundingRect(block);
+ br.setRight(qreal(INT_MAX)); // the block might have shrunk
+ emit q->updateRequest(br);
}
QRectF QTextControlPrivate::rectForPosition(int position) const
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 8a745ab..d812d88 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -363,7 +363,8 @@ bool QLocalSocket::canReadLine() const
Q_D(const QLocalSocket);
if (state() != ConnectedState)
return false;
- return (d->readBuffer.indexOf('\n') != -1 || QIODevice::canReadLine());
+ return (QIODevice::canReadLine()
+ || d->readBuffer.indexOf('\n', d->actualReadBufferSize) != -1);
}
void QLocalSocket::close()
diff --git a/tests/auto/linguist/lrelease/tst_lrelease.cpp b/tests/auto/linguist/lrelease/tst_lrelease.cpp
index 39de8a1..93cb97c 100644
--- a/tests/auto/linguist/lrelease/tst_lrelease.cpp
+++ b/tests/auto/linguist/lrelease/tst_lrelease.cpp
@@ -60,6 +60,7 @@ private slots:
void mixedcodecs();
void compressed();
void idbased();
+ void markuntranslated();
void dupes();
private:
@@ -210,6 +211,18 @@ void tst_lrelease::idbased()
QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("This has no translation."));
}
+void tst_lrelease::markuntranslated()
+{
+ QVERIFY(!QProcess::execute(binDir + "/lrelease -markuntranslated # -idbased testdata/idbased.ts"));
+
+ QTranslator translator;
+ QVERIFY(translator.load("testdata/idbased.qm"));
+ qApp->installTranslator(&translator);
+
+ QCOMPARE(qtTrId("test_id"), QString::fromAscii("This is a test string."));
+ QCOMPARE(qtTrId("untranslated_id"), QString::fromAscii("#This has no translation."));
+}
+
void tst_lrelease::dupes()
{
QProcess proc;
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
index eaa271a..7ddb68f 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.cpp
@@ -63,3 +63,52 @@ line c++ comment } (with brace)
#define This is another // comment in } define \
something } comment
} // complain here
+
+
+
+// Nested class in same file
+class TopLevel {
+ Q_OBJECT
+
+ class Nested;
+};
+
+class TopLevel::Nested {
+ void foo();
+};
+
+TopLevel::Nested::foo()
+{
+ TopLevel::tr("TopLevel");
+}
+
+// Nested class in other file
+#include "main.h"
+
+class TopLevel2::Nested {
+ void foo();
+};
+
+TopLevel2::Nested::foo()
+{
+ TopLevel2::tr("TopLevel2");
+}
+
+
+
+namespace NameSpace {
+class ToBeUsed;
+}
+
+// using statement before class definition
+using NameSpace::ToBeUsed;
+
+class NameSpace::ToBeUsed {
+ Q_OBJECT
+ void caller();
+};
+
+void ToBeUsed::caller()
+{
+ tr("NameSpace::ToBeUsed");
+}
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h
new file mode 100644
index 0000000..54a76ab
--- /dev/null
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/main.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// IMPORTANT!!!! If you want to add testdata to this file,
+// always add it to the end in order to not change the linenumbers of translations!!!
+
+class TopLevel2 {
+ Q_OBJECT
+
+ class Nested;
+};
+
+
diff --git a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
index 07a7469..6f48e27 100644
--- a/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/parsecpp2/project.ts.result
@@ -1,4 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0">
+<context>
+ <name>NameSpace::ToBeUsed</name>
+ <message>
+ <location filename="main.cpp" line="113"/>
+ <source>NameSpace::ToBeUsed</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TopLevel</name>
+ <message>
+ <location filename="main.cpp" line="82"/>
+ <source>TopLevel</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>TopLevel2</name>
+ <message>
+ <location filename="main.cpp" line="94"/>
+ <source>TopLevel2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
</TS>
diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp
index f35d4d2..9dc467e 100644
--- a/tests/auto/qstringbuilder1/stringbuilder.cpp
+++ b/tests/auto/qstringbuilder1/stringbuilder.cpp
@@ -41,8 +41,15 @@
#define LITERAL "some literal"
+// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
+#define UTF8_LITERAL "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l"
+
void runScenario()
{
+ // set codec for C strings to 0, enforcing Latin1
+ QTextCodec::setCodecForCStrings(0);
+ QVERIFY(!QTextCodec::codecForCStrings());
+
QLatin1Literal l1literal(LITERAL);
QLatin1String l1string(LITERAL);
QString string(l1string);
@@ -75,5 +82,24 @@ void runScenario()
QCOMPARE(r, r2);
r = string P ba;
QCOMPARE(r, r2);
+
+ // now test with codec for C strings set
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+ QVERIFY(QTextCodec::codecForCStrings());
+ QCOMPARE(QTextCodec::codecForCStrings()->name(), QByteArray("UTF-8"));
+
+ string = QString::fromUtf8(UTF8_LITERAL);
+ r2 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
+ ba = UTF8_LITERAL;
+
+ r = string P UTF8_LITERAL;
+ QCOMPARE(r.size(), r2.size());
+ QCOMPARE(r, r2);
+ r = UTF8_LITERAL P string;
+ QCOMPARE(r, r2);
+ r = ba P string;
+ QCOMPARE(r, r2);
+ r = string P ba;
+ QCOMPARE(r, r2);
#endif
}
diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro
index 011dec2..51933de 100644
--- a/tools/assistant/lib/lib.pro
+++ b/tools/assistant/lib/lib.pro
@@ -40,7 +40,8 @@ SOURCES += qhelpenginecore.cpp \
qhelpsearchindex_default.cpp \
qhelpsearchindexwriter_default.cpp \
qhelpsearchindexreader_default.cpp \
- qhelpsearchindexreader.cpp
+ qhelpsearchindexreader.cpp \
+ qhelp_global.cpp
# access to clucene
SOURCES += qhelpsearchindexwriter_clucene.cpp \
diff --git a/tools/assistant/lib/qhelp_global.cpp b/tools/assistant/lib/qhelp_global.cpp
new file mode 100644
index 0000000..980de27
--- /dev/null
+++ b/tools/assistant/lib/qhelp_global.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Assistant.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QRegExp>
+#include <QtCore/QMutexLocker>
+#include <QtGui/QTextDocument>
+
+#include "qhelp_global.h"
+
+QString QHelpGlobal::uniquifyConnectionName(const QString &name, void *pointer)
+{
+ static int counter = 0;
+ static QMutex mutex;
+
+ QMutexLocker locker(&mutex);
+ if (++counter > 1000)
+ counter = 0;
+
+ return QString::fromLatin1("%1-%2-%3").
+ arg(name).arg(long(pointer)).arg(counter);
+}
+
+QString QHelpGlobal::documentTitle(const QString &content)
+{
+ QString title = QObject::tr("Untitled");
+ if (!content.isEmpty()) {
+ int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
+ int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
+ if ((end - start) > 0) {
+ title = content.mid(start, end - start);
+ if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) {
+ QTextDocument doc;
+ doc.setHtml(title);
+ title = doc.toPlainText();
+ }
+ }
+ }
+ return title;
+}
+
+QString QHelpGlobal::codecFromData(const QByteArray &data)
+{
+ QString codec = codecFromXmlData(data);
+ if (codec.isEmpty())
+ codec = codecFromHtmlData(data);
+ return codec.isEmpty() ? QLatin1String("utf-8") : codec;
+}
+
+QString QHelpGlobal::codecFromHtmlData(const QByteArray &data)
+{
+ QString content = QString::fromUtf8(data.constData(), data.size());
+ int start = content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
+ if (start > 0) {
+ int end;
+ QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
+ while (start != -1) {
+ end = content.indexOf(QLatin1Char('>'), start) + 1;
+ const QString &meta = content.mid(start, end - start).toLower();
+ if (r.indexIn(meta) != -1)
+ return r.cap(1);
+ start = content.indexOf(QLatin1String("<meta"), end,
+ Qt::CaseInsensitive);
+ }
+ }
+ return QString();
+}
+
+QString QHelpGlobal::codecFromXmlData(const QByteArray &data)
+{
+ QString content = QString::fromUtf8(data.constData(), data.size());
+ const QRegExp encodingExp(QLatin1String("^\\s*<\\?xml version="
+ "\"\\d\\.\\d\" encoding=\"([^\"]+)\"\\?>.*"));
+ return encodingExp.exactMatch(content) ? encodingExp.cap(1) : QString();
+}
diff --git a/tools/assistant/lib/qhelp_global.h b/tools/assistant/lib/qhelp_global.h
index 723d867..4e31d67 100644
--- a/tools/assistant/lib/qhelp_global.h
+++ b/tools/assistant/lib/qhelp_global.h
@@ -45,9 +45,6 @@
#include <QtCore/qglobal.h>
#include <QtCore/QString>
#include <QtCore/QObject>
-#include <QtCore/QRegExp>
-#include <QtCore/QMutexLocker>
-#include <QtGui/QTextDocument>
QT_BEGIN_HEADER
@@ -65,56 +62,13 @@ QT_MODULE(Help)
class QHelpGlobal {
public:
- static QString uniquifyConnectionName(const QString &name, void *pointer)
- {
- static int counter = 0;
- static QMutex mutex;
+ static QString uniquifyConnectionName(const QString &name, void *pointer);
+ static QString documentTitle(const QString &content);
+ static QString codecFromData(const QByteArray &data);
- QMutexLocker locker(&mutex);
- if (++counter > 1000)
- counter = 0;
-
- return QString::fromLatin1("%1-%2-%3")
- .arg(name).arg(long(pointer)).arg(counter);
- };
-
- static QString documentTitle(const QString &content)
- {
- QString title = QObject::tr("Untitled");
- if (!content.isEmpty()) {
- int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
- int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
- if ((end - start) > 0) {
- title = content.mid(start, end - start);
- if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) {
- QTextDocument doc;
- doc.setHtml(title);
- title = doc.toPlainText();
- }
- }
- }
- return title;
- };
-
- static QString charsetFromData(const QByteArray &data)
- {
- QString content = QString::fromUtf8(data.constData(), data.size());
- int start =
- content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
- if (start > 0) {
- int end;
- QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
- while (start != -1) {
- end = content.indexOf(QLatin1Char('>'), start) + 1;
- const QString &meta = content.mid(start, end - start).toLower();
- if (r.indexIn(meta) != -1)
- return r.cap(1);
- start = content.indexOf(QLatin1String("<meta"), end,
- Qt::CaseInsensitive);
- }
- }
- return QLatin1String("utf-8");
- }
+private:
+ static QString codecFromHtmlData(const QByteArray &data);
+ static QString codecFromXmlData(const QByteArray &data);
};
QT_END_NAMESPACE
diff --git a/tools/assistant/lib/qhelpgenerator.cpp b/tools/assistant/lib/qhelpgenerator.cpp
index 0294b30..48d73aa 100644
--- a/tools/assistant/lib/qhelpgenerator.cpp
+++ b/tools/assistant/lib/qhelpgenerator.cpp
@@ -528,7 +528,7 @@ bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPa
QByteArray data = fi.readAll();
if (fileName.endsWith(QLatin1String(".html"))
|| fileName.endsWith(QLatin1String(".htm"))) {
- charSet = QHelpGlobal::charsetFromData(data);
+ charSet = QHelpGlobal::codecFromData(data);
QTextStream stream(&data);
stream.setCodec(QTextCodec::codecForName(charSet.toLatin1().constData()));
title = QHelpGlobal::documentTitle(stream.readAll());
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
index 284cbd3..ab32537 100644
--- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
+++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
@@ -430,8 +430,8 @@ private:
QString readData(const QByteArray &data)
{
QTextStream textStream(data);
- QByteArray charSet = QHelpGlobal::charsetFromData(data).toLatin1();
- textStream.setCodec(QTextCodec::codecForName(charSet.constData()));
+ const QByteArray &codec = QHelpGlobal::codecFromData(data).toLatin1();
+ textStream.setCodec(QTextCodec::codecForName(codec.constData()));
QString stream = textStream.readAll();
if (stream.isNull() || stream.isEmpty())
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp
index 36b115e..06deb85 100644
--- a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp
+++ b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp
@@ -274,7 +274,7 @@ void QHelpSearchIndexWriter::run()
continue;
QTextStream s(data);
- QString en = QHelpGlobal::charsetFromData(data);
+ QString en = QHelpGlobal::codecFromData(data);
s.setCodec(QTextCodec::codecForName(en.toLatin1().constData()));
QString text = s.readAll();
diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro
index 1cbd1d3..1a7e874 100644
--- a/tools/assistant/tools/assistant/assistant.pro
+++ b/tools/assistant/tools/assistant/assistant.pro
@@ -4,8 +4,6 @@ TEMPLATE = app
LANGUAGE = C++
TARGET = assistant
-DEFINES += QT_CLUCENE_SUPPORT
-
contains(QT_CONFIG, webkit) {
QT += webkit
}
diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp
index 53f3822..c888a5f 100644
--- a/tools/assistant/tools/assistant/helpviewer.cpp
+++ b/tools/assistant/tools/assistant/helpviewer.cpp
@@ -137,24 +137,22 @@ QNetworkReply *HelpNetworkAccessManager::createRequest(Operation op,
const QNetworkRequest &request, QIODevice *outgoingData)
{
const QString& scheme = request.url().scheme();
- if (scheme == QLatin1String("qthelp") || scheme == QLatin1String("about")) {
- const QUrl& url = request.url();
- QString mimeType = url.toString();
- if (mimeType.endsWith(QLatin1String(".svg"))
- || mimeType.endsWith(QLatin1String(".svgz"))) {
- mimeType = QLatin1String("image/svg+xml");
- }
- else if (mimeType.endsWith(QLatin1String(".css"))) {
- mimeType = QLatin1String("text/css");
- }
- else if (mimeType.endsWith(QLatin1String(".js"))) {
- mimeType = QLatin1String("text/javascript");
- } else {
- mimeType = QLatin1String("text/html");
- }
- return new HelpNetworkReply(request, helpEngine->fileData(url), mimeType);
+ const QUrl& url = request.url();
+ QString mimeType = url.toString();
+ if (mimeType.endsWith(QLatin1String(".svg"))
+ || mimeType.endsWith(QLatin1String(".svgz"))) {
+ mimeType = QLatin1String("image/svg+xml");
}
- return QNetworkAccessManager::createRequest(op, request, outgoingData);
+ else if (mimeType.endsWith(QLatin1String(".css"))) {
+ mimeType = QLatin1String("text/css");
+ }
+ else if (mimeType.endsWith(QLatin1String(".js"))) {
+ mimeType = QLatin1String("text/javascript");
+ } else {
+ mimeType = QLatin1String("text/html");
+ }
+
+ return new HelpNetworkReply(request, helpEngine->fileData(url), mimeType);
}
class HelpPage : public QWebPage
diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp
index 4d7fe10..12bc5b1 100644
--- a/tools/assistant/tools/assistant/main.cpp
+++ b/tools/assistant/tools/assistant/main.cpp
@@ -115,7 +115,7 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller)
const uint userCollectionCreationTime = user.
customValue(QLatin1String("CreationTime"), 1).toUInt();
- if (callerCollectionCreationTime == userCollectionCreationTime)
+ if (callerCollectionCreationTime <= userCollectionCreationTime)
return false;
user.setCustomValue(QLatin1String("CreationTime"),
@@ -124,6 +124,12 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller)
caller.customValue(QLatin1String("WindowTitle")));
user.setCustomValue(QLatin1String("LastShownPages"),
caller.customValue(QLatin1String("LastShownPages")));
+#if !defined(QT_NO_WEBKIT)
+ const QLatin1String zoomKey("LastPagesZoomWebView");
+#else
+ const QLatin1String zoomKey("LastPagesZoomTextBrowser");
+#endif
+ user.setCustomValue(zoomKey, caller.customValue(zoomKey));
user.setCustomValue(QLatin1String("CurrentFilter"),
caller.customValue(QLatin1String("CurrentFilter")));
user.setCustomValue(QLatin1String("CacheDirectory"),
@@ -148,6 +154,8 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller)
caller.customValue(QLatin1String("AboutTexts")));
user.setCustomValue(QLatin1String("AboutImages"),
caller.customValue(QLatin1String("AboutImages")));
+ user.setCustomValue(QLatin1String("defaultHomepage"),
+ caller.customValue(QLatin1String("defaultHomepage")));
return true;
}
diff --git a/tools/assistant/tools/assistant/searchwidget.cpp b/tools/assistant/tools/assistant/searchwidget.cpp
index 48fa8c6..3b456a3 100644
--- a/tools/assistant/tools/assistant/searchwidget.cpp
+++ b/tools/assistant/tools/assistant/searchwidget.cpp
@@ -85,7 +85,8 @@ SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
SLOT(searchingFinished(int)));
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
- browser->viewport()->installEventFilter(this);
+ if (browser) // Will be null if lib was configured not to use CLucene.
+ browser->viewport()->installEventFilter(this);
}
SearchWidget::~SearchWidget()
diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 2867849..ecaed27 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -79,6 +79,9 @@ static void printUsage()
" -removeidentical\n"
" If the translated text is the same as\n"
" the source text, do not include the message\n"
+ " -markuntranslated <prefix>\n"
+ " If a message has no real translation, use the source text\n"
+ " prefixed with the given string instead\n"
" -silent\n"
" Do not explain what is being done\n"
" -version\n"
@@ -100,15 +103,14 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo
}
static bool releaseTranslator(Translator &tor, const QString &qmFileName,
- bool verbose, bool ignoreUnfinished,
- bool removeIdentical, bool idBased, TranslatorSaveMode mode)
+ ConversionData &cd, bool removeIdentical)
{
- Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose);
+ Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, cd.isVerbose());
- if (verbose)
+ if (cd.isVerbose())
printOut(QCoreApplication::tr( "Updating '%1'...\n").arg(qmFileName));
if (removeIdentical) {
- if ( verbose )
+ if (cd.isVerbose())
printOut(QCoreApplication::tr( "Removing translations equal to source text in '%1'...\n").arg(qmFileName));
tor.stripIdenticalSourceTranslations();
}
@@ -120,12 +122,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
return false;
}
- ConversionData cd;
tor.normalizeTranslations(cd);
- cd.m_verbose = verbose;
- cd.m_ignoreUnfinished = ignoreUnfinished;
- cd.m_idBased = idBased;
- cd.m_saveMode = mode;
bool ok = tor.release(&file, cd);
file.close();
@@ -139,11 +136,11 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
return true;
}
-static bool releaseTsFile(const QString& tsFileName, bool verbose,
- bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode)
+static bool releaseTsFile(const QString& tsFileName,
+ ConversionData &cd, bool removeIdentical)
{
Translator tor;
- if (!loadTsFile(tor, tsFileName, verbose))
+ if (!loadTsFile(tor, tsFileName, cd.isVerbose()))
return false;
QString qmFileName = tsFileName;
@@ -155,7 +152,7 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose,
}
qmFileName += QLatin1String(".qm");
- return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode);
+ return releaseTranslator(tor, qmFileName, cd, removeIdentical);
}
int main(int argc, char **argv)
@@ -166,37 +163,40 @@ int main(int argc, char **argv)
if (translator.load(QLatin1String("lrelease_") + QLocale::system().name()))
app.installTranslator(&translator);
- bool verbose = true; // the default is true starting with Qt 4.2
- bool ignoreUnfinished = false;
- bool idBased = false;
- // the default mode is SaveEverything starting with Qt 4.2
- TranslatorSaveMode mode = SaveEverything;
+ ConversionData cd;
+ cd.m_verbose = true; // the default is true starting with Qt 4.2
bool removeIdentical = false;
Translator tor;
+ QStringList inputFiles;
QString outputFile;
- int numFiles = 0;
for (int i = 1; i < argc; ++i) {
if (args[i] == QLatin1String("-compress")) {
- mode = SaveStripped;
+ cd.m_saveMode = SaveStripped;
continue;
} else if (args[i] == QLatin1String("-idbased")) {
- idBased = true;
+ cd.m_idBased = true;
continue;
} else if (args[i] == QLatin1String("-nocompress")) {
- mode = SaveEverything;
+ cd.m_saveMode = SaveEverything;
continue;
} else if (args[i] == QLatin1String("-removeidentical")) {
removeIdentical = true;
continue;
} else if (args[i] == QLatin1String("-nounfinished")) {
- ignoreUnfinished = true;
+ cd.m_ignoreUnfinished = true;
continue;
+ } else if (args[i] == QLatin1String("-markuntranslated")) {
+ if (i == argc - 1) {
+ printUsage();
+ return 1;
+ }
+ cd.m_unTrPrefix = args[++i];
} else if (args[i] == QLatin1String("-silent")) {
- verbose = false;
+ cd.m_verbose = false;
continue;
} else if (args[i] == QLatin1String("-verbose")) {
- verbose = true;
+ cd.m_verbose = true;
continue;
} else if (args[i] == QLatin1String("-version")) {
printOut(QCoreApplication::tr( "lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)) );
@@ -206,41 +206,37 @@ int main(int argc, char **argv)
printUsage();
return 1;
}
- i++;
- outputFile = args[i];
+ outputFile = args[++i];
} else if (args[i] == QLatin1String("-help")) {
printUsage();
return 0;
- } else if (args[i][0] == QLatin1Char('-')) {
+ } else if (args[i].startsWith(QLatin1Char('-'))) {
printUsage();
return 1;
} else {
- numFiles++;
+ inputFiles << args[i];
}
}
- if (numFiles == 0) {
+ if (inputFiles.isEmpty()) {
printUsage();
return 1;
}
- for (int i = 1; i < argc; ++i) {
- if (args[i][0] == QLatin1Char('-') || args[i] == outputFile)
- continue;
-
- if (args[i].endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
- || args[i].endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
+ foreach (const QString &inputFile, inputFiles) {
+ if (inputFile.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
+ || inputFile.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
QHash<QByteArray, QStringList> varMap;
- bool ok = evaluateProFile(args[i], verbose, &varMap );
+ bool ok = evaluateProFile(inputFile, cd.isVerbose(), &varMap);
if (ok) {
QStringList translations = varMap.value("TRANSLATIONS");
if (translations.isEmpty()) {
qWarning("lrelease warning: Met no 'TRANSLATIONS' entry in"
" project file '%s'\n",
- qPrintable(args[i]));
+ qPrintable(inputFile));
} else {
foreach (const QString &trans, translations)
- if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode))
+ if (!releaseTsFile(trans, cd, removeIdentical))
return 1;
}
} else {
@@ -251,18 +247,17 @@ int main(int argc, char **argv)
}
} else {
if (outputFile.isEmpty()) {
- if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode))
+ if (!releaseTsFile(inputFile, cd, removeIdentical))
return 1;
} else {
- if (!loadTsFile(tor, args[i], verbose))
+ if (!loadTsFile(tor, inputFile, cd.isVerbose()))
return 1;
}
}
}
if (!outputFile.isEmpty())
- return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished,
- removeIdentical, idBased, mode) ? 0 : 1;
+ return releaseTranslator(tor, outputFile, cd, removeIdentical) ? 0 : 1;
return 0;
}
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
index 4d89156..fb95a95 100644
--- a/tools/linguist/lupdate/cpp.cpp
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -135,6 +135,11 @@ struct Namespace {
// Nested classes may be forward-declared inside a definition, and defined in another file.
// The latter will detach the class' child list, so clones need a backlink to the original
// definition (either one in case of multiple definitions).
+ // Namespaces can have tr() functions as well, so we need to track parent definitions for
+ // them as well. The complication is that we may have to deal with a forrest instead of
+ // a tree - in that case the parent will be arbitrary. However, it seem likely that
+ // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central
+ // header or only locally in a file.
Namespace *classDef;
QString trQualification;
@@ -256,17 +261,20 @@ private:
bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const;
bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
NamespaceList *resolved) const;
- bool fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments,
- bool isDeclaration,
+ bool fullyQualify(const NamespaceList &namespaces, int nsCnt,
+ const QList<HashString> &segments, bool isDeclaration,
NamespaceList *resolved, QStringList *unresolved) const;
- bool fullyQualify(const NamespaceList &namespaces, const QString &segments,
- bool isDeclaration,
+ bool fullyQualify(const NamespaceList &namespaces,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const;
+ bool fullyQualify(const NamespaceList &namespaces,
+ const QString &segments, bool isDeclaration,
NamespaceList *resolved, QStringList *unresolved) const;
bool findNamespaceCallback(const Namespace *ns, void *context) const;
const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const;
void enterNamespace(NamespaceList *namespaces, const HashString &name);
void truncateNamespaces(NamespaceList *namespaces, int lenght);
- Namespace *modifyNamespace(NamespaceList *namespaces, bool tryOrigin = true);
+ Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true);
enum {
Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
@@ -780,7 +788,7 @@ uint CppParser::getToken()
if (yyCh == EOF) {
qWarning("%s:%d: Unterminated C++ comment\n",
qPrintable(yyFileName), yyLineNo);
- return Tok_Comment;
+ break;
}
*ptr++ = yyCh;
@@ -958,7 +966,7 @@ void CppParser::loadState(const SavedState *state)
pendingContext = state->pendingContext;
}
-Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin)
+Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool haveLast)
{
Namespace *pns, *ns = &results->rootNamespace;
for (int i = 1; i < namespaces->count(); ++i) {
@@ -966,7 +974,7 @@ Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin)
if (!(ns = pns->children.value(namespaces->at(i)))) {
do {
ns = new Namespace;
- if (tryOrigin)
+ if (haveLast || i < namespaces->count() - 1)
if (const Namespace *ons = findNamespace(*namespaces, i + 1))
ns->classDef = ons->classDef;
pns->children.insert(namespaces->at(i), ns);
@@ -1052,7 +1060,18 @@ bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const
}
QHash<HashString, NamespaceList>::ConstIterator nsai = ns->aliases.constFind(data->segment);
if (nsai != ns->aliases.constEnd()) {
- *data->resolved = *nsai;
+ const NamespaceList &nsl = *nsai;
+ if (nsl.last().value().isEmpty()) { // Delayed alias resolution
+ NamespaceList &nslIn = *const_cast<NamespaceList *>(&nsl);
+ nslIn.removeLast();
+ NamespaceList nslOut;
+ if (!fullyQualify(data->namespaces, data->nsCount, nslIn, false, &nslOut, 0)) {
+ const_cast<Namespace *>(ns)->aliases.remove(data->segment);
+ return false;
+ }
+ nslIn = nslOut;
+ }
+ *data->resolved = nsl;
return true;
}
return false;
@@ -1081,8 +1100,8 @@ bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const Has
return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data);
}
-bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments,
- bool isDeclaration,
+bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt,
+ const QList<HashString> &segments, bool isDeclaration,
NamespaceList *resolved, QStringList *unresolved) const
{
int nsIdx;
@@ -1099,7 +1118,7 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashSt
nsIdx = 0;
} else {
initSegIdx = 0;
- nsIdx = namespaces.count() - 1;
+ nsIdx = nsCnt - 1;
}
do {
@@ -1122,8 +1141,16 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashSt
return false;
}
-bool CppParser::fullyQualify(const NamespaceList &namespaces, const QString &quali,
- bool isDeclaration,
+bool CppParser::fullyQualify(const NamespaceList &namespaces,
+ const QList<HashString> &segments, bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved) const
+{
+ return fullyQualify(namespaces, namespaces.count(),
+ segments, isDeclaration, resolved, unresolved);
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces,
+ const QString &quali, bool isDeclaration,
NamespaceList *resolved, QStringList *unresolved) const
{
static QString strColons(QLatin1String("::"));
@@ -1633,9 +1660,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
if (fullName.isEmpty())
break;
- NamespaceList nsl;
- if (fullyQualify(namespaces, fullName, false, &nsl, 0))
- modifyNamespace(&namespaces, false)->aliases[ns] = nsl;
+ fullName.append(HashString(QString())); // Mark as unresolved
+ modifyNamespace(&namespaces)->aliases[ns] = fullName;
}
} else if (yyTok == Tok_LeftBrace) {
// Anonymous namespace
@@ -1661,7 +1687,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
NamespaceList nsl;
if (fullyQualify(namespaces, fullName, false, &nsl, 0))
- modifyNamespace(&namespaces, false)->usings << HashStringList(nsl);
+ modifyNamespace(&namespaces)->usings << HashStringList(nsl);
} else {
QList<HashString> fullName;
if (yyTok == Tok_ColonColon)
@@ -1676,9 +1702,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
if (fullName.isEmpty())
break;
- NamespaceList nsl;
- if (fullyQualify(namespaces, fullName, false, &nsl, 0))
- modifyNamespace(&namespaces, true)->aliases[nsl.last()] = nsl;
+ // using-declarations cannot rename classes, so the last element of
+ // fullName is already the resolved name we actually want.
+ // As we do no resolution here, we'll collect useless usings of data
+ // members and methods as well. This is no big deal.
+ HashString &ns = fullName.last();
+ fullName.append(HashString(QString())); // Mark as unresolved
+ modifyNamespace(&namespaces)->aliases[ns] = fullName;
}
break;
case Tok_tr:
@@ -1875,7 +1905,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
break;
case Tok_Q_DECLARE_TR_FUNCTIONS:
if (getMacroArgs()) {
- Namespace *ns = modifyNamespace(&namespaces, true);
+ Namespace *ns = modifyNamespace(&namespaces);
ns->hasTrFunctions = true;
ns->trQualification = yyWord;
ns->trQualification.detach();
@@ -1883,7 +1913,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
yyTok = getToken();
break;
case Tok_Q_OBJECT:
- modifyNamespace(&namespaces, true)->hasTrFunctions = true;
+ modifyNamespace(&namespaces)->hasTrFunctions = true;
yyTok = getToken();
break;
case Tok_Ident:
diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp
index 317a07e..5965aac 100644
--- a/tools/linguist/shared/qm.cpp
+++ b/tools/linguist/shared/qm.cpp
@@ -172,8 +172,8 @@ public:
bool save(QIODevice *iod);
- void insert(const TranslatorMessage &msg, bool forceComment);
- void insertIdBased(const TranslatorMessage &message);
+ void insert(const TranslatorMessage &msg, const QStringList &tlns, bool forceComment);
+ void insertIdBased(const TranslatorMessage &message, const QStringList &tlns);
void squeeze(TranslatorSaveMode mode);
@@ -186,7 +186,8 @@ private:
// on turn should be the same as passed to the actual tr(...) calls
QByteArray originalBytes(const QString &str, bool isUtf8) const;
- void insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8);
+ void insertInternal(const TranslatorMessage &message, const QStringList &tlns,
+ bool forceComment, bool isUtf8);
static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2);
@@ -413,12 +414,13 @@ void Releaser::squeeze(TranslatorSaveMode mode)
}
}
-void Releaser::insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8)
+void Releaser::insertInternal(const TranslatorMessage &message, const QStringList &tlns,
+ bool forceComment, bool isUtf8)
{
ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8),
originalBytes(message.sourceText(), isUtf8),
originalBytes(message.comment(), isUtf8),
- message.translations());
+ tlns);
if (!forceComment) {
ByteTranslatorMessage bmsg2(
bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations());
@@ -430,20 +432,15 @@ void Releaser::insertInternal(const TranslatorMessage &message, bool forceCommen
m_messages.insert(bmsg, 0);
}
-void Releaser::insert(const TranslatorMessage &message, bool forceComment)
+void Releaser::insert(const TranslatorMessage &message, const QStringList &tlns, bool forceComment)
{
- insertInternal(message, forceComment, message.isUtf8());
+ insertInternal(message, tlns, forceComment, message.isUtf8());
if (message.isUtf8() && message.isNonUtf8())
- insertInternal(message, forceComment, false);
+ insertInternal(message, tlns, forceComment, false);
}
-void Releaser::insertIdBased(const TranslatorMessage &message)
+void Releaser::insertIdBased(const TranslatorMessage &message, const QStringList &tlns)
{
- QStringList tlns = message.translations();
- if (message.type() == TranslatorMessage::Unfinished)
- for (int i = 0; i < tlns.size(); ++i)
- if (tlns.at(i).isEmpty())
- tlns[i] = message.sourceText();
ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns);
m_messages.insert(bmsg, 0);
}
@@ -725,10 +722,16 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
} else {
++finished;
}
+ QStringList tlns = msg.translations();
+ if (msg.type() == TranslatorMessage::Unfinished
+ && (cd.m_idBased || !cd.m_unTrPrefix.isEmpty()))
+ for (int j = 0; j < tlns.size(); ++j)
+ if (tlns.at(j).isEmpty())
+ tlns[j] = cd.m_unTrPrefix + msg.sourceText();
if (cd.m_idBased) {
if (!msg.context().isEmpty() || !msg.comment().isEmpty())
++droppedData;
- releaser.insertIdBased(msg);
+ releaser.insertIdBased(msg, tlns);
} else {
// Drop the comment in (context, sourceText, comment),
// unless the context is empty,
@@ -739,7 +742,7 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
msg.comment().isEmpty()
|| msg.context().isEmpty()
|| translator.contains(msg.context(), msg.sourceText(), QString());
- releaser.insert(msg, forceComment);
+ releaser.insert(msg, tlns, forceComment);
}
}
}
diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h
index 1dd6a59..ef81d2a 100644
--- a/tools/linguist/shared/translator.h
+++ b/tools/linguist/shared/translator.h
@@ -86,6 +86,7 @@ public:
QString m_defaultContext;
QByteArray m_codecForSource; // CPP, PO & QM specific
QByteArray m_outputCodec; // PO specific
+ QString m_unTrPrefix; // QM specific
QString m_sourceFileName;
QString m_targetFileName;
QDir m_sourceDir;