diff options
109 files changed, 6245 insertions, 747 deletions
@@ -7086,9 +7086,6 @@ FNR == 1 { if ( \$3 == "moc" || \$3 ~ /^Qt/ ) { target_file = first matched_target = 1 - } else if ( \$3 == "lrelease" || \$3 == "qm_phony_target" ) { - target_file = second - matched_target = 1 } } @@ -7173,7 +7170,6 @@ for part in $CFG_BUILD_PARTS; do case "$part" in tools) PART_ROOTS="$PART_ROOTS tools" ;; libs) PART_ROOTS="$PART_ROOTS src" ;; - translations) PART_ROOTS="$PART_ROOTS tools/linguist/lrelease translations" ;; examples) PART_ROOTS="$PART_ROOTS examples demos" ;; *) ;; esac diff --git a/dist/changes-4.5.2 b/dist/changes-4.5.2 index 91a7bef..163e476 100644 --- a/dist/changes-4.5.2 +++ b/dist/changes-4.5.2 @@ -55,6 +55,10 @@ General Improvements Plugins (r41346, r43550, r43915, r43917, r43923) Clipboard (r41360) SVG (r43590, r43795) + * Backported various security fixes (r41262, r41568, + r41741, r41854, r42081, r42216, r42223, r42333, + r42365, r42532, r42533, r44010) + - QAbstractItemView * [250754] Changing the font of the view did not update the size of the diff --git a/doc/src/animation.qdoc b/doc/src/animation.qdoc index 843e0aa..da9b401 100644 --- a/doc/src/animation.qdoc +++ b/doc/src/animation.qdoc @@ -208,12 +208,6 @@ Note that QObject must be the first class inherited as the meta-object system demands this. - \warning The QItemAnimation class, which was initially intended - for animating \l{QGraphicsItem}s may be deprecated or removed from - the animation framework. - - \omit (need something about the list of animations). \endomit - \section1 Easing Curves As mentioned, QPropertyAnimation performs an interpolation between diff --git a/doc/src/known-issues.qdoc b/doc/src/known-issues.qdoc index e005b14..9c90908 100644 --- a/doc/src/known-issues.qdoc +++ b/doc/src/known-issues.qdoc @@ -58,13 +58,6 @@ \section1 Issues with Third Party Software - \section2 Intel Compiler Support - - Although it is possible to build applications against Qt 4.5.x using Intel - CC 10, these applications will crash when run. We recommend that developers - who rely on this compiler wait until a fix is available before upgrading to - the Qt 4.5.x series of releases. - \section2 X11 Hardware Support \list diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index 800e0be..805855a 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -2692,6 +2692,11 @@ the last image is not cropped. */ +/*! + \enum Qt::Initialization + \internal +*/ + /*! \enum Qt::GestureType \since 4.6 diff --git a/doc/src/snippets/statemachine/main.cpp b/doc/src/snippets/statemachine/main.cpp new file mode 100644 index 0000000..f20d245 --- /dev/null +++ b/doc/src/snippets/statemachine/main.cpp @@ -0,0 +1,48 @@ + +#include <QtGui> + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + QLabel *label = new QLabel; + +//![0] + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QState *s3 = new QState(); +//![0] + +//![4] + s1->assignProperty(label, "text", "In state s1"); + s2->assignProperty(label, "text", "In state s2"); + s3->assignProperty(label, "text", "In state s3"); +//![4] + +//![5] + QObject::connect(s3, SIGNAL(entered()), button, SLOT(showMaximized())); + QObject::connect(s3, SIGNAL(exited()), button, SLOT(showMinimized())); +//![5] + +//![1] + s1->addTransition(button, SIGNAL(clicked()), s2); + s2->addTransition(button, SIGNAL(clicked()), s3); + s3->addTransition(button, SIGNAL(clicked()), s1); +//![1] + +//![2] + machine.addState(s1); + machine.addState(s2); + machine.addState(s3); + machine.setInitialState(s1); +//![2] + +//![3] + machine.start(); +//![3] + + label->show(); + + return app.exec(); +} diff --git a/doc/src/snippets/statemachine/main2.cpp b/doc/src/snippets/statemachine/main2.cpp new file mode 100644 index 0000000..60a61e7 --- /dev/null +++ b/doc/src/snippets/statemachine/main2.cpp @@ -0,0 +1,51 @@ + +#include <QtGui> + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + QStateMachine machine; + +//![0] + QState *s1 = new QState(); + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); + QState *s13 = new QState(s1); + s1->setInitialState(s11); + machine.addState(s1); +//![0] + +//![2] + s12>addTransition(quitButton, SIGNAL(clicked()), s12); +//![2] + +//![1] + QFinalState *s2 = new QFinalState(); + s1->addTransition(quitButton, SIGNAL(clicked()), s2); + machine.addState(s2); + + QObject::connect(&machine, SIGNAL(finished()), QApplication::instance(), SLOT(quit())); +//![1] + + QButton *interruptButton = new QPushButton("Interrupt Button"); + +//![3] + QHistoryState *s1h = s1->addHistoryState(); + + QState *s3 = new QState(); + s3->assignProperty(label, "text", "In s3"); + QMessageBox mbox; + mbox.addButton(QMessageBox::Ok); + mbox.setText("Interrupted!"); + mbox.setIcon(QMessageBox::Information); + QObject::connect(s3, SIGNAL(entered()), &mbox, SLOT(exec())); + s3->addTransition(s1h); + machine.addState(s3); + + s1->addTransition(interruptButton, SIGNAL(clicked()), s3); +//![3] + + return app.exec(); +} + diff --git a/doc/src/snippets/statemachine/main3.cpp b/doc/src/snippets/statemachine/main3.cpp new file mode 100644 index 0000000..b04b850 --- /dev/null +++ b/doc/src/snippets/statemachine/main3.cpp @@ -0,0 +1,21 @@ + +#include <QtGui> + +int main(int argv, char **args) +{ + QApplication app(argv, args); + +//![0] + QState *s1 = new QState(QState::ParallelStates); + // s11 and s12 will be entered in parallel + QState *s11 = new QState(s1); + QState *s12 = new QState(s1); +//![0] + +//![1] + s1->addTransition(s1, SIGNAL(finished()), s2); +//![1] + + return app.exec(); +} + diff --git a/doc/src/snippets/statemachine/main4.cpp b/doc/src/snippets/statemachine/main4.cpp new file mode 100644 index 0000000..5681bbd --- /dev/null +++ b/doc/src/snippets/statemachine/main4.cpp @@ -0,0 +1,71 @@ + +#include <QtGui> + + +//![0] +struct StringEvent : public QEvent +{ + StringEvent(const QString &val) + : QEvent(QEvent::Type(QEvent::User+1)), + value(val) {} + + QString value; +}; +//![0] + +//![1] +class StringTransition : public QAbstractTransition +{ +public: + StringTransition(const QString &value) + : m_value(value) {} + +protected: + virtual bool eventTest(QEvent *e) const + { + if (e->type() != QEvent::Type(QEvent::User+1)) // StringEvent + return false; + StringEvent *se = static_cast<StringEvent*>(e); + return (m_value == se->value); + } + + virtual void onTransition(QEvent *) {} + +private: + QString m_value; +}; +//![1] + +int main(int argv, char **args) +{ + QApplication app(argv, args); + +//![2] + QStateMachine machine; + QState *s1 = new QState(); + QState *s2 = new QState(); + QFinalState *done = new QFinalState(); + + StringTransition *t1 = new StringTransition("Hello"); + t1->setTargetState(s2); + s1->addTransition(t1); + StringTransition *t2 = new StringTransition("world"); + t2->setTargetState(done); + s2->addTransition(t2); + + machine.addState(s1); + machine.addState(s2); + machine.addState(done); + machine.setInitialState(s1); +//![2] + +//![3] + machine.postEvent(new StringEvent("Hello")); + machine.postEvent(new StringEvent("world")); +//![3] + + return app.exec(); +} + +#include "main4.moc" + diff --git a/doc/src/snippets/statemachine/main5.cpp b/doc/src/snippets/statemachine/main5.cpp new file mode 100644 index 0000000..90ad8c7 --- /dev/null +++ b/doc/src/snippets/statemachine/main5.cpp @@ -0,0 +1,103 @@ + +#include <QtGui> + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + { +//![0] + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); +//![0] + +//![1] + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(); + machine.addState(s2); +//![1] + } + + { + +//![2] + QStateMachine machine; + machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); + + QState *s1 = new QState(); + s1->assignProperty(object, "fooBar", 1.0); + machine.addState(s1); + machine.setInitialState(s1); + + QState *s2 = new QState(s1); + s2->assignProperty(object, "fooBar", 2.0); + s1->setInitialState(s2); + + QState *s3 = new QState(s1); +//![2] + + } + + { +//![3] + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + s1->addTransition(button, SIGNAL(clicked()), s2); +//![3] + + } + + { +//![4] + QState *s1 = new QState(); + QState *s2 = new QState(); + + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + s2->assignProperty(button, "geometry", QRectF(0, 0, 100, 100)); + + QSignalTransition *transition = s1->addTransition(button, SIGNAL(clicked()), s2); + transition->addAnimation(new QPropertyAnimation(button, "geometry")); +//![4] + + } + + { + +//![5] + QState *s1 = new QState(); + s1->assignProperty(button, "geometry", QRectF(0, 0, 50, 50)); + + QState *s2 = new QState(); + + s1->addTransition(s1, SIGNAL(polished()), s2); +//![5] + + } + + { + +//![6] + QState *s1 = new QState(); + QState *s2 = new QState(); + + s2->assignProperty(object, "fooBar", 2.0); + s1->addTransition(s2); + + QStateMachine machine; + machine.setInitialState(s1); + machine.addDefaultAnimation(new QPropertyAnimation(object, "fooBar")); +//![6] + + } + + return app.exec(); +} + diff --git a/examples/widgets/calendarwidget/window.cpp b/examples/widgets/calendarwidget/window.cpp index 7672a05..c31ea0c 100644 --- a/examples/widgets/calendarwidget/window.cpp +++ b/examples/widgets/calendarwidget/window.cpp @@ -167,22 +167,22 @@ void Window::reformatHeaders() //! [8] void Window::reformatCalendarPage() { - QTextCharFormat mayFirstFormat; - if (mayFirstCheckBox->isChecked()) - mayFirstFormat.setForeground(Qt::red); - - QTextCharFormat firstFridayFormat; - if (firstFridayCheckBox->isChecked()) + if (firstFridayCheckBox->isChecked()) { + QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1); + while (firstFriday.dayOfWeek() != Qt::Friday) + firstFriday = firstFriday.addDays(1); + QTextCharFormat firstFridayFormat; firstFridayFormat.setForeground(Qt::blue); + calendar->setDateTextFormat(firstFriday, firstFridayFormat); + } - QDate date(calendar->yearShown(), calendar->monthShown(), 1); - - calendar->setDateTextFormat(QDate(date.year(), 5, 1), mayFirstFormat); - - date.setDate(date.year(), date.month(), 1); - while (date.dayOfWeek() != Qt::Friday) - date = date.addDays(1); - calendar->setDateTextFormat(date, firstFridayFormat); + //May First in Red takes precedence + if (mayFirstCheckBox->isChecked()) { + const QDate mayFirst(calendar->yearShown(), 5, 1); + QTextCharFormat mayFirstFormat; + mayFirstFormat.setForeground(Qt::red); + calendar->setDateTextFormat(mayFirst, mayFirstFormat); + } } //! [8] diff --git a/projects.pro b/projects.pro index 2d8e7f4..953eae8 100644 --- a/projects.pro +++ b/projects.pro @@ -41,12 +41,7 @@ for(PROJECT, $$list($$lower($$unique(QT_BUILD_PARTS)))) { } else:isEqual(PROJECT, docs) { contains(QT_BUILD_PARTS, tools):include(doc/doc.pri) } else:isEqual(PROJECT, translations) { - contains(QT_BUILD_PARTS, tools) { - include(translations/translations.pri) # ts targets - } else { - SUBDIRS += tools/linguist/lrelease - } - SUBDIRS += translations # qm build step + contains(QT_BUILD_PARTS, tools):include(translations/translations.pri) } else:isEqual(PROJECT, qmake) { # SUBDIRS += qmake } else { diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index a68301c..7526a81 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -43,6 +43,7 @@ \class QPropertyAnimation \brief The QPropertyAnimation class animates Qt properties \since 4.6 + \mainclass \ingroup animation QPropertyAnimation interpolates over \l{Qt's Property System}{Qt diff --git a/src/corelib/codecs/qfontlaocodec.cpp b/src/corelib/codecs/qfontlaocodec.cpp index 85017e0..6dd87de 100644 --- a/src/corelib/codecs/qfontlaocodec.cpp +++ b/src/corelib/codecs/qfontlaocodec.cpp @@ -97,8 +97,7 @@ QString QFontLaoCodec::convertToUnicode(const char *, int, ConverterState *) con QByteArray QFontLaoCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *) const { - QByteArray rstring; - rstring.resize(len); + QByteArray rstring(len, Qt::Uninitialized); uchar *rdata = (uchar *) rstring.data(); const QChar *sdata = uc; int i = 0; diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 6b9c77b..1bf76ea 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -225,11 +225,10 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState char *inBytes = const_cast<char *>(chars); #endif - QByteArray in; if (remainingCount) { // we have to prepend the remaining bytes from the previous conversion inBytesLeft += remainingCount; - in.resize(inBytesLeft); + QByteArray in(inBytesLeft, Qt::Uninitialized); inBytes = in.data(); memcpy(in.data(), remainingBuffer, remainingCount); @@ -238,9 +237,8 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState remainingCount = 0; } - QByteArray ba; size_t outBytesLeft = len * 2 + 2; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); char *outBytes = ba.data(); do { size_t ret = iconv(state->cd, &inBytes, &inBytesLeft, &outBytes, &outBytesLeft); @@ -328,8 +326,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt state = new IconvState(QIconvCodec::createIconv_t(0, UTF16)); if (state->cd != reinterpret_cast<iconv_t>(-1)) { size_t outBytesLeft = len + 3; // +3 for the BOM - QByteArray ba; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); outBytes = ba.data(); #if !defined(NO_BOM) @@ -358,18 +355,16 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } size_t outBytesLeft = len; - QByteArray ba; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); outBytes = ba.data(); // now feed iconv() the real data inBytes = const_cast<char *>(reinterpret_cast<const char *>(uc)); inBytesLeft = len * sizeof(QChar); - QByteArray in; if (convState && convState->remainingChars) { // we have one surrogate char to be prepended - in.resize(sizeof(QChar) + len); + QByteArray in(sizeof(QChar) + len, Qt::Uninitialized); inBytes = in.data(); QChar remaining = convState->state_data[0]; diff --git a/src/corelib/codecs/qisciicodec.cpp b/src/corelib/codecs/qisciicodec.cpp index a33fd0d..c054313 100644 --- a/src/corelib/codecs/qisciicodec.cpp +++ b/src/corelib/codecs/qisciicodec.cpp @@ -187,8 +187,7 @@ QByteArray QIsciiCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalid = 0; - QByteArray result; - result.resize(2*len); //worst case + QByteArray result(2 * len, Qt::Uninitialized); //worst case uchar *ch = reinterpret_cast<uchar *>(result.data()); @@ -250,8 +249,7 @@ QString QIsciiCodec::convertToUnicode(const char* chars, int len, ConverterState halant = state->state_data[0]; } - QString result; - result.resize(len); + QString result(len, Qt::Uninitialized); QChar *uc = result.data(); const int base = codecs[idx].base; diff --git a/src/corelib/codecs/qlatincodec.cpp b/src/corelib/codecs/qlatincodec.cpp index 176ae97..9113555 100644 --- a/src/corelib/codecs/qlatincodec.cpp +++ b/src/corelib/codecs/qlatincodec.cpp @@ -62,8 +62,7 @@ QString QLatin1Codec::convertToUnicode(const char *chars, int len, ConverterStat QByteArray QLatin1Codec::convertFromUnicode(const QChar *ch, int len, ConverterState *state) const { const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; - QByteArray r; - r.resize(len); + QByteArray r(len, Qt::Uninitialized); char *d = r.data(); int invalid = 0; for (int i = 0; i < len; ++i) { @@ -151,8 +150,7 @@ QString QLatin15Codec::convertToUnicode(const char* chars, int len, ConverterSta QByteArray QLatin15Codec::convertFromUnicode(const QChar *in, int length, ConverterState *state) const { const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; - QByteArray r; - r.resize(length); + QByteArray r(length, Qt::Uninitialized); char *d = r.data(); int invalid = 0; for (int i = 0; i < length; ++i) { diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 7a62d4e..0d14f67 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -653,8 +653,7 @@ QString QSimpleTextCodec::convertToUnicode(const char* chars, int len, Converter const unsigned char * c = (const unsigned char *)chars; - QString r; - r.resize(len); + QString r(len, Qt::Uninitialized); QChar* uc = r.data(); for (int i = 0; i < len; i++) { @@ -677,8 +676,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con delete tmp; } - QByteArray r; - r.resize(length); + QByteArray r(length, Qt::Uninitialized); int i = length; int u; const QChar* ucp = in; diff --git a/src/corelib/codecs/qtsciicodec.cpp b/src/corelib/codecs/qtsciicodec.cpp index 7f660bf..c24d32d 100644 --- a/src/corelib/codecs/qtsciicodec.cpp +++ b/src/corelib/codecs/qtsciicodec.cpp @@ -82,8 +82,7 @@ QByteArray QTsciiCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalid = 0; - QByteArray rstr; - rstr.resize(len); + QByteArray rstr(len, Qt::Uninitialized); uchar* cursor = (uchar*)rstr.data(); for (int i = 0; i < len; i++) { QChar ch = uc[i]; diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 12575f9..abae6f7 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -351,8 +351,7 @@ QString QUtf16Codec::convertToUnicode(const char *chars, int len, ConverterState if (headerdone && endian == Detect) endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BE : LE; - QString result; - result.resize(len); // worst case + QString result(len, Qt::Uninitialized); // worst case QChar *qch = (QChar *)result.unicode(); while (len--) { if (half) { @@ -472,8 +471,7 @@ QByteArray QUtf32Codec::convertFromUnicode(const QChar *uc, int len, ConverterSt endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BE : LE; } - QByteArray d; - d.resize(length); + QByteArray d(length, Qt::Uninitialized); char *data = d.data(); if (!state || !(state->flags & IgnoreHeader)) { if (endian == BE) { diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fe11fab..2e2a09d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1546,6 +1546,10 @@ public: TitleBarArea // For move }; + enum Initialization { + Uninitialized + }; + enum TouchPointState { TouchPointPressed = 0x01, TouchPointMoved = 0x02, diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 0c45776..5d3386e 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1304,6 +1304,21 @@ QByteArray::QByteArray(int size, char ch) } /*! + \internal + + Constructs a byte array of size \a size with uninitialized contents. +*/ + +QByteArray::QByteArray(int size, Qt::Initialization) +{ + d = static_cast<Data *>(qMalloc(sizeof(Data)+size)); + d->ref = 1; + d->alloc = d->size = size; + d->data = d->array; + d->array[size] = '\0'; +} + +/*! Sets the size of the byte array to \a size bytes. If \a size is greater than the current size, the byte array is @@ -2977,8 +2992,7 @@ QByteArray QByteArray::simplified() const { if (d->size == 0) return *this; - QByteArray result; - result.resize(d->size); + QByteArray result(d->size, Qt::Uninitialized); const char *from = d->data; const char *fromend = from + d->size; int outc=0; @@ -3429,8 +3443,7 @@ QByteArray QByteArray::toBase64() const const char padchar = '='; int padlen = 0; - QByteArray tmp; - tmp.resize(((d->size * 4) / 3) + 3); + QByteArray tmp((d->size * 4) / 3 + 3, Qt::Uninitialized); int i = 0; char *out = tmp.data(); @@ -3768,8 +3781,7 @@ QByteArray QByteArray::fromBase64(const QByteArray &base64) { unsigned int buf = 0; int nbits = 0; - QByteArray tmp; - tmp.resize((base64.size() * 3) / 4); + QByteArray tmp((base64.size() * 3) / 4, Qt::Uninitialized); int offset = 0; for (int i = 0; i < base64.size(); ++i) { @@ -3817,8 +3829,7 @@ QByteArray QByteArray::fromBase64(const QByteArray &base64) */ QByteArray QByteArray::fromHex(const QByteArray &hexEncoded) { - QByteArray res; - res.resize((hexEncoded.size() + 1)/ 2); + QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized); uchar *result = (uchar *)res.data() + res.size(); bool odd_digit = true; @@ -3855,8 +3866,7 @@ QByteArray QByteArray::fromHex(const QByteArray &hexEncoded) */ QByteArray QByteArray::toHex() const { - QByteArray hex; - hex.resize(d->size*2); + QByteArray hex(d->size * 2, Qt::Uninitialized); char *hexData = hex.data(); const uchar *data = (const uchar *)d->data; for (int i = 0; i < d->size; ++i) { diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 5cd4d63..e494ac1 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -42,8 +42,8 @@ #ifndef QBYTEARRAY_H #define QBYTEARRAY_H -#include <QtCore/qglobal.h> #include <QtCore/qatomic.h> +#include <QtCore/qnamespace.h> #include <string.h> #include <stdarg.h> @@ -127,6 +127,7 @@ public: QByteArray(const char *); QByteArray(const char *, int size); QByteArray(int size, char c); + QByteArray(int size, Qt::Initialization); inline QByteArray(const QByteArray &); inline ~QByteArray(); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 52fb8a2..cbdd32c 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -185,8 +185,7 @@ static QString languageToCode(QLocale::Language language) const unsigned char *c = language_code_list + 3*(uint(language)); - QString code; - code.resize(c[2] == 0 ? 2 : 3); + QString code(c[2] == 0 ? 2 : 3, Qt::Uninitialized); code[0] = ushort(c[0]); code[1] = ushort(c[1]); @@ -201,8 +200,7 @@ static QString countryToCode(QLocale::Country country) if (country == QLocale::AnyCountry) return QString(); - QString code; - code.resize(2); + QString code(2, Qt::Uninitialized); const unsigned char *c = country_code_list + 2*(uint(country)); code[0] = ushort(c[0]); code[1] = ushort(c[1]); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3b70f44..3ff263d 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1012,14 +1012,13 @@ QString::QString(int size, QChar ch) } } -/*! - Constructs a string of the given \a size without initializing the - characters. This is only used in \c QStringBuilder::toString(). +/*! \fn QString::QString(int size, Qt::Initialization) + \internal - \internal + Constructs a string of the given \a size without initializing the + characters. This is only used in \c QStringBuilder::toString(). */ - -QString::QString(int size, Uninitialized) +QString::QString(int size, Qt::Initialization) { d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar)); d->ref = 1; @@ -3849,8 +3848,7 @@ QString QString::fromUtf8(const char *str, int size) if (size < 0) size = qstrlen(str); - QString result; - result.resize(size); // worst case + QString result(size, Qt::Uninitialized); // worst case ushort *qch = result.d->data; uint uc = 0; uint min_uc = 0; @@ -3965,8 +3963,7 @@ QString QString::fromUcs4(const uint *unicode, int size) ++size; } - QString s; - s.resize(size*2); // worst case + QString s(size * 2, Qt::Uninitialized); // worst case ushort *uc = s.d->data; for (int i = 0; i < size; ++i) { uint u = unicode[i]; @@ -4029,8 +4026,7 @@ QString QString::simplified() const { if (d->size == 0) return *this; - QString result; - result.resize(d->size); + QString result(d->size, Qt::Uninitialized); const QChar *from = (const QChar*) d->data; const QChar *fromend = (const QChar*) from+d->size; int outc=0; @@ -4882,8 +4878,7 @@ QString QString::toLower() const c = QChar::surrogateToUcs4(*(p - 1), c); const QUnicodeTables::Properties *prop = qGetProp(c); if (prop->lowerCaseDiff || prop->lowerCaseSpecial) { - QString s; - s.resize(d->size); + QString s(d->size, Qt::Uninitialized); memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort)); ushort *pp = s.d->data + (p - d->data); while (p < e) { @@ -4974,8 +4969,7 @@ QString QString::toUpper() const c = QChar::surrogateToUcs4(*(p - 1), c); const QUnicodeTables::Properties *prop = qGetProp(c); if (prop->upperCaseDiff || prop->upperCaseSpecial) { - QString s; - s.resize(d->size); + QString s(d->size, Qt::Uninitialized); memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort)); ushort *pp = s.d->data + (p - d->data); while (p < e) { @@ -6272,8 +6266,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f + d.locale_occurrences *qMax(abs_field_width, larg.length()); - QString result; - result.resize(result_len); + QString result(result_len, Qt::Uninitialized); QChar *result_buff = (QChar*) result.unicode(); QChar *rc = result_buff; diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 4b2ceb7..6bb0d8e 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -579,8 +579,7 @@ public: bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; } bool isRightToLeft() const { if (!d->clean) updateProperties(); return d->righttoleft; } - struct Uninitialized {}; - QString(int size, Uninitialized); + QString(int size, Qt::Initialization); private: #if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 19f14b4..852c072 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -80,7 +80,7 @@ public: operator QString() const { QString s(QConcatenable< QStringBuilder<A, B> >::size(*this), - QString::Uninitialized()); + Qt::Uninitialized); QChar *d = s.data(); QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 582ba9b..e258cb5 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -501,8 +501,6 @@ void QFontDialogPrivate::updateFamilies() { Q_Q(QFontDialog); - familyList->blockSignals(true); - enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; QStringList familyNames = fdb.families(writingSystem); @@ -556,7 +554,6 @@ void QFontDialogPrivate::updateFamilies() && familyList->hasFocus()) familyEdit->selectAll(); - familyList->blockSignals(false); updateStyles(); } @@ -567,9 +564,6 @@ void QFontDialogPrivate::updateFamilies() void QFontDialogPrivate::updateStyles() { Q_Q(QFontDialog); - - styleList->blockSignals(true); - QStringList styles = fdb.styles(familyList->currentText()); styleList->model()->setStringList(styles); @@ -613,8 +607,6 @@ void QFontDialogPrivate::updateStyles() smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText()); } - styleList->blockSignals(false); - updateSizes(); } @@ -628,8 +620,6 @@ void QFontDialogPrivate::updateSizes() { Q_Q(QFontDialog); - sizeList->blockSignals(true); - if (!familyList->currentText().isEmpty()) { QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText()); @@ -659,7 +649,6 @@ void QFontDialogPrivate::updateSizes() sizeEdit->clear(); } - sizeList->blockSignals(false); _q_updateSample(); } diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/gui/dialogs/qinputdialog.cpp index 8c0c2c7..e2c5742 100644 --- a/src/gui/dialogs/qinputdialog.cpp +++ b/src/gui/dialogs/qinputdialog.cpp @@ -1128,8 +1128,8 @@ void QInputDialog::done(int result) is \a parent. The dialog will be modal and uses the specified widget \a flags. - This function returns the text which has been entered in the line - edit. It will not return an empty string. + If the dialog is accepted, this function returns the text in the dialog's + line edit. If the dialog is rejected, a null QString is returned. Use this static function like this: @@ -1158,7 +1158,7 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri if (ret) { return dialog.textValue(); } else { - return text; + return QString(); } } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1c062cc..e8ed97f 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -800,7 +800,7 @@ QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos, void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const { // COMBINE - if (itemIsUntransformable() && viewTransform) { + if (viewTransform && itemIsUntransformable()) { *x = q_ptr->deviceTransform(*viewTransform); } else { if (transformData) @@ -822,7 +822,7 @@ void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransf void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const { // COMBINE - if (itemIsUntransformable() && viewTransform) { + if (viewTransform && itemIsUntransformable()) { *x = q_ptr->deviceTransform(*viewTransform); } else { x->translate(pos.x(), pos.y()); @@ -992,7 +992,8 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec bool hasPos = !childd->pos.isNull(); if (hasPos || childd->transformData) { // COMBINE - QTransform matrix = childd->transformToParent() * *x; + QTransform matrix = childd->transformToParent(); + matrix *= *x; *rect |= matrix.mapRect(child->boundingRect()); if (!childd->children.isEmpty()) childd->childrenBoundingRectHelper(&matrix, rect); @@ -3238,8 +3239,7 @@ QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) c QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0)); // COMBINE - QTransform matrix; - matrix.translate(mappedPoint.x(), mappedPoint.y()); + QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y()); if (untransformedAncestor->d_ptr->transformData) matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix); @@ -3337,9 +3337,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co bool cousins = other != commonAncestor && this != commonAncestor; if (cousins) { bool good = false; - QTransform thisToScene; - QTransform otherToScene; - thisToScene = itemTransform(commonAncestor, &good); + QTransform thisToScene = itemTransform(commonAncestor, &good); + QTransform otherToScene(Qt::Uninitialized); if (good) otherToScene = other->itemTransform(commonAncestor, &good); if (!good) { @@ -4184,8 +4183,7 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c p.end(); // Transform QRegion back to device space - QTransform unscale; - unscale.scale(1 / granularity, 1 / granularity); + QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity); QRegion r; QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0)); foreach (const QRect &rect, QRegion( colorMask ).rects()) { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7428d79..6998429 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1428,6 +1428,63 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } +QList<QGraphicsItem *> QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform, + QRegion *exposedRegion) +{ + if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { + if (needSortTopLevelItems) { + needSortTopLevelItems = false; + qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + } + return topLevelItems; + } + + const QRectF exposedRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); + QRectF sceneRect; + QTransform invertedViewTransform(Qt::Uninitialized); + if (!viewTransform) { + sceneRect = exposedRect; + } else { + invertedViewTransform = viewTransform->inverted(); + sceneRect = invertedViewTransform.mapRect(exposedRect); + } + if (!largestUntransformableItem.isEmpty()) { + // ### Nuke this when we move the indexing code into a separate + // class. All the largestUntransformableItem code should then go + // away, and the estimate function should return untransformable + // items as well. + QRectF untr = largestUntransformableItem; + QRectF ltri = !viewTransform ? untr : invertedViewTransform.mapRect(untr); + ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); + sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); + } + + QList<QGraphicsItem *> tmp = estimateItemsInRect(sceneRect); + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + + // Sort if the toplevel list is unsorted. + if (needSortTopLevelItems) { + needSortTopLevelItems = false; + qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + } + + QList<QGraphicsItem *> tli; + for (int i = 0; i < topLevelItems.size(); ++i) { + // ### Investigate smarter ways. Looping through all top level + // items is not optimal. If the BSP tree is to have maximum + // effect, it should be possible to sort the subset of items + // quickly. We must use this approach for now, as it's the only + // current way to keep the stable sorting order (insertion order). + QGraphicsItem *item = topLevelItems.at(i); + if (item->d_ptr->itemDiscovered) { + item->d_ptr->itemDiscovered = 0; + tli << item; + } + } + return tli; +} + void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items, const QTransform &parentTransform, @@ -5169,165 +5226,118 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, - const QTransform &viewTransform, + const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget, - QList<QGraphicsItem *> *topLevelItems, qreal parentOpacity) { - // Calculate opacity. - qreal opacity; - bool invisibleButChildIgnoresParentOpacity = false; - if (item) { - if (!item->d_ptr->visible) - return; - opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { - invisibleButChildIgnoresParentOpacity = !item->d_ptr->childrenCombineOpacity(); - if (!invisibleButChildIgnoresParentOpacity) - return; - } - } else { - opacity = parentOpacity; - } - - // Item is invisible. - bool hasContents = item && !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); - bool invisible = !hasContents || invisibleButChildIgnoresParentOpacity; - - // Calculate the full transform for this item. - bool wasDirtyParentSceneTransform = false; - bool dontDrawItem = true; - QTransform transform; - if (item) { - if (item->d_ptr->itemIsUntransformable()) { - transform = item->deviceTransform(viewTransform); - } else { - if (item->d_ptr->dirtySceneTransform) { - item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform - : QTransform(); - item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); - item->d_ptr->dirtySceneTransform = 0; - wasDirtyParentSceneTransform = true; - } - transform = item->d_ptr->sceneTransform; - transform *= viewTransform; - } - - if (!invisible) { - QRectF brect = item->boundingRect(); - // ### This does not take the clip into account. - _q_adjustRect(&brect); - QRect viewBoundingRect = transform.mapRect(brect).toRect(); - item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); - viewBoundingRect.adjust(-1, -1, 1, 1); - if (exposedRegion) - dontDrawItem = !exposedRegion->intersects(viewBoundingRect); - else - dontDrawItem = viewBoundingRect.isEmpty(); - } - } + Q_ASSERT(item); - // Find and sort children. - QList<QGraphicsItem *> tmp; - QList<QGraphicsItem *> *children = 0; - if (item) { - children = &item->d_ptr->children; - } else if (topLevelItems) { - children = topLevelItems; - } else if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { - children = &this->topLevelItems; - } else { - QRectF sceneRect = viewTransform.inverted().mapRect(QRectF(exposedRegion->boundingRect().adjusted(-1, -1, 1, 1))); - if (!largestUntransformableItem.isEmpty()) { - // ### Nuke this when we move the indexing code into a separate - // class. All the largestUntransformableItem code should then go - // away, and the estimate function should return untransformable - // items as well. - QRectF untr = largestUntransformableItem; - QRectF ltri = viewTransform.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - } - tmp = estimateItemsInRect(sceneRect); + if (!item->d_ptr->visible) + return; - QList<QGraphicsItem *> tli; - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); + const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + if (!itemHasContents && !itemHasChildren) + return; // Item has neither contents nor children!(?) - // Sort if the toplevel list is unsorted. - if (needSortTopLevelItems) { - needSortTopLevelItems = false; - qStableSort(this->topLevelItems.begin(), - this->topLevelItems.end(), qt_notclosestLeaf); - } + const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + const bool itemIsFullyTransparent = (opacity < 0.0001); + if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) + return; - for (int i = 0; i < this->topLevelItems.size(); ++i) { - // ### Investigate smarter ways. Looping through all top level - // items is not optimal. If the BSP tree is to have maximum - // effect, it should be possible to sort the subset of items - // quickly. We must use this approach for now, as it's the only - // current way to keep the stable sorting order (insertion order). - QGraphicsItem *item = this->topLevelItems.at(i); - if (item->d_ptr->itemDiscovered) { - item->d_ptr->itemDiscovered = 0; - tli << item; + QTransform transform(Qt::Uninitialized); + QTransform *transformPtr = 0; +#define ENSURE_TRANSFORM_PTR \ + if (!transformPtr) { \ + Q_ASSERT(!itemIsUntransformable); \ + if (viewTransform) { \ + transform = item->d_ptr->sceneTransform; \ + transform *= *viewTransform; \ + transformPtr = &transform; \ + } else { \ + transformPtr = &item->d_ptr->sceneTransform; \ + } \ + } + + // Update the item's scene transform if the item is transformable; + // otherwise calculate the full transform, + bool wasDirtyParentSceneTransform = false; + const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable(); + if (itemIsUntransformable) { + transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform()); + transformPtr = &transform; + } else if (item->d_ptr->dirtySceneTransform) { + item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform + : QTransform(); + item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); + item->d_ptr->dirtySceneTransform = 0; + wasDirtyParentSceneTransform = true; + } + + const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + bool drawItem = itemHasContents && !itemIsFullyTransparent; + if (drawItem) { + const QRectF brect = adjustedItemBoundingRect(item); + ENSURE_TRANSFORM_PTR + QRect viewBoundingRect = transformPtr->mapRect(brect).toRect(); + item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); + viewBoundingRect.adjust(-1, -1, 1, 1); + drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty(); + if (!drawItem) { + if (!itemHasChildren) + return; + if (itemClipsChildrenToShape) { + if (wasDirtyParentSceneTransform) + item->d_ptr->invalidateChildrenSceneTransform(); + return; } } + } // else we know for sure this item has children we must process. - tmp = tli; - children = &tmp; - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontDrawChildren = item && hasContents && dontDrawItem && childClip; - childClip &= !dontDrawChildren && !children->isEmpty(); - if (item && invisible) - dontDrawItem = true; - - // Clip children. - if (childClip) { - painter->save(); - painter->setWorldTransform(transform); - painter->setClipPath(item->shape(), Qt::IntersectClip); - } - - if (!dontDrawChildren) { - if (item && item->d_ptr->needSortChildren) { + int i = 0; + if (itemHasChildren) { + if (item->d_ptr->needSortChildren) { item->d_ptr->needSortChildren = 0; - qStableSort(children->begin(), children->end(), qt_notclosestLeaf); - } else if (!item && needSortTopLevelItems && children != &tmp) { - needSortTopLevelItems = false; - qStableSort(children->begin(), children->end(), qt_notclosestLeaf); + qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); } - } - // Draw children behind - int i = 0; - if (!dontDrawChildren) { - // ### Don't visit children that don't ignore parent opacity if this - // item is invisible. - for (i = 0; i < children->size(); ++i) { - QGraphicsItem *child = children->at(i); + if (itemClipsChildrenToShape) { + painter->save(); + ENSURE_TRANSFORM_PTR + painter->setWorldTransform(*transformPtr); + painter->setClipPath(item->shape(), Qt::IntersectClip); + } + + // Draw children behind + for (i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, - 0, opacity); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity); } } // Draw item - if (!dontDrawItem) { - item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion ? *exposedRegion : QRegion(), exposedRegion == 0); - - bool clipsToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsToShape); - bool savePainter = clipsToShape || painterStateProtection; + if (drawItem) { + Q_ASSERT(!itemIsFullyTransparent); + Q_ASSERT(itemHasContents); + item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion + ? *exposedRegion : QRegion(), exposedRegion == 0); + + const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; + const bool savePainter = itemClipsToShape || painterStateProtection; if (savePainter) painter->save(); - if (!childClip) - painter->setWorldTransform(transform); - if (clipsToShape) + + if (!itemHasChildren || !itemClipsChildrenToShape) { + ENSURE_TRANSFORM_PTR + painter->setWorldTransform(*transformPtr); + } + if (itemClipsToShape) painter->setClipPath(item->shape(), Qt::IntersectClip); painter->setOpacity(opacity); @@ -5341,22 +5351,19 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * } // Draw children in front - if (!dontDrawChildren) { - // ### Don't visit children that don't ignore parent opacity if this - // item is invisible. - for (; i < children->size(); ++i) { - QGraphicsItem *child = children->at(i); + if (itemHasChildren) { + for (; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; - drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, - widget, 0, opacity); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity); } - } else if (wasDirtyParentSceneTransform) { - item->d_ptr->invalidateChildrenSceneTransform(); } // Restore child clip - if (childClip) + if (itemHasChildren && itemClipsChildrenToShape) painter->restore(); } @@ -5649,7 +5656,7 @@ void QGraphicsScene::drawItems(QPainter *painter, if (!item->d_ptr->itemDiscovered) { topLevelItems << item; item->d_ptr->itemDiscovered = 1; - d->drawSubtreeRecursive(item, painter, viewTransform, expose, widget); + d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget); } } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 983486f..ebc854f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -211,6 +211,7 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; + QList<QGraphicsItem *> topLevelItemsInStackingOrder(const QTransform *const, QRegion *); void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; @@ -264,10 +265,18 @@ public: void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); - - void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform &viewTransform, - QRegion *exposedRegion, QWidget *widget, - QList<QGraphicsItem *> *topLevelItems = 0, qreal parentOpacity = qreal(1.0)); + + inline void drawItems(QPainter *painter, const QTransform *const viewTransform, + QRegion *exposedRegion, QWidget *widget) + { + const QList<QGraphicsItem *> tli = topLevelItemsInStackingOrder(viewTransform, exposedRegion); + for (int i = 0; i < tli.size(); ++i) + drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); + return; + } + + void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const, + QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0)); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 6ac2914..ee45690 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1965,8 +1965,7 @@ void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect itemList.clear(); // Setup painter matrix. - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); + QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); QTransform painterMatrix = d->matrix * moveMatrix; painterMatrix *= QTransform() .translate(targetRect.left(), targetRect.top()) @@ -2317,9 +2316,9 @@ QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const QPainterPath QGraphicsView::mapToScene(const QPainterPath &path) const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(d->horizontalScroll(), d->verticalScroll()); - return (moveMatrix * d->matrix.inverted()).map(path); + QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll()); + matrix *= d->matrix.inverted(); + return matrix.map(path); } /*! @@ -2413,9 +2412,9 @@ QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const QPainterPath QGraphicsView::mapFromScene(const QPainterPath &path) const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); - return (d->matrix * moveMatrix).map(path); + QTransform matrix = d->matrix; + matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); + return matrix.map(path); } /*! @@ -3360,8 +3359,8 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // Items if (!(d->optimizationFlags & IndirectPainting)) { - d->scene->d_func()->drawSubtreeRecursive(0, &painter, viewTransform, &d->exposedRegion, - viewport(), 0); + d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, + &d->exposedRegion, viewport()); } else { // Find all exposed items bool allItems = false; @@ -3614,8 +3613,7 @@ QTransform QGraphicsView::transform() const QTransform QGraphicsView::viewportTransform() const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); + QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix; } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index ca2b782..fa1ce29 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3951,10 +3951,8 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf if (newSize == size()) return copy(); - QImage img; - QTransform wm; - wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); - img = transformed(wm, mode); + QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); + QImage img = transformed(wm, mode); return img; } @@ -3981,9 +3979,8 @@ QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const if (w <= 0) return QImage(); - QTransform wm; qreal factor = (qreal) w / width(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } @@ -4010,9 +4007,8 @@ QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const if (h <= 0) return QImage(); - QTransform wm; qreal factor = (qreal) h / height(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 56c3a29..61be832 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1446,10 +1446,9 @@ QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Tran if (newSize == size()) return *this; - QPixmap pix; - QTransform wm; - wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); - pix = transformed(wm, mode); + QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), + (qreal)newSize.height() / height()); + QPixmap pix = transformed(wm, mode); return pix; } @@ -1476,9 +1475,8 @@ QPixmap QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const if (w <= 0) return QPixmap(); - QTransform wm; qreal factor = (qreal) w / width(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } @@ -1505,9 +1503,8 @@ QPixmap QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const if (h <= 0) return QPixmap(); - QTransform wm; qreal factor = (qreal) h / height(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } diff --git a/src/gui/itemviews/qitemeditorfactory.cpp b/src/gui/itemviews/qitemeditorfactory.cpp index c576e40..480a472 100644 --- a/src/gui/itemviews/qitemeditorfactory.cpp +++ b/src/gui/itemviews/qitemeditorfactory.cpp @@ -158,6 +158,10 @@ QByteArray QItemEditorFactory::valuePropertyName(QVariant::Type type) const */ QItemEditorFactory::~QItemEditorFactory() { + //we make sure we delete all the QItemEditorCreatorBase + //this has to be done only once, hence the QSet + QSet<QItemEditorCreatorBase*> set = creatorMap.values().toSet(); + qDeleteAll(set); } /*! @@ -170,8 +174,16 @@ QItemEditorFactory::~QItemEditorFactory() */ void QItemEditorFactory::registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator) { - delete creatorMap.value(type, 0); - creatorMap[type] = creator; + QHash<QVariant::Type, QItemEditorCreatorBase *>::iterator it = creatorMap.find(type); + if (it != creatorMap.end()) { + QItemEditorCreatorBase *oldCreator = it.value(); + Q_ASSERT(oldCreator); + creatorMap.erase(it); + if (!creatorMap.values().contains(oldCreator)) + delete oldCreator; // if it is no more in use we can delete it + } + + creatorMap[type] = creator; } class QDefaultItemEditorFactory : public QItemEditorFactory diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp index 7c50b80..221267f 100644 --- a/src/gui/painting/qmatrix.cpp +++ b/src/gui/painting/qmatrix.cpp @@ -197,6 +197,10 @@ QT_BEGIN_NAMESPACE /***************************************************************************** QMatrix member functions *****************************************************************************/ +/*! + \fn QMatrix::QMatrix(Qt::Initialization) + \internal +*/ /*! Constructs an identity matrix. diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index e28c950..aa4177c 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -61,6 +61,7 @@ class QVariant; class Q_GUI_EXPORT QMatrix // 2D transform matrix { public: + inline explicit QMatrix(Qt::Initialization) {} QMatrix(); QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy); diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 8e8485d..4fb1832 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -1008,8 +1008,7 @@ void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt & const int size = qRound(ti.fontEngine->ascent()); QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(p.x(), p.y() - size); + QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 1d3e38e..78515ac 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3996,7 +3996,7 @@ void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data) const QClipData *c = clip(); if (c) { const QRect r(QPoint(c->xmin, c->ymin), - QPoint(c->xmax, c->ymax)); + QSize(c->xmax - c->xmin, c->ymax - c->ymin)); clipRect = clipRect.intersected(r); blend = data->blend; } else { diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 5ebca47..a4db284 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -848,8 +848,7 @@ void QPaintEngineEx::drawImage(const QPointF &pos, const QImage &image) void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) { QBrush brush(state()->pen.color(), pixmap); - QTransform xform; - xform.translate(r.x() - s.x(), r.y() - s.y()); + QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); brush.setTransform(xform); qreal pts[] = { r.x(), r.y(), diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 9625b28..053955c 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -45,9 +45,6 @@ #include <private/qdatabuffer_p.h> #include <qmath.h> -#include <QImage> -#include <QPainter> - /** The algorithm is as follows: @@ -68,6 +65,20 @@ QT_BEGIN_NAMESPACE +static inline bool fuzzyIsNull(qreal d) +{ + if (sizeof(qreal) == sizeof(double)) + return qAbs(d) <= 1e-12; + else + return qAbs(d) <= 1e-5f; +} + +static inline bool comparePoints(const QPointF &a, const QPointF &b) +{ + return fuzzyIsNull(a.x() - b.x()) + && fuzzyIsNull(a.y() - b.y()); +} + //#define QDEBUG_CLIPPER static qreal dot(const QPointF &a, const QPointF &b) { @@ -105,8 +116,10 @@ private: bool QIntersectionFinder::beziersIntersect(const QBezier &one, const QBezier &two) const { - return (one.pt1() == two.pt1() && one.pt2() == two.pt2() && one.pt3() == two.pt3() && one.pt4() == two.pt4()) - || (one.pt1() == two.pt4() && one.pt2() == two.pt3() && one.pt3() == two.pt2() && one.pt4() == two.pt1()) + return (comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2()) + && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4())) + || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3()) + && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1())) || QBezier::findIntersections(one, two, 0); } @@ -118,17 +131,17 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const const QPointF q1 = b.p1(); const QPointF q2 = b.p2(); - if (p1 == p2 || q1 == q2) + if (comparePoints(p1, p2) || comparePoints(q1, q2)) return false; - const bool p1_equals_q1 = (p1 == q1); - const bool p2_equals_q2 = (p2 == q2); + const bool p1_equals_q1 = comparePoints(p1, q1); + const bool p2_equals_q2 = comparePoints(p2, q2); if (p1_equals_q1 && p2_equals_q2) return true; - const bool p1_equals_q2 = (p1 == q2); - const bool p2_equals_q1 = (p2 == q1); + const bool p1_equals_q2 = comparePoints(p1, q2); + const bool p2_equals_q1 = comparePoints(p2, q1); if (p1_equals_q2 && p2_equals_q1) return true; @@ -184,8 +197,10 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections) { - if ((one.pt1() == two.pt1() && one.pt2() == two.pt2() && one.pt3() == two.pt3() && one.pt4() == two.pt4()) - || (one.pt1() == two.pt4() && one.pt2() == two.pt3() && one.pt3() == two.pt2() && one.pt4() == two.pt1())) { + if ((comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2()) + && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4())) + || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3()) + && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))) { return; } @@ -230,17 +245,17 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData const QPointF q1 = b.p1(); const QPointF q2 = b.p2(); - if (p1 == p2 || q1 == q2) + if (comparePoints(p1, p2) || comparePoints(q1, q2)) return; - const bool p1_equals_q1 = (p1 == q1); - const bool p2_equals_q2 = (p2 == q2); + const bool p1_equals_q1 = comparePoints(p1, q1); + const bool p2_equals_q2 = comparePoints(p2, q2); if (p1_equals_q1 && p2_equals_q2) return; - const bool p1_equals_q2 = (p1 == q2); - const bool p2_equals_q1 = (p2 == q1); + const bool p1_equals_q2 = comparePoints(p1, q2); + const bool p2_equals_q1 = comparePoints(p2, q1); if (p1_equals_q2 && p2_equals_q1) return; @@ -624,11 +639,11 @@ public: const qreal pivot = pivotComponents[depth & 1]; const qreal value = pointComponents[depth & 1]; - if (qFuzzyCompare(pivot, value)) { + if (fuzzyIsNull(pivot - value)) { const qreal pivot2 = pivotComponents[(depth + 1) & 1]; const qreal value2 = pointComponents[(depth + 1) & 1]; - if (qFuzzyCompare(pivot2, value2)) { + if (fuzzyIsNull(pivot2 - value2)) { if (node.id < 0) node.id = m_tree->nextId(); @@ -802,15 +817,15 @@ QWingedEdge::TraversalStatus QWingedEdge::next(const QWingedEdge::TraversalStatu static bool isLine(const QBezier &bezier) { - const bool equal_1_2 = bezier.pt1() == bezier.pt2(); - const bool equal_2_3 = bezier.pt2() == bezier.pt3(); - const bool equal_3_4 = bezier.pt3() == bezier.pt4(); + const bool equal_1_2 = comparePoints(bezier.pt1(), bezier.pt2()); + const bool equal_2_3 = comparePoints(bezier.pt2(), bezier.pt3()); + const bool equal_3_4 = comparePoints(bezier.pt3(), bezier.pt4()); // point? if (equal_1_2 && equal_2_3 && equal_3_4) return true; - if (bezier.pt1() == bezier.pt4()) + if (comparePoints(bezier.pt1(), bezier.pt4())) return equal_1_2 || equal_3_4; return (equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4); @@ -844,14 +859,14 @@ void QPathSegments::addPath(const QPainterPath &path) else currentPoint = path.elementAt(i); - if (i > 0 && m_points.at(lastMoveTo) == currentPoint) + if (i > 0 && comparePoints(m_points.at(lastMoveTo), currentPoint)) current = lastMoveTo; else m_points << currentPoint; switch (path.elementAt(i).type) { case QPainterPath::MoveToElement: - if (hasMoveTo && last != lastMoveTo && m_points.at(last) != m_points.at(lastMoveTo)) + if (hasMoveTo && last != lastMoveTo && !comparePoints(m_points.at(last), m_points.at(lastMoveTo))) m_segments << Segment(m_pathId, last, lastMoveTo); hasMoveTo = true; last = lastMoveTo = current; @@ -879,7 +894,7 @@ void QPathSegments::addPath(const QPainterPath &path) } } - if (hasMoveTo && last != lastMoveTo && m_points.at(last) != m_points.at(lastMoveTo)) + if (hasMoveTo && last != lastMoveTo && !comparePoints(m_points.at(last), m_points.at(lastMoveTo))) m_segments << Segment(m_pathId, last, lastMoveTo); for (int i = firstSegment; i < m_segments.size(); ++i) { @@ -1357,7 +1372,7 @@ void QWingedEdge::addBezierEdge(const QBezier *bezier, const QPointF &a, const Q if (qFuzzyCompare(alphaA, alphaB)) return; - if (a == b) { + if (comparePoints(a, b)) { int v = insert(a); addBezierEdge(bezier, v, v, alphaA, alphaB, path); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index c3452e1..664751a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1929,8 +1929,7 @@ void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &t QVarLengthArray<glyph_t> glyphs; QVarLengthArray<QFixedPoint> positions; - QTransform m; - m.translate(p.x(), p.y()); + QTransform m = QTransform::fromTranslate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, m, ti.flags, glyphs, positions); if (glyphs.size() == 0) diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp index 179927f..72faf7c 100644 --- a/src/gui/painting/qprintengine_win.cpp +++ b/src/gui/painting/qprintengine_win.cpp @@ -663,8 +663,7 @@ void QWin32PrintEngine::drawPixmap(const QRectF &targetRect, qreal scaleX = 1.0f; qreal scaleY = 1.0f; - QTransform scaleMatrix; - scaleMatrix.scale(r.width() / pixmap.width(), r.height() / pixmap.height()); + QTransform scaleMatrix = QTransform::fromScale(r.width() / pixmap.width(), r.height() / pixmap.height()); QTransform adapted = QPixmap::trueMatrix(d->painterMatrix * scaleMatrix, pixmap.width(), pixmap.height()); @@ -1875,8 +1874,7 @@ static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> _glyphs; - QTransform matrix; - matrix.translate(baseline_pos.x(), baseline_pos.y()); + QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, _glyphs, positions); if (_glyphs.size() == 0) { diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 629b38e..58e4b4e 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -703,7 +703,7 @@ static inline qreal qRoundF(qreal v) void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { - if (a == b || width == 0) + if (a == b || width == 0 || d->clipRect.isEmpty()) return; QPointF pa = a; diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index f94c353..30c22b2 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -179,7 +179,7 @@ private: }; -class QStroker : public QStrokerOps +class Q_GUI_EXPORT QStroker : public QStrokerOps { public: diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 5b1ae07..f0b2351 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -232,6 +232,11 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QTransform::QTransform(Qt::Initialization) + \internal +*/ + +/*! Constructs an identity matrix. All elements are set to zero except \c m11 and \c m22 (specifying diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index bb04f7b..291d35c 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -71,6 +71,7 @@ public: TxProject = 0x10 }; + inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {} QTransform(); QTransform(qreal h11, qreal h12, qreal h13, qreal h21, qreal h22, qreal h23, diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 902ffdd..3855ba7 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1738,8 +1738,7 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o // same rendering code for both orientations. if (vertical) { rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - QTransform m; - m.translate(rect.height()-1, -1.0); + QTransform m = QTransform::fromTranslate(rect.height()-1, -1.0); m.rotate(90.0); painter->setTransform(m, true); } diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 682e00b..c5c6973 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1963,8 +1963,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, newRot = -90; } tr.setRect(0, 0, tr.height(), tr.width()); - QTransform m; - m.translate(newX, newY); + QTransform m = QTransform::fromTranslate(newX, newY); m.rotate(newRot); p->setTransform(m, true); } diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index a4a468d..8499811 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2848,8 +2848,7 @@ void QGtkStyle::drawControl(ControlElement element, if (vertical) { rect.translate(xt, -yt * 2); rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height - QTransform m; - m.translate(rect.height(), 0); + QTransform m = QTransform::fromTranslate(rect.height(), 0); m.rotate(90.0); painter->setTransform(m); } diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 3935dc1..12aa679 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2642,8 +2642,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // same rendering code for both orientations. if (vertical) { rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - QTransform m; - m.translate(rect.height()-1, 0); + QTransform m = QTransform::fromTranslate(rect.height()-1, 0); m.rotate(90.0); painter->setTransform(m, true); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 25bdfd2..05b3695 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -422,8 +422,7 @@ void QFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y); + QTransform matrix = QTransform::fromTranslate(x, y); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags); } @@ -1151,8 +1150,7 @@ void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyp QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); QSize s(_size - 3, _size - 3); @@ -1180,8 +1178,7 @@ void QFontEngineBox::draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 6bbf4e8..fc55a2c 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1826,7 +1826,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { int below_height = above_height + d->scroll->scrollOffset; - for(int i2 = i; i2 < (int)d->actionList.count(); i2++) + for(int i2 = i; i2 < d->actionList.count(); i2++) below_height += d->actionRects.value(d->actionList.at(i2)).height(); size.setHeight(below_height); } @@ -2263,7 +2263,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) break; } } - if (e->button() == Qt::LeftButton || (e->button() == Qt::RightButton && isContextMenu)) + if (e->button() || isContextMenu) #endif d->activateAction(action, QAction::Trigger); } @@ -2746,7 +2746,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) if (d->hasHadMouse && !rect().contains(e->pos())) d->setCurrentAction(0); return; - } else if(e->buttons() & (Qt::LeftButton | Qt::RightButton)) { + } else if(e->buttons()) { d->mouseDown = this; } if (d->sloppyRegion.contains(e->pos())) { diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index d1978e3..4977b31 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1029,15 +1029,14 @@ void QPlainTextEditPrivate::ensureViewportLayouted() \section1 Using QPlainTextEdit as a Display Widget - The text is set or replaced using setPlainText() which deletes any - existing text and replaces it with the text passed in the - setPlainText() call. + The text is set or replaced using setPlainText() which deletes the + existing text and replaces it with the text passed to setPlainText(). - Text itself can be inserted using the QTextCursor class or using - the convenience functins insertPlainText(), appendPlainText() or + Text can be inserted using the QTextCursor class or using the + convenience functions insertPlainText(), appendPlainText() or paste(). - By default the text edit wraps words at whitespace to fit within + By default, the text edit wraps words at whitespace to fit within the text edit widget. The setLineWrapMode() function is used to specify the kind of line wrap you want, \l WidgetWidth or \l NoWrap if you don't want any wrapping. If you use word wrap to @@ -1725,8 +1724,7 @@ static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF p->save(); if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) { if (!gradientRect.isNull()) { - QTransform m; - m.translate(gradientRect.left(), gradientRect.top()); + QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top()); m.scale(gradientRect.width(), gradientRect.height()); brush.setTransform(m); const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index cfce735..f0c694d 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1020,7 +1020,8 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) for (int i = 0; i < channelCount; ++i) { if (channels[i].reply == reply) { channels[i].reply = 0; - closeChannel(i); + if (reply->d_func()->connectionCloseEnabled()) + closeChannel(i); QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index ed2f220..907aaef 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -112,8 +112,6 @@ static void ensureInitialized() are supplied that take a request and optional data, and each return a QNetworkReply object. The returned object is used to obtain any data returned in response to the corresponding request. - the reply to is where most of the signals as well - as the downloaded data are posted. A simple download off the network could be accomplished with: \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 0 @@ -122,7 +120,8 @@ static void ensureInitialized() takes is the QNetworkReply object containing the downloaded data as well as meta-data (headers, etc.). - \note The slot is responsible for deleting the object at that point. + \note After the request has finished, it is the responsibility of the user + to delete the QNetworkReply object at an appropriate time. A more involved example, assuming the manager is already existent, can be: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 75d8a56..6ff0c53 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1063,8 +1063,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(p.x(), p.y()); + QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index b594f5b..e173a8d 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -4206,8 +4206,7 @@ void QOpenGLPaintEnginePrivate::drawImageAsPath(const QRectF &r, const QImage &i qreal scaleX = r.width() / sr.width(); qreal scaleY = r.height() / sr.height(); - QTransform brush_matrix; - brush_matrix.translate(r.left(), r.top()); + QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top()); brush_matrix.scale(scaleX, scaleY); brush_matrix.translate(-sr.left(), -sr.top()); @@ -4228,8 +4227,7 @@ void QOpenGLPaintEnginePrivate::drawTiledImageAsPath(const QRectF &r, const QIma QBrush old_brush = cbrush; QPointF old_brush_origin = brush_origin; - QTransform brush_matrix; - brush_matrix.translate(r.left(), r.top()); + QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top()); brush_matrix.scale(sx, sy); cbrush = QBrush(img); @@ -4871,8 +4869,7 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte // add the glyphs used to the glyph texture cache QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(qRound(p.x()), qRound(p.y())); + QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); // make sure the glyphs we want to draw are in the cache diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 1c86466..9dc7818 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -237,6 +237,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) w = rect.width(); h = rect.height(); d = otherData->d; + is_null = (w <= 0 || h <= 0); DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); #if (Q_DIRECTFB_VERSION >= 0x010000) dfbSurface->ReleaseSource(dfbSurface); @@ -330,6 +331,8 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect); data->w = size.width(); data->h = size.height(); + data->is_null = (data->w <= 0 || data->h <= 0); + #if (Q_DIRECTFB_VERSION >= 0x010000) data->dfbSurface->ReleaseSource(data->dfbSurface); #endif diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index ad6c38e..e81aef4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -60,22 +60,23 @@ public: ~QDirectFBPixmapData(); // Re-implemented from QPixmapData: - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - void fill(const QColor &color); - inline bool hasAlphaChannel() const { return alpha; } - QPixmap transformed(const QTransform &matrix, - Qt::TransformationMode mode) const; - QImage toImage() const; - QPaintEngine* paintEngine() const; + virtual void resize(int width, int height); + virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + virtual void copy(const QPixmapData *data, const QRect &rect); + virtual void fill(const QColor &color); + virtual QPixmap transformed(const QTransform &matrix, + Qt::TransformationMode mode) const; + virtual QImage toImage() const; + virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); + virtual int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} + QImage *buffer(uint lockFlags); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice - int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} inline QImage::Format pixelFormat() const { return format; } static bool hasAlphaChannel(const QImage &img); + inline bool hasAlphaChannel() const { return alpha; } private: void invalidate(); QDirectFBPaintEngine *engine; diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index b6ca82d..1a82377 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1043,26 +1043,22 @@ QVariant QDB2Result::data(int field) case QVariant::Double: { QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull); - bool ok=false; - switch(d->precisionPolicy) { + switch(numericalPrecisionPolicy()) { case QSql::LowPrecisionInt32: - v = new QVariant(value.toInt(&ok)); + v = new QVariant(qGetIntData(d->hStmt, field, isNull)); break; case QSql::LowPrecisionInt64: - v = new QVariant(value.toLongLong(&ok)); + v = new QVariant(qGetBigIntData(d->hStmt, field, isNull)); break; case QSql::LowPrecisionDouble: - v = new QVariant(value.toDouble(&ok)); + v = new QVariant(qGetDoubleData(d->hStmt, field, isNull)); break; case QSql::HighPrecision: default: // length + 1 for the comma - v = new QVariant(value); - ok = true; + v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull)); break; } - if(!ok) - v = new QVariant(); break; } case QVariant::String: @@ -1146,6 +1142,10 @@ void QDB2Result::virtual_hook(int id, void *data) Q_ASSERT(data); *static_cast<bool*>(data) = nextResult(); break; + case QSqlResult::DetachFromResultSet: + if (d->hStmt) + SQLCloseCursor(d->hStmt); + break; default: QSqlResult::virtual_hook(id, data); } @@ -1177,7 +1177,7 @@ QDB2Driver::~QDB2Driver() delete d; } -bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int, +bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts) { if (isOpen()) @@ -1200,6 +1200,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas setOpenError(true); return false; } + + QString protocol; // Set connection attributes const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); for (int i = 0; i < opts.count(); ++i) { @@ -1230,7 +1232,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) { v = val.toUInt(); r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); - } else { + } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) { + protocol = tmp; + } + else { qWarning("QDB2Driver::open: Unknown connection attribute '%s'", tmp.toLocal8Bit().constData()); } @@ -1239,9 +1244,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas "Unable to set connection attribute '%1'").arg(opt), d); } + if (protocol.isEmpty()) + protocol = QLatin1String("PROTOCOL=TCPIP"); + + if (port < 0 ) + port = 50000; + QString connQStr; - connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=") - + password; + connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host + + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user + + QLatin1String(";PWD=") + password; + + SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH]; SQLSMALLINT cb; @@ -1260,7 +1274,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas return false; } - d->user = user.toUpper(); + d->user = user; setOpen(true); setOpenError(false); return true; @@ -1305,10 +1319,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const SQLHANDLE hStmt; QString catalog, schema, table; - qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tableName, &catalog, &schema, &table); if (schema.isEmpty()) schema = d->user; + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -1322,6 +1351,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY, SQL_IS_UINTEGER); + + //Aside: szSchemaName and szTableName parameters of SQLColumns + //are case sensitive search patterns, so no escaping is used. r = SQLColumns(hStmt, NULL, 0, @@ -1402,7 +1434,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const bool isNull; QString fieldVal = qGetStringData(hStmt, 2, -1, isNull); QString userVal = qGetStringData(hStmt, 1, -1, isNull); - if (userVal != d->user) + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + + if (userVal != user) fieldVal = userVal + QLatin1Char('.') + fieldVal; tl.append(fieldVal); r = SQLFetchScroll(hStmt, @@ -1433,7 +1471,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const return index; } QString catalog, schema, table; - qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tablename, &catalog, &schema, &table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -1477,7 +1531,6 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case BatchOperations: case LastInsertId: case SimpleLocking: - case LowPrecisionNumbers: case EventNotifications: return false; case BLOB: @@ -1485,6 +1538,8 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case MultipleResultSets: case PreparedQueries: case PositionalPlaceholders: + case LowPrecisionNumbers: + case FinishQuery: return true; case Unicode: // this is the query that shows the codepage for the types: diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 0698f26..d714327 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1103,6 +1103,19 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) // null value QVariant v; v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0)); + if(v.type() == QVariant::Double) { + switch(numericalPrecisionPolicy()) { + case QSql::LowPrecisionInt32: + v.convert(QVariant::Int); + break; + case QSql::LowPrecisionInt64: + v.convert(QVariant::LongLong); + break; + case QSql::HighPrecision: + v.convert(QVariant::String); + break; + } + } row[idx] = v; continue; } @@ -1168,6 +1181,27 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) row[idx] = QVariant(); break; } + if (d->sqlda->sqlvar[i].sqlscale < 0) { + QVariant v = row[idx]; + switch(numericalPrecisionPolicy()) { + case QSql::LowPrecisionInt32: + if(v.convert(QVariant::Int)) + row[idx]=v; + break; + case QSql::LowPrecisionInt64: + if(v.convert(QVariant::LongLong)) + row[idx]=v; + break; + case QSql::LowPrecisionDouble: + if(v.convert(QVariant::Double)) + row[idx]=v; + break; + case QSql::HighPrecision: + if(v.convert(QVariant::String)) + row[idx]=v; + break; + } + } } return true; @@ -1339,7 +1373,6 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const case LastInsertId: case BatchOperations: case SimpleLocking: - case LowPrecisionNumbers: case FinishQuery: case MultipleResultSets: return false; @@ -1349,6 +1382,7 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const case Unicode: case BLOB: case EventNotifications: + case LowPrecisionNumbers: return true; } return false; @@ -1558,12 +1592,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const QSqlQuery q(createResult()); q.setForwardOnly(true); - + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, " "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' " + "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1591,12 +1629,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const if (!isOpen()) return index; + QString tablename = table; + if (isIdentifierEscaped(tablename, QSqlDriver::TableName)) + tablename = stripDelimiters(tablename, QSqlDriver::TableName); + else + tablename = tablename.toUpper(); + QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND a.RDB$RELATION_NAME = '") + table.toUpper() + + "AND a.RDB$RELATION_NAME = '") + tablename + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 46726a5..bfd65fc 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -254,6 +254,9 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags) case FIELD_TYPE_FLOAT : case FIELD_TYPE_DOUBLE : case FIELD_TYPE_DECIMAL : +#if defined(FIELD_TYPE_NEWDECIMAL) + case FIELD_TYPE_NEWDECIMAL: +#endif type = QVariant::Double; break; case FIELD_TYPE_DATE : diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index ca4b286..d5fb10f 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -1899,7 +1899,7 @@ void QOCIResult::virtual_hook(int id, void *data) QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data)); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 164e82c..3658ff3 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -598,6 +598,7 @@ QChar QODBCDriverPrivate::quoteChar() const return quote; } + bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts) { // Set any connection attributes diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index db09e93..1ab8214 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -891,6 +891,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + switch(d->pro) { case QPSQLDriver::Version6: stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " @@ -923,7 +933,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "FROM pg_attribute, pg_class " "WHERE %1 pg_class.oid IN " "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " - " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) " + " (SELECT oid FROM pg_class WHERE relname = '%2')) " "AND pg_attribute.attrelid = pg_class.oid " "AND pg_attribute.attisdropped = false " "ORDER BY pg_attribute.attnum"); @@ -931,11 +941,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); break; } - i.exec(stmt.arg(tbl.toLower())); + i.exec(stmt.arg(tbl)); while (i.isActive() && i.next()) { QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt())); idx.append(f); @@ -954,6 +964,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + QString stmt; switch(d->pro) { case QPSQLDriver::Version6: @@ -998,7 +1018,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "left join pg_attrdef on (pg_attrdef.adrelid = " "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " "where %1 " - "and lower(pg_class.relname) = '%2' " + "and pg_class.relname = '%2' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "and pg_attribute.attisdropped = false " @@ -1007,12 +1027,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); break; } QSqlQuery query(createResult()); - query.exec(stmt.arg(tbl.toLower())); + query.exec(stmt.arg(tbl)); if (d->pro >= QPSQLDriver::Version71) { while (query.next()) { int len = query.value(3).toInt(); diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 1a05873..8e1091b 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -289,7 +289,7 @@ void QSQLiteResult::virtual_hook(int id, void *data) sqlite3_reset(d->stmt); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } @@ -656,9 +656,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const if (!isOpen()) return QSqlIndex(); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tblname, true); + return qGetTableInfo(q, table, true); } QSqlRecord QSQLiteDriver::record(const QString &tbl) const @@ -666,9 +670,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tbl); + return qGetTableInfo(q, table); } QVariant QSQLiteDriver::handle() const @@ -676,10 +684,10 @@ QVariant QSQLiteDriver::handle() const return qVariantFromValue(d->access); } -QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const +QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) { + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) { res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); res.replace(QLatin1Char('.'), QLatin1String("\".\"")); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index 790c1ef..1989c45 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -260,7 +260,7 @@ void QSQLite2Result::virtual_hook(int id, void *data) d->finalize(); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index 5ddc4e4..e100863 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db) // insert d in error handler dict errs()->insert(d->dbproc, d); + dbcmd(d->dbproc, "set quoted_identifier on"); + dbsqlexec(d->dbproc); } QTDSResult::~QTDSResult() @@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) if (qIsNull(d->buffer.at(i * 2 + 1))) values[idx] = QVariant(QVariant::String); else - values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)); + values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed(); break; case QVariant::ByteArray: { if (qIsNull(d->buffer.at(i * 2 + 1))) @@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const return info; QSqlQuery t(createResult()); t.setForwardOnly(true); + + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QString stmt (QLatin1String("select name, type, length, prec from syscolumns " "where id = (select id from sysobjects where name = '%1')")); - t.exec(stmt.arg(tablename)); + t.exec(stmt.arg(table)); while (t.next()) { QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt())); f.setLength(t.value(2).toInt()); @@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const { QSqlRecord rec = record(tablename); - QSqlIndex idx(tablename); - if ((!isOpen()) || (tablename.isEmpty())) + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlIndex idx(table); + if ((!isOpen()) || (table.isEmpty())) return QSqlIndex(); QSqlQuery t(createResult()); t.setForwardOnly(true); - t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename)); + t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table)); if (t.next()) { QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(',')); QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*")); diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp index 3cace06..ca51dc0 100644 --- a/src/sql/kernel/qsqlcachedresult.cpp +++ b/src/sql/kernel/qsqlcachedresult.cpp @@ -294,4 +294,17 @@ QSqlCachedResult::ValueCache &QSqlCachedResult::cache() return d->cache; } +void QSqlCachedResult::virtual_hook(int id, void *data) +{ + switch (id) { + case QSqlResult::DetachFromResultSet: + case QSqlResult::SetNumericalPrecision: + cleanup(); + break; + default: + QSqlResult::virtual_hook(id, data); + } +} + + QT_END_NAMESPACE diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h index d19435c..a384b2e 100644 --- a/src/sql/kernel/qsqlcachedresult_p.h +++ b/src/sql/kernel/qsqlcachedresult_p.h @@ -89,6 +89,7 @@ protected: int colCount() const; ValueCache &cache(); + void virtual_hook(int id, void *data); private: bool cacheNext(); QSqlCachedResultPrivate *d; diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 1c1595d..93c9d9f 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -905,7 +905,6 @@ QVariant QSqlResult::lastInsertId() const */ void QSqlResult::virtual_hook(int, void *) { - Q_ASSERT(false); } /*! \internal @@ -971,6 +970,7 @@ void QSqlResult::detachFromResultSet() void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) { d->precisionPolicy = policy; + virtual_hook(SetNumericalPrecision, &policy); } /*! \internal diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 1acc846..156af26 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record) int QSqlTableModelPrivate::nameToIndex(const QString &name) const { - return rec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return rec.indexOf(fieldname); } void QSqlTableModelPrivate::initRecordAndPrimaryIndex() @@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName) { Q_D(QSqlTableModel); clear(); - if(d->db.tables().contains(tableName.toUpper())) - d->tableName = tableName.toUpper(); - else - d->tableName = tableName; + d->tableName = tableName; d->initRecordAndPrimaryIndex(); d->initColOffsets(d->rec.count()); @@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const if (!f.isValid()) return s; - QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName); + QString table = d->tableName; + //we can safely escape the field because it would have been obtained from the database + //and have the correct case QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName); s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); @@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) mrow.rec = d->rec; mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row()); } + QString fieldName; for (int i = 0; i < record.count(); ++i) { - int idx = mrow.rec.indexOf(record.fieldName(i)); + fieldName = record.fieldName(i); + if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)) + fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName); + int idx = mrow.rec.indexOf(fieldName); if (idx == -1) isOk = false; else diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 44477e5..e2c1312 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -3378,6 +3378,7 @@ void QSvgHandler::init() { m_doc = 0; m_style = 0; + m_animEnd = 0; m_defaultCoords = LT_PX; m_defaultPen = QPen(Qt::black, 1, Qt::NoPen, Qt::FlatCap, Qt::SvgMiterJoin); m_defaultPen.setMiterLimit(4); diff --git a/tests/auto/qaccessibility_mac/tst_qaccessibility_mac.cpp b/tests/auto/qaccessibility_mac/tst_qaccessibility_mac.cpp index b81fa12..deb6c8d 100644 --- a/tests/auto/qaccessibility_mac/tst_qaccessibility_mac.cpp +++ b/tests/auto/qaccessibility_mac/tst_qaccessibility_mac.cpp @@ -833,9 +833,14 @@ void tst_accessibility_mac::testTabWidget() // Window is not reported properly on 10.5 if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5) { QVERIFY(equal(window(tabGroup), form)); - QVERIFY(equal(window(tabButton1), form)); + + // ### hangs on 10.4 +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + QVERIFY(equal(window(tabButton1), form)); +#endif } -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) +// ### hangs on 10.4 +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) QVERIFY(equal(topLevelUIElement(tabGroup), form)); QVERIFY(equal(topLevelUIElement(tabButton1), form)); #endif @@ -1423,7 +1428,6 @@ void tst_accessibility_mac::testListView() const AXUIElementRef listElement = childByRole(scrollAreaElement, "AXList"); QVERIFY(listElement); QVERIFY(equal(::parent(listElement), scrollAreaElement)); - // Window is not reported properly on 10.5 if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5) QVERIFY(equal(::window(listElement), windowElement)); @@ -1438,9 +1442,11 @@ void tst_accessibility_mac::testListView() QVERIFY(value(A) == "A"); QVERIFY(equal(::parent(A), listElement)); QVERIFY(enabled(A)); - // Window is not reported properly on 10.5 - if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5) - QVERIFY(equal(::window(A), windowElement)); + + // Window is not reported properly on 10.5, this test + // hangs on 10.4. Disable it for now. + // if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5) + // QVERIFY(equal(::window(A), windowElement)); QVERIFY(above(A, B)); QVERIFY(!above(B, A)); diff --git a/tests/auto/qfontdialog/tst_qfontdialog.cpp b/tests/auto/qfontdialog/tst_qfontdialog.cpp index c12c229..1444ee0 100644 --- a/tests/auto/qfontdialog/tst_qfontdialog.cpp +++ b/tests/auto/qfontdialog/tst_qfontdialog.cpp @@ -47,7 +47,9 @@ #include <qfontinfo.h> #include <qtimer.h> #include <qmainwindow.h> +#include <qlistview.h> #include "qfontdialog.h" +#include <private/qfontdialog_p.h> //TESTED_CLASS= //TESTED_FILES= @@ -74,6 +76,7 @@ public slots: private slots: void defaultOkButton(); void setFont(); + void task256466_wrongStyle(); }; tst_QFontDialog::tst_QFontDialog() @@ -151,6 +154,29 @@ void tst_QFontDialog::setFont() } +class FriendlyFontDialog : public QFontDialog +{ + friend tst_QFontDialog; + Q_DECLARE_PRIVATE(QFontDialog); +}; + +void tst_QFontDialog::task256466_wrongStyle() +{ + QFontDatabase fdb; + FriendlyFontDialog dialog; + QListView *familyList = reinterpret_cast<QListView*>(dialog.d_func()->familyList); + QListView *styleList = reinterpret_cast<QListView*>(dialog.d_func()->styleList); + QListView *sizeList = reinterpret_cast<QListView*>(dialog.d_func()->sizeList); + for (int i = 0; i < familyList->model()->rowCount(); ++i) { + QModelIndex currentFamily = familyList->model()->index(i, 0); + familyList->setCurrentIndex(currentFamily); + QCOMPARE(dialog.currentFont(), fdb.font(currentFamily.data().toString(), + styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt())); + } +} + + + QTEST_MAIN(tst_QFontDialog) #include "tst_qfontdialog.moc" diff --git a/tests/auto/qinputdialog/tst_qinputdialog.cpp b/tests/auto/qinputdialog/tst_qinputdialog.cpp index a658aeb..7e4b828 100644 --- a/tests/auto/qinputdialog/tst_qinputdialog.cpp +++ b/tests/auto/qinputdialog/tst_qinputdialog.cpp @@ -56,6 +56,7 @@ class tst_QInputDialog : public QObject { Q_OBJECT QWidget *parent; + QDialog::DialogCode doneCode; void (*testFunc)(QInputDialog *); static void testFuncGetInteger(QInputDialog *dialog); static void testFuncGetDouble(QInputDialog *dialog); @@ -72,6 +73,7 @@ private slots: void getText(); void getItem_data(); void getItem(); + void task256299_getTextReturnNullStringOnRejected(); }; QString stripFraction(const QString &s) @@ -245,8 +247,9 @@ void tst_QInputDialog::timerEvent(QTimerEvent *event) killTimer(event->timerId()); QInputDialog *dialog = qFindChild<QInputDialog *>(parent); Q_ASSERT(dialog); - testFunc(dialog); - dialog->done(QDialog::Accepted); // cause static function call to return + if (testFunc) + testFunc(dialog); + dialog->done(doneCode); // cause static function call to return } void tst_QInputDialog::getInteger_data() @@ -266,6 +269,7 @@ void tst_QInputDialog::getInteger() QFETCH(int, max); Q_ASSERT(min < max); parent = new QWidget; + doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetInteger; startTimer(0); bool ok = false; @@ -305,6 +309,7 @@ void tst_QInputDialog::getDouble() QFETCH(int, decimals); Q_ASSERT(min < max && decimals >= 0 && decimals <= 13); parent = new QWidget; + doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetDouble; startTimer(0); bool ok = false; @@ -322,6 +327,7 @@ void tst_QInputDialog::getDouble() void tst_QInputDialog::task255502getDouble() { parent = new QWidget; + doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetDouble; startTimer(0); bool ok = false; @@ -347,6 +353,7 @@ void tst_QInputDialog::getText() { QFETCH(QString, text); parent = new QWidget; + doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetText; startTimer(0); bool ok = false; @@ -356,6 +363,19 @@ void tst_QInputDialog::getText() delete parent; } +void tst_QInputDialog::task256299_getTextReturnNullStringOnRejected() +{ + parent = new QWidget; + doneCode = QDialog::Rejected; + testFunc = 0; + startTimer(0); + bool ok = true; + const QString result = QInputDialog::getText(parent, "", "", QLineEdit::Normal, "foobar", &ok); + QVERIFY(!ok); + QVERIFY(result.isNull()); + delete parent; +} + void tst_QInputDialog::getItem_data() { QTest::addColumn<QStringList>("items"); @@ -373,6 +393,7 @@ void tst_QInputDialog::getItem() QFETCH(QStringList, items); QFETCH(bool, editable); parent = new QWidget; + doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetItem; startTimer(0); bool ok = false; diff --git a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp index 5540b38..d9a7d56 100644 --- a/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp +++ b/tests/auto/qitemeditorfactory/tst_qitemeditorfactory.cpp @@ -61,16 +61,40 @@ void tst_QItemEditorFactory::createEditor() void tst_QItemEditorFactory::createCustomEditor() { - QItemEditorFactory editorFactory; + //we make it inherit from QObject so that we can use QPointer + class MyEditor : public QObject, public QStandardItemEditorCreator<QDoubleSpinBox> + { + }; - QItemEditorCreatorBase *creator = new QStandardItemEditorCreator<QDoubleSpinBox>(); - editorFactory.registerEditor(QVariant::Rect, creator); + QPointer<MyEditor> creator = new MyEditor; + QPointer<MyEditor> creator2 = new MyEditor; - QWidget parent; + { + QItemEditorFactory editorFactory; + + editorFactory.registerEditor(QVariant::Rect, creator); + editorFactory.registerEditor(QVariant::RectF, creator); + + //creator should not be deleted as a result of calling the next line + editorFactory.registerEditor(QVariant::Rect, creator2); + QVERIFY(creator); + + //this should erase creator2 + editorFactory.registerEditor(QVariant::Rect, creator); + QVERIFY(creator2.isNull()); + + + QWidget parent; + + QWidget *w = editorFactory.createEditor(QVariant::Rect, &parent); + QCOMPARE(w->metaObject()->className(), "QDoubleSpinBox"); + QCOMPARE(w->metaObject()->userProperty().type(), QVariant::Double); + } - QWidget *w = editorFactory.createEditor(QVariant::Rect, &parent); - QCOMPARE(w->metaObject()->className(), "QDoubleSpinBox"); - QCOMPARE(w->metaObject()->userProperty().type(), QVariant::Double); + //editorFactory has been deleted, so should be creator + //because editorFActory has the ownership + QVERIFY(creator.isNull()); + QVERIFY(creator2.isNull()); delete creator; } diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 3f36729..7e42da8 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -228,6 +228,7 @@ private slots: void zeroOpacity(); void clippingBug(); + void emptyClip(); private: void fillData(); @@ -4218,5 +4219,23 @@ void tst_QPainter::clippingBug() QCOMPARE(img, expected); } +void tst_QPainter::emptyClip() +{ + QImage img(64, 64, QImage::Format_ARGB32_Premultiplied); + QPainter p(&img); + p.setRenderHints(QPainter::Antialiasing); + p.setClipRect(0, 32, 64, 0); + p.fillRect(0, 0, 64, 64, Qt::white); + + QPainterPath path; + path.lineTo(64, 0); + path.lineTo(64, 64); + path.lineTo(40, 64); + path.lineTo(40, 80); + path.lineTo(0, 80); + + p.fillPath(path, Qt::green); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qpathclipper/tst_qpathclipper.cpp b/tests/auto/qpathclipper/tst_qpathclipper.cpp index f3077ee..6e6b632 100644 --- a/tests/auto/qpathclipper/tst_qpathclipper.cpp +++ b/tests/auto/qpathclipper/tst_qpathclipper.cpp @@ -93,6 +93,7 @@ private slots: void task204301(); void task209056(); + void task251909(); }; Q_DECLARE_METATYPE(QPainterPath) @@ -1397,6 +1398,25 @@ void tst_QPathClipper::task209056() QVERIFY(p3 != QPainterPath()); } +void tst_QPathClipper::task251909() +{ + QPainterPath p1; + p1.moveTo(0, -10); + p1.lineTo(10, -10); + p1.lineTo(10, 0); + p1.lineTo(0, 0); + + QPainterPath p2; + p2.moveTo(0, 8e-14); + p2.lineTo(10, -8e-14); + p2.lineTo(10, 10); + p2.lineTo(0, 10); + + QPainterPath result = p1.united(p2); + + QVERIFY(result.elementCount() <= 5); +} + QTEST_APPLESS_MAIN(tst_QPathClipper) diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 77d1d5b..a490a2f 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -105,11 +105,7 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0 inline static bool testWhiteSpaceNames( const QString &name ) { -/* return name.startsWith( "QPSQL" ) - || name.startsWith( "QODBC" ) - || name.startsWith( "QSQLITE" ) - || name.startsWith( "QMYSQL" );*/ - return name != QLatin1String("QSQLITE2"); + return name != QLatin1String("QTDS7"); } inline static QString toHex( const QString& binary ) @@ -211,7 +207,7 @@ public: // This requires a local ODBC data source to be configured( pointing to a MySql database ) // addDb( "QODBC", "mysqlodbc", "troll", "trond" ); // addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead.nokia.troll.no" ); +// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); // addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); // addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); @@ -221,7 +217,7 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux // addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux +// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED! // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte @@ -242,17 +238,17 @@ public: // addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1 // use in-memory database to prevent local files -// addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + addDb("QSQLITE", ":memory:"); +// addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); // addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); // addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_", "testuser", "Ee4Gabf6_", "" ); -// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk;TDS_Version=8.0", "troll", "trondk", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.nokia.troll.no;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond;TDS_Version=8.0", "troll", "trond", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.apac.nokia.com;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "testuser", "Ee4Gabf6_", "" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" ); // addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" ); } @@ -320,16 +316,18 @@ public: QSqlQuery q( db ); QStringList dbtables=db.tables(); - foreach(const QString &tableName, tableNames) { + foreach(QString tableName, tableNames) + { wasDropped = true; - foreach(const QString dbtablesName, dbtables) { - if(dbtablesName.toUpper() == tableName.toUpper()) { - dbtables.removeAll(dbtablesName); - wasDropped = q.exec("drop table " + db.driver()->escapeIdentifier( dbtablesName, QSqlDriver::TableName )); - if(!wasDropped) - wasDropped = q.exec("drop table " + dbtablesName); - } - } + QString table=tableName; + if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName)) + table = db.driver()->stripDelimiters(table, QSqlDriver::TableName); + + if ( dbtables.contains( table, Qt::CaseSensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + else if ( dbtables.contains( table, Qt::CaseInsensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + if ( !wasDropped ) qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables; } diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 13ec263..cce4602 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1625,7 +1625,7 @@ void tst_QSqlDatabase::precisionPolicy() q.bindValue(1, 123); QVERIFY_SQL(q, exec()); q.bindValue(0, 2); - q.bindValue(1, QString("1850000000000.0001")); + q.bindValue(1, 1850000000000.0001); QVERIFY_SQL(q, exec()); // These are expected to pass @@ -1633,29 +1633,39 @@ void tst_QSqlDatabase::precisionPolicy() QString query = QString("SELECT num FROM %1 WHERE id = 1").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(q.value(0).type() != QVariant::LongLong) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::LongLong); QCOMPARE(q.value(0).toLongLong(), (qlonglong)123); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Int); QCOMPARE(q.value(0).toInt(), 123); q.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), (double)123); query = QString("SELECT num FROM %1 WHERE id = 2").arg(tableName); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::Double); QCOMPARE(q.value(0).toDouble(), QString("1850000000000.0001").toDouble()); @@ -1663,21 +1673,27 @@ void tst_QSqlDatabase::precisionPolicy() q.setNumericalPrecisionPolicy(QSql::HighPrecision); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::String); q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QEXPECT_FAIL("QOCI", "Oracle fails here, to retrieve next", Continue); QVERIFY_SQL(q, exec(query)); QVERIFY_SQL(q, next()); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); QCOMPARE(q.value(0).type(), QVariant::LongLong); QSql::NumericalPrecisionPolicy oldPrecision= db.numericalPrecisionPolicy(); - db.setNumericalPrecisionPolicy(QSql::LowPrecisionDouble); + db.setNumericalPrecisionPolicy(QSql::LowPrecisionInt64); QSqlQuery q2(db); q2.exec(QString("SELECT num FROM %1 WHERE id = 2").arg(tableName)); QVERIFY_SQL(q2, exec(query)); QVERIFY_SQL(q2, next()); - QCOMPARE(q2.value(0).type(), QVariant::Double); + if(db.driverName().startsWith("QSQLITE")) + QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue); + QCOMPARE(q2.value(0).type(), QVariant::LongLong); db.setNumericalPrecisionPolicy(oldPrecision); } diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro new file mode 100644 index 0000000..0024841 --- /dev/null +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +SOURCES += tst_qsqldriver.cpp + +QT += sql + +wince*: { + plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.path = . + DEPLOYMENT += plugFiles +} else { + win32-g++ { + LIBS += -lws2_32 + } else:win32 { + LIBS += ws2_32.lib + } +} diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp new file mode 100644 index 0000000..bbd7483 --- /dev/null +++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <QtSql/QtSql> + +#include "../qsqldatabase/tst_databases.h" + + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QSqlDriver : public QObject +{ + Q_OBJECT + +public: + void recreateTestTables(QSqlDatabase); + + tst_Databases dbs; + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void record(); + void primaryIndex(); +}; + + +void tst_QSqlDriver::initTestCase_data() +{ + dbs.open(); + if (dbs.fillTestTable() == 0) { + qWarning("NO DATABASES"); + QSKIP("No database drivers are available in this Qt configuration", SkipAll); + } +} + +void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + tst_Databases::safeDropTables( db, tableNames ); + + QVERIFY_SQL( q, exec("create table " + qTableName("relTEST1") + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(4, 'boris', 2, 2)")); +} + +void tst_QSqlDriver::initTestCase() +{ + foreach (const QString &dbname, dbs.dbNames) + recreateTestTables(QSqlDatabase::database(dbname)); +} + +void tst_QSqlDriver::cleanupTestCase() +{ + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + foreach (const QString &dbName, dbs.dbNames) { + QSqlDatabase db = QSqlDatabase::database(dbName); + tst_Databases::safeDropTables( db, tableNames ); + } + dbs.close(); +} + +void tst_QSqlDriver::init() +{ +} + +void tst_QSqlDriver::cleanup() +{ +} + +void tst_QSqlDriver::record() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + QStringList fields; + fields << "id" << "name" << "title_key" << "another_title_key"; + + //check we can get records using an unquoted mixed case table name + QSqlRecord rec = db.driver()->record(tablename); + QCOMPARE(rec.count(), 4); + + if (db.driverName().startsWith("QIBASE")|| db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + for(int i = 0; i < fields.count(); ++i) + fields[i] = fields[i].toUpper(); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + //check we can get records using a properly quoted table name + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + QCOMPARE(rec.count(), 4); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + //check that we can't get records using incorrect tablename casing that's been quoted + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match + else + QCOMPARE(rec.count(), 0); + +} + +void tst_QSqlDriver::primaryIndex() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + //check that we can get primary index using unquoted mixed case table name + QSqlIndex index = db.driver()->primaryIndex(tablename); + QCOMPARE(index.count(), 1); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + //check that we can get the primary index using a quoted tablename + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + QCOMPARE(index.count(), 1); + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + + //check that we can not get the primary index using a quoted but incorrect table name casing + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing + else + QCOMPARE(index.count(), 0); +} + +QTEST_MAIN(tst_QSqlDriver) +#include "tst_qsqldriver.moc" diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index d17706b..825db6c 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -177,9 +177,10 @@ private slots: #ifdef NOT_READY_YET void task_217003_data() { generic_data(); } void task_217003(); - void task_229811(); void task_229811_data() { generic_data(); } + void task_234422_data() { generic_data(); } + void task_234422(); #endif void task_250026_data() { generic_data("QODBC"); } void task_250026(); @@ -2775,6 +2776,44 @@ void tst_QSqlQuery::task_229811() q.exec("DROP TABLE " + tableName ); } + +void tst_QSqlQuery::task_234422() +{ + QFETCH( QString, dbName ); + QSqlDatabase db = QSqlDatabase::database( dbName ); + CHECK_DATABASE( db ); + + QSqlQuery query(db); + QStringList m_airlines; + QStringList m_countries; + + m_airlines << "Lufthansa" << "SAS" << "United" << "KLM" << "Aeroflot"; + m_countries << "DE" << "SE" << "US" << "NL" << "RU"; + + QString tableName = qTableName( "task_234422" ); + + query.exec("DROP TABLE " + tableName); + QVERIFY_SQL(query,exec("CREATE TABLE " + tableName + " (id int primary key, " + "name varchar(20), homecountry varchar(2))")); + for (int i = 0; i < m_airlines.count(); ++i) { + QVERIFY(query.exec(QString("INSERT INTO " + tableName + " values(%1, '%2', '%3')") + .arg(i).arg(m_airlines[i], m_countries[i]))); + } + + QVERIFY_SQL(query, exec("SELECT name FROM " + tableName)); + QVERIFY(query.isSelect()); + QVERIFY(query.first()); + QVERIFY(query.next()); + QCOMPARE(query.at(), 1); + + QSqlQuery query2(query); + + QVERIFY_SQL(query2,exec()); + QVERIFY(query2.first()); + QCOMPARE(query2.at(), 0); + QCOMPARE(query.at(), 1); +} + #endif QTEST_MAIN( tst_QSqlQuery ) diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 5725548..4588af8 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -82,6 +82,10 @@ private slots: void insertRecordDuplicateFieldNames(); void invalidData(); void relationModel(); + void casing(); + void escapedRelations(); + void escapedTableName(); + void whiteSpaceInIdentifiers(); }; @@ -103,7 +107,9 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) << qTableName( "reltest2" ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) - << qTableName( "reltest5" ); + << qTableName( "reltest5" ) + << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); tst_Databases::safeDropTables( db, tableNames ); QVERIFY_SQL( q, exec("create table " + qTableName("reltest1") + @@ -128,6 +134,19 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("create table " + qTableName("reltest5") + " (title varchar(20) not null primary key, abbrev varchar(20))")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('herr', 'Hr')")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('mister', 'Mr')")); + + if (testWhiteSpaceNames(db.driverName())) { + QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) + + " int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)")); + + QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')")); + } } void tst_QSqlRelationalTableModel::initTestCase() @@ -142,10 +161,14 @@ void tst_QSqlRelationalTableModel::cleanupTestCase() tableNames << qTableName( "reltest1" ) << qTableName( "reltest2" ) << qTableName( "reltest3" ) - << qTableName( "reltest4" ); + << qTableName( "reltest4" ) + << qTableName( "reltest5" ); foreach (const QString &dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); - tst_Databases::safeDropTables( db, tableNames ); + QStringList tables = tableNames; + tables << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); + tst_Databases::safeDropTables( db, tables ); } dbs.close(); } @@ -273,7 +296,12 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + //sybase doesn't allow tables with the same alias used twice as col names + //so don't set up an identical relation when using the tds driver + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -284,7 +312,10 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -299,10 +330,15 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); } //check setting of data when the relational key is a non-integer type @@ -336,7 +372,8 @@ void tst_QSqlRelationalTableModel::multipleRelation() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 0)).toInt(), 3); @@ -344,7 +381,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim")); } void tst_QSqlRelationalTableModel::insertRecord() @@ -357,6 +394,7 @@ void tst_QSqlRelationalTableModel::insertRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -398,6 +436,7 @@ void tst_QSqlRelationalTableModel::setRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -450,13 +489,18 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); model.insertRows(0, 1); model.setData(model.index(0, 0), 1011); @@ -467,12 +511,20 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1011); QCOMPARE(model.data(model.index(0,1)).toString(), QString("test")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); QCOMPARE(model.data(model.index(1,0)).toInt(), 1); QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 2); + + QVERIFY_SQL(model, submitAll()); @@ -481,9 +533,16 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); - model.setData(model.index(0,3),1); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + } else { + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); + } model.insertRows(0, 2); model.setData(model.index(0, 0), 1012); @@ -499,17 +558,27 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(),1012); QCOMPARE(model.data(model.index(0,1)).toString(), QString("george")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + QCOMPARE(model.data(model.index(1,0)).toInt(),1013); QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 1); QCOMPARE(model.data(model.index(2,0)).toInt(), 1); QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(2,3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -574,7 +643,8 @@ void tst_QSqlRelationalTableModel::sort() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -589,11 +659,19 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - QCOMPARE(model.rowCount(), 4); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.rowCount(), 4); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + } else { + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(1, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(2, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2); + } + } static void testRevert(QSqlRelationalTableModel &model) @@ -663,7 +741,7 @@ void tst_QSqlRelationalTableModel::revert() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -689,7 +767,9 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -698,7 +778,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(3, 0)).toInt(), 3); QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 ); model.insertRow(model.rowCount()); QVERIFY(model.setData(model.index(4, 0), 5, Qt::EditRole)); @@ -710,11 +793,18 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(0, 0)).toInt(), 5); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(4, 0)).toInt(), 3); QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(4, 3)).toInt(), 2); } // For task 140782 and 176374: If the main table and the the related tables uses the same @@ -729,27 +819,38 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("reltest3")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); + model.setSort(0, Qt::AscendingOrder); // Duplication of "name", used in both reltest3 and reltest4. model.setRelation(2, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); - QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name")).toUpper()).toString(), + QString("Trondheim")); + } else { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), QString("Trondheim")); + } QSqlRecord rec = model.record(); rec.setValue(0, 3); rec.setValue(1, "Berge"); rec.setValue(2, 1); // Must insert the key value - QCOMPARE(rec.fieldName(0), QLatin1String("id")); - QCOMPARE(rec.fieldName(1), QLatin1String("name")); // This comes from main table + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(rec.fieldName(0), QLatin1String("ID")); + QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table + } else { + QCOMPARE(rec.fieldName(0), QLatin1String("id")); + QCOMPARE(rec.fieldName(1), QLatin1String("name")); + } // The duplicate field names is aliased because it's comes from the relation's display column. - if(!db.driverName().startsWith("QIBASE")) - QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); - else + if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) QCOMPARE(rec.fieldName(2), (qTableName("reltest4").append(QLatin1String("_name"))).toUpper()); + else + QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); QVERIFY(model.insertRecord(-1, rec)); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo")); @@ -793,7 +894,7 @@ void tst_QSqlRelationalTableModel::relationModel() QVERIFY(model.relationModel(3) == NULL); QVERIFY(model.relationModel(4) == NULL); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); QVERIFY(model.relationModel(0) == NULL); @@ -806,5 +907,285 @@ void tst_QSqlRelationalTableModel::relationModel() QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr")); } +void tst_QSqlRelationalTableModel::casing() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (db.driverName().startsWith("QSQLITE")) + QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + + QStringList tableNames; + tableNames << qTableName("CASETEST1", db.driver()).toUpper(); + tableNames << qTableName("casetest1", db.driver()); + tst_Databases::safeDropTables(db, tableNames); + + QSqlQuery q(db); + QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)")); + + QVERIFY_SQL( q, exec("create table " + qTableName("casetest1", db.driver()) + + " (ident int not null primary key, name varchar(20), title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)")); + + if (db.driverName().startsWith("QOCI")) { + //try an owner that doesn't exist + QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 0); + + //try an owner that does exist + rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + } + QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + + rec = db.driver()->record(qTableName("casetest1", db.driver())); + QCOMPARE( rec.count(), 3); + + QSqlTableModel upperCaseModel(0, db); + upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + + QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper()); + + QVERIFY_SQL(upperCaseModel, select()); + + QCOMPARE(upperCaseModel.rowCount(), 4); + + QSqlTableModel lowerCaseModel(0, db); + lowerCaseModel.setTable(qTableName("casetest1", db.driver())); + QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver())); + QVERIFY_SQL(lowerCaseModel, select()); + + QCOMPARE(lowerCaseModel.rowCount(), 3); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + tst_Databases::safeDropTables(db, tableNames); +} + +void tst_QSqlRelationalTableModel::escapedRelations() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + recreateTestTables(db); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + + //try with relation table name quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2").toUpper(),QSqlDriver::TableName), + "tid", + "title")); + } else { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2"),QSqlDriver::TableName), + "tid", + "title")); + + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with index column quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + "title")); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + "title")); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with display column quoted + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with tablename and index and display columns quoted in the relation + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); +} + +void tst_QSqlRelationalTableModel::escapedTableName() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // set the values using OnRowChange Strategy with an escaped tablename + { + QSqlRelationalTableModel model(0, db); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1").toUpper(), QSqlDriver::TableName)); + } else { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1"), QSqlDriver::TableName)); + } + model.setSort(0, Qt::AscendingOrder); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); + QVERIFY(model.setData(model.index(0, 2), 2)); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + + model.submit(); + + QVERIFY(model.setData(model.index(3,1), QString("boris2"))); + QVERIFY(model.setData(model.index(3, 2), 1)); + + QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); + + model.submit(); + } + { //verify values + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); + + } +} + +void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers() { + + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (!testWhiteSpaceNames(db.driverName())) + QSKIP("White space test irrelevant for driver", SkipAll); + QSqlRelationalTableModel model(0, db); + model.setTable(db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName)); + model.setSort(0, Qt::DescendingOrder); + model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName), + db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName))); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York")); + + QSqlRecord rec; + QSqlField f1("id", QVariant::Int); + QSqlField f2(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1.setValue(3); + f2.setValue(2); + f3.setValue(7); + + f1.setGenerated(true); + f2.setGenerated(true); + f3.setGenerated(true); + + rec.append(f1); + rec.append(f2); + rec.append(f3); + + QVERIFY_SQL(model, insertRecord(-1, rec)); + model.submitAll(); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 3); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 7); + + //TODO: For some reson setting a record using manual submit fails + //model.setEditStrategy(QSqlTableModel::OnManualSubmit); + + QSqlRecord recNew; + QSqlField f1New("id", QVariant::Int); + QSqlField f2New(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3New(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1New.setValue(4); + f2New.setValue(1); + f3New.setValue(6); + + f1New.setGenerated(true); + f2New.setGenerated(true); + f3New.setGenerated(true); + + recNew.append(f1New); + recNew.append(f2New); + recNew.append(f3New); + + QVERIFY_SQL(model, setRecord(0, recNew)); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); + + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); +} + QTEST_MAIN(tst_QSqlRelationalTableModel) #include "tst_qsqlrelationaltablemodel.moc" diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 5d1f9d4..aa882be 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -145,7 +145,7 @@ void tst_QSqlTableModel::dropTestTables() << qTableName("bigtable") << qTableName("foo"); if (testWhiteSpaceNames(db.driverName())) - tableNames << qTableName("qtestw hitespace"); + tableNames << qTableName("qtestw hitespace", db.driver()); tst_Databases::safeDropTables(db, tableNames); @@ -277,6 +277,7 @@ void tst_QSqlTableModel::setRecord() QList<QSqlTableModel::EditStrategy> policies = QList<QSqlTableModel::EditStrategy>() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit; + QString Xsuffix; foreach( QSqlTableModel::EditStrategy submitpolicy, policies) { QSqlTableModel model(0, db); @@ -295,6 +296,8 @@ void tst_QSqlTableModel::setRecord() if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) QVERIFY(model.submitAll()); + else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1) + model.submit(); else { // dataChanged() is not emitted when submitAll() is called QCOMPARE(spy.count(), 2); @@ -304,10 +307,12 @@ void tst_QSqlTableModel::setRecord() } } - QCOMPARE(model.data(model.index(0, 1)).toString(), QString("fooX")); - QCOMPARE(model.data(model.index(0, 2)).toString(), QString("barX")); - QCOMPARE(model.data(model.index(1, 1)).toString(), QString("bazX")); - QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joeX")); + Xsuffix.append('X'); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("foo").append(Xsuffix)); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("bar").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 1)).toString(), QString("baz").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joe").append(Xsuffix)); } } diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index fbd9923..3bca573 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title, - const QString &url, QWidget *parent) + const QString &url, QWidget *parent) : QDialog(parent) , m_url(url) , m_title(title) @@ -95,21 +95,21 @@ BookmarkDialog::BookmarkDialog(BookmarkManager *manager, const QString &title, connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(addAccepted())); connect(ui.newFolderButton, SIGNAL(clicked()), this, SLOT(addNewFolder())); connect(ui.toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked())); - connect(ui.bookmarkEdit, SIGNAL(textChanged(const QString&)), this, - SLOT(textChanged(const QString&))); + connect(ui.bookmarkEdit, SIGNAL(textChanged(QString)), this, + SLOT(textChanged(QString))); - connect(bookmarkManager->treeBookmarkModel(), SIGNAL(itemChanged(QStandardItem*)), + connect(bookmarkManager->treeBookmarkModel(), + SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); - connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(const QString&)), this, - SLOT(selectBookmarkFolder(const QString&))); + connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(QString)), this, + SLOT(selectBookmarkFolder(QString))); - connect(ui.treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, - SLOT(customContextMenuRequested(const QPoint&))); + connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this, + SLOT(customContextMenuRequested(QPoint))); - connect(ui.treeView->selectionModel(), - SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - this, SLOT(currentChanged(const QModelIndex&, const QModelIndex&))); + connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, + QModelIndex)), this, SLOT(currentChanged(QModelIndex))); } BookmarkDialog::~BookmarkDialog() @@ -118,8 +118,8 @@ BookmarkDialog::~BookmarkDialog() void BookmarkDialog::addAccepted() { - const QItemSelection selection = ui.treeView->selectionModel()->selection(); - const QModelIndexList list = selection.indexes(); + QItemSelectionModel *model = ui.treeView->selectionModel(); + const QModelIndexList &list = model->selection().indexes(); QModelIndex index; if (!list.isEmpty()) @@ -131,8 +131,8 @@ void BookmarkDialog::addAccepted() void BookmarkDialog::addNewFolder() { - const QItemSelection selection = ui.treeView->selectionModel()->selection(); - const QModelIndexList list = selection.indexes(); + QItemSelectionModel *model = ui.treeView->selectionModel(); + const QModelIndexList &list = model->selection().indexes(); QModelIndex index; if (!list.isEmpty()) @@ -143,13 +143,12 @@ void BookmarkDialog::addNewFolder() if (newFolder.isValid()) { ui.treeView->expand(index); const QModelIndex &index = proxyModel->mapFromSource(newFolder); - ui.treeView->selectionModel()->setCurrentIndex(index, - QItemSelectionModel::ClearAndSelect); + model->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); ui.bookmarkFolders->clear(); ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders()); - const QString name = index.data().toString(); + const QString &name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); } ui.treeView->setFocus(); @@ -183,14 +182,14 @@ void BookmarkDialog::itemChanged(QStandardItem *item) ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders()); QString name = tr("Bookmarks"); - const QModelIndex& index = ui.treeView->currentIndex(); + const QModelIndex &index = ui.treeView->currentIndex(); if (index.isValid()) name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); } } -void BookmarkDialog::textChanged(const QString& string) +void BookmarkDialog::textChanged(const QString &string) { ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!string.isEmpty()); } @@ -209,9 +208,12 @@ void BookmarkDialog::selectBookmarkFolder(const QString &folderName) QList<QStandardItem*> list = model->findItems(folderName, Qt::MatchCaseSensitive | Qt::MatchRecursive, 0); if (!list.isEmpty()) { - QModelIndex index = model->indexFromItem(list.at(0)); - ui.treeView->selectionModel()->setCurrentIndex( - proxyModel->mapFromSource(index), QItemSelectionModel::ClearAndSelect); + const QModelIndex &index = model->indexFromItem(list.at(0)); + QItemSelectionModel *model = ui.treeView->selectionModel(); + if (model) { + model->setCurrentIndex(proxyModel->mapFromSource(index), + QItemSelectionModel::ClearAndSelect); + } } } @@ -226,13 +228,13 @@ void BookmarkDialog::customContextMenuRequested(const QPoint &point) QAction *removeItem = menu.addAction(tr("Delete Folder")); QAction *renameItem = menu.addAction(tr("Rename Folder")); - QAction *picked_action = menu.exec(ui.treeView->mapToGlobal(point)); - if (!picked_action) + QAction *picked = menu.exec(ui.treeView->mapToGlobal(point)); + if (!picked) return; - if (picked_action == removeItem) { - bookmarkManager->removeBookmarkItem(ui.treeView, - proxyModel->mapToSource(index)); + const QModelIndex &proxyIndex = proxyModel->mapToSource(index); + if (picked == removeItem) { + bookmarkManager->removeBookmarkItem(ui.treeView, proxyIndex); ui.bookmarkFolders->clear(); ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders()); @@ -242,10 +244,9 @@ void BookmarkDialog::customContextMenuRequested(const QPoint &point) name = index.data().toString(); ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name)); } - else if (picked_action == renameItem) { - QStandardItem *item = bookmarkManager->treeBookmarkModel()-> - itemFromIndex(proxyModel->mapToSource(index)); - if (item) { + else if (picked == renameItem) { + BookmarkModel *model = bookmarkManager->treeBookmarkModel(); + if (QStandardItem *item = model->itemFromIndex(proxyIndex)) { item->setEditable(true); ui.treeView->edit(index); item->setEditable(false); @@ -253,19 +254,12 @@ void BookmarkDialog::customContextMenuRequested(const QPoint &point) } } -void BookmarkDialog::currentChanged(const QModelIndex& current, - const QModelIndex& previous) +void BookmarkDialog::currentChanged(const QModelIndex ¤t) { - Q_UNUSED(previous) - - if (!current.isValid()) { - ui.bookmarkFolders->setCurrentIndex( - ui.bookmarkFolders->findText(tr("Bookmarks"))); - return; - } - - ui.bookmarkFolders->setCurrentIndex( - ui.bookmarkFolders->findText(current.data().toString())); + QString text = tr("Bookmarks"); + if (current.isValid()) + text = current.data().toString(); + ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(text)); } bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) @@ -276,7 +270,7 @@ bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) QModelIndex index = ui.treeView->currentIndex(); switch (ke->key()) { case Qt::Key_F2: { - const QModelIndex& source = proxyModel->mapToSource(index); + const QModelIndex &source = proxyModel->mapToSource(index); QStandardItem *item = bookmarkManager->treeBookmarkModel()->itemFromIndex(source); if (item) { @@ -307,10 +301,11 @@ bool BookmarkDialog::eventFilter(QObject *object, QEvent *e) } +// #pragma mark -- BookmarkWidget BookmarkWidget::BookmarkWidget(BookmarkManager *manager, QWidget *parent, - bool showButtons) + bool showButtons) : QWidget(parent) , addButton(0) , removeButton(0) @@ -326,7 +321,7 @@ BookmarkWidget::~BookmarkWidget() void BookmarkWidget::removeClicked() { - const QModelIndex& index = treeView->currentIndex(); + const QModelIndex &index = treeView->currentIndex(); if (searchField->text().isEmpty()) { bookmarkManager->removeBookmarkItem(treeView, filterBookmarkModel->mapToSource(index)); @@ -360,10 +355,11 @@ void BookmarkWidget::filterChanged() expandItems(); } -void BookmarkWidget::expand(const QModelIndex& index) +void BookmarkWidget::expand(const QModelIndex &index) { - const QModelIndex& source = filterBookmarkModel->mapToSource(index); - QStandardItem *item = bookmarkManager->treeBookmarkModel()->itemFromIndex(source); + const QModelIndex &source = filterBookmarkModel->mapToSource(index); + QStandardItem *item = + bookmarkManager->treeBookmarkModel()->itemFromIndex(source); if (item) item->setData(treeView->isExpanded(index), Qt::UserRole + 11); } @@ -404,22 +400,22 @@ void BookmarkWidget::customContextMenuRequested(const QPoint &point) } } - QAction *picked_action = menu.exec(treeView->mapToGlobal(point)); - if (!picked_action) + QAction *pickedAction = menu.exec(treeView->mapToGlobal(point)); + if (!pickedAction) return; - if (picked_action == showItem) { + if (pickedAction == showItem) { emit requestShowLink(data); } - else if (picked_action == showItemNewTab) { + else if (pickedAction == showItemNewTab) { CentralWidget::instance()->setSourceInNewTab(data); } - else if (picked_action == removeItem) { + else if (pickedAction == removeItem) { bookmarkManager->removeBookmarkItem(treeView, filterBookmarkModel->mapToSource(index)); } - else if (picked_action == renameItem) { - const QModelIndex& source = filterBookmarkModel->mapToSource(index); + else if (pickedAction == renameItem) { + const QModelIndex &source = filterBookmarkModel->mapToSource(index); QStandardItem *item = bookmarkManager->treeBookmarkModel()->itemFromIndex(source); if (item) { @@ -443,7 +439,7 @@ void BookmarkWidget::setup(bool showButtons) searchField = new QLineEdit(this); vlayout->addWidget(searchField); - connect(searchField, SIGNAL(textChanged(const QString &)), this, + connect(searchField, SIGNAL(textChanged(QString)), this, SLOT(filterChanged())); treeView = new TreeView(this); @@ -490,17 +486,14 @@ void BookmarkWidget::setup(bool showButtons) treeView->viewport()->installEventFilter(this); treeView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(treeView, SIGNAL(expanded(const QModelIndex&)), this, - SLOT(expand(const QModelIndex&))); - - connect(treeView, SIGNAL(collapsed(const QModelIndex&)), this, - SLOT(expand(const QModelIndex&))); - - connect(treeView, SIGNAL(activated(const QModelIndex&)), this, - SLOT(activated(const QModelIndex&))); - - connect(treeView, SIGNAL(customContextMenuRequested(const QPoint&)), - this, SLOT(customContextMenuRequested(const QPoint&))); + connect(treeView, SIGNAL(expanded(QModelIndex)), this, + SLOT(expand(QModelIndex))); + connect(treeView, SIGNAL(collapsed(QModelIndex)), this, + SLOT(expand(QModelIndex))); + connect(treeView, SIGNAL(activated(QModelIndex)), this, + SLOT(activated(QModelIndex))); + connect(treeView, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(customContextMenuRequested(QPoint))); filterBookmarkModel->setFilterKeyColumn(0); filterBookmarkModel->setDynamicSortFilter(true); @@ -514,8 +507,8 @@ void BookmarkWidget::expandItems() QStandardItemModel *model = bookmarkManager->treeBookmarkModel(); QList<QStandardItem*>list = model->findItems(QLatin1String("*"), Qt::MatchWildcard | Qt::MatchRecursive, 0); - foreach (const QStandardItem* item, list) { - const QModelIndex& index = model->indexFromItem(item); + foreach (const QStandardItem *item, list) { + const QModelIndex &index = model->indexFromItem(item); treeView->setExpanded(filterBookmarkModel->mapFromSource(index), item->data(Qt::UserRole + 11).toBool()); } @@ -541,17 +534,17 @@ bool BookmarkWidget::eventFilter(QObject *object, QEvent *e) if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast<QKeyEvent*>(e); if (index.isValid() && searchField->text().isEmpty()) { + const QModelIndex &src = filterBookmarkModel->mapToSource(index); if (ke->key() == Qt::Key_F2) { - QStandardItem *item = bookmarkManager->treeBookmarkModel() - ->itemFromIndex(filterBookmarkModel->mapToSource(index)); + QStandardItem *item = + bookmarkManager->treeBookmarkModel()->itemFromIndex(src); if (item) { item->setEditable(true); treeView->edit(index); item->setEditable(false); } } else if (ke->key() == Qt::Key_Delete) { - bookmarkManager->removeBookmarkItem(treeView, - filterBookmarkModel->mapToSource(index)); + bookmarkManager->removeBookmarkItem(treeView, src); } } @@ -559,7 +552,7 @@ bool BookmarkWidget::eventFilter(QObject *object, QEvent *e) default: break; case Qt::Key_Up: { case Qt::Key_Down: - treeView->subclassKeyPressEvent(ke); + treeView->subclassKeyPressEvent(ke); } break; case Qt::Key_Enter: { @@ -593,9 +586,10 @@ bool BookmarkWidget::eventFilter(QObject *object, QEvent *e) } +// #pragma mark -- BookmarkModel -BookmarkModel::BookmarkModel(int rows, int columns, QObject * parent) +BookmarkModel::BookmarkModel(int rows, int columns, QObject *parent) : QStandardItemModel(rows, columns, parent) { } @@ -612,23 +606,23 @@ Qt::DropActions BookmarkModel::supportedDropActions() const Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index); - if (index.data(Qt::UserRole + 10).toString() == QLatin1String("Folder")) + if ((!index.isValid()) // can only happen for the invisible root item + || index.data(Qt::UserRole + 10).toString() == QLatin1String("Folder")) return (Qt::ItemIsDropEnabled | defaultFlags) &~ Qt::ItemIsDragEnabled; return (Qt::ItemIsDragEnabled | defaultFlags) &~ Qt::ItemIsDropEnabled; } +// #pragma mark -- BookmarkManager -BookmarkManager::BookmarkManager(QHelpEngineCore* _helpEngine) +BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) : treeModel(new BookmarkModel(0, 1, this)) , listModel(new BookmarkModel(0, 1, this)) , helpEngine(_helpEngine) { folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon); - treeModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Bookmark")); - listModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Bookmark")); connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(itemChanged(QStandardItem*))); @@ -652,22 +646,10 @@ BookmarkModel* BookmarkManager::listBookmarkModel() void BookmarkManager::saveBookmarks() { - qint32 depth = 0; QByteArray bookmarks; QDataStream stream(&bookmarks, QIODevice::WriteOnly); - QStandardItem *root = treeModel->invisibleRootItem(); - - for (int i = 0; i < root->rowCount(); ++i) { - const QStandardItem *item = root->child(i); - stream << depth; // root - stream << item->data(Qt::DisplayRole).toString(); - stream << item->data(Qt::UserRole + 10).toString(); - stream << item->data(Qt::UserRole + 11).toBool(); - if (item->rowCount() > 0) { - readBookmarksRecursive(item, stream, (depth +1)); - } - } + readBookmarksRecursive(treeModel->invisibleRootItem(), stream, 0); helpEngine->setCustomValue(QLatin1String("Bookmarks"), bookmarks); } @@ -687,7 +669,7 @@ QStringList BookmarkManager::bookmarkFolders() const return folders; } -QModelIndex BookmarkManager::addNewFolder(const QModelIndex& index) +QModelIndex BookmarkManager::addNewFolder(const QModelIndex &index) { QStandardItem *item = new QStandardItem(uniqueFolderName()); item->setEditable(false); @@ -703,16 +685,17 @@ QModelIndex BookmarkManager::addNewFolder(const QModelIndex& index) return treeModel->indexFromItem(item); } -void BookmarkManager::removeBookmarkItem(QTreeView *treeView, const QModelIndex& index) +void BookmarkManager::removeBookmarkItem(QTreeView *treeView, + const QModelIndex &index) { QStandardItem *item = treeModel->itemFromIndex(index); if (item) { QString data = index.data(Qt::UserRole + 10).toString(); if (data == QLatin1String("Folder") && item->rowCount() > 0) { int value = QMessageBox::question(treeView, tr("Remove"), - tr("You are going to delete a Folder, this will also<br>" - "remove it's content. Are you sure to continue?"), - QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); + tr("You are going to delete a Folder, this will also<br>" + "remove it's content. Are you sure to continue?"), + QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if (value == QMessageBox::Cancel) return; @@ -733,28 +716,26 @@ void BookmarkManager::removeBookmarkItem(QTreeView *treeView, const QModelIndex& } } -void BookmarkManager::showBookmarkDialog(QWidget* parent, const QString &name, - const QString &url) +void BookmarkManager::showBookmarkDialog(QWidget *parent, const QString &name, + const QString &url) { BookmarkDialog dialog(this, name, url, parent); dialog.exec(); } -void BookmarkManager::addNewBookmark(const QModelIndex& index, - const QString &name, const QString &url) +void BookmarkManager::addNewBookmark(const QModelIndex &index, + const QString &name, const QString &url) { QStandardItem *item = new QStandardItem(name); item->setEditable(false); item->setData(false, Qt::UserRole + 11); item->setData(url, Qt::UserRole + 10); - if (index.isValid()) { + if (index.isValid()) treeModel->itemFromIndex(index)->appendRow(item); - listModel->appendRow(item->clone()); - } else { + else treeModel->appendRow(item); - listModel->appendRow(item->clone()); - } + listModel->appendRow(item->clone()); } void BookmarkManager::itemChanged(QStandardItem *item) @@ -785,7 +766,8 @@ void BookmarkManager::setupBookmarkModels() QList<int> lastDepths; QList<QStandardItem*> parents; - QByteArray ba = helpEngine->customValue(QLatin1String("Bookmarks")).toByteArray(); + QByteArray ba = + helpEngine->customValue(QLatin1String("Bookmarks")).toByteArray(); QDataStream stream(ba); while (!stream.atEnd()) { stream >> depth >> name >> type >> expanded; @@ -855,8 +837,7 @@ void BookmarkManager::removeBookmarkFolderItems(QStandardItem *item) } void BookmarkManager::readBookmarksRecursive(const QStandardItem *item, - QDataStream &stream, - const qint32 depth) const + QDataStream &stream, const qint32 depth) const { for (int j = 0; j < item->rowCount(); ++j) { const QStandardItem *child = item->child(j); diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h index 29da5f3..bf7af41 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.h +++ b/tools/assistant/tools/assistant/bookmarkmanager.h @@ -74,7 +74,7 @@ class BookmarkDialog : public QDialog Q_OBJECT public: - BookmarkDialog(BookmarkManager *manager, const QString &title, + BookmarkDialog(BookmarkManager *manager, const QString &title, const QString &url, QWidget *parent = 0); ~BookmarkDialog(); @@ -86,8 +86,8 @@ private slots: void textChanged(const QString& string); void selectBookmarkFolder(const QString &folderName); void customContextMenuRequested(const QPoint &point); - void currentChanged(const QModelIndex& current, const QModelIndex& previous); - + void currentChanged(const QModelIndex& current); + private: bool eventFilter(QObject *object, QEvent *e); @@ -177,14 +177,16 @@ public: QStringList bookmarkFolders() const; QModelIndex addNewFolder(const QModelIndex& index); void removeBookmarkItem(QTreeView *treeView, const QModelIndex& index); - void showBookmarkDialog(QWidget* parent, const QString &name, const QString &url); - void addNewBookmark(const QModelIndex& index, const QString &name, const QString &url); + void showBookmarkDialog(QWidget* parent, const QString &name, + const QString &url); + void addNewBookmark(const QModelIndex& index, const QString &name, + const QString &url); void setupBookmarkModels(); private slots: void itemChanged(QStandardItem *item); -private: +private: QString uniqueFolderName() const; void removeBookmarkFolderItems(QStandardItem *item); void readBookmarksRecursive(const QStandardItem *item, QDataStream &stream, @@ -193,7 +195,7 @@ private: private: QString oldText; QIcon folderIcon; - + BookmarkModel *treeModel; BookmarkModel *listModel; QStandardItem *renameItem; diff --git a/tools/assistant/translations/qt_help.pro b/tools/assistant/translations/qt_help.pro index e6208a6..9f4d7d8 100644 --- a/tools/assistant/translations/qt_help.pro +++ b/tools/assistant/translations/qt_help.pro @@ -42,6 +42,7 @@ HEADERS += ../lib/qhelpcollectionhandler_p.h \ TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/qt_help_de.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_ja.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/qt_help_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/qt_help_zh_TW.ts \ diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro index 8572123..4b836e6 100644 --- a/tools/assistant/translations/translations.pro +++ b/tools/assistant/translations/translations.pro @@ -43,6 +43,7 @@ HEADERS += ../tools/assistant/aboutdialog.h \ TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_de.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_ja.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/assistant_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_zh_TW.ts \ diff --git a/tools/assistant/translations/translations_adp.pro b/tools/assistant/translations/translations_adp.pro index e3edca4..c6f3e81 100644 --- a/tools/assistant/translations/translations_adp.pro +++ b/tools/assistant/translations/translations_adp.pro @@ -34,6 +34,7 @@ HEADERS += ../compat/helpwindow.h \ TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/assistant_adp_de.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_ja.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/assistant_adp_zh_TW.ts diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index dcc955b..e8fb282 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3087,7 +3087,6 @@ void Configure::buildHostTools() << "src/tools/moc" << "src/tools/rcc" << "src/tools/uic" - << "tools/linguist/lrelease" << "tools/checksdk"; if (dictionary[ "CETEST" ] == "yes") diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro index 234b0b1..890b252 100644 --- a/tools/linguist/linguist/linguist.pro +++ b/tools/linguist/linguist/linguist.pro @@ -101,6 +101,7 @@ RESOURCES += linguist.qrc TRANSLATIONS=$$[QT_INSTALL_TRANSLATIONS]/linguist_ja.ts \ $$[QT_INSTALL_TRANSLATIONS]/linguist_pl.ts \ + $$[QT_INSTALL_TRANSLATIONS]/linguist_ru.ts \ $$[QT_INSTALL_TRANSLATIONS]/linguist_untranslated.ts \ $$[QT_INSTALL_TRANSLATIONS]/linguist_zh_CN.ts \ $$[QT_INSTALL_TRANSLATIONS]/linguist_zh_TW.ts \ diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph index 0b06cea..629c60b 100644 --- a/tools/linguist/phrasebooks/russian.qph +++ b/tools/linguist/phrasebooks/russian.qph @@ -1,4 +1,5 @@ -<!DOCTYPE QPH><QPH language="ru"> +<!DOCTYPE QPH> +<QPH language="ru"> <phrase> <source>About</source> <target>О программе</target> @@ -68,10 +69,6 @@ <target>авто-прокрутка</target> </phrase> <phrase> - <source>Back</source> - <target>Назад</target> -</phrase> -<phrase> <source>boxed edit</source> <target>окно редактирования</target> </phrase> @@ -117,11 +114,11 @@ </phrase> <phrase> <source>Close button</source> - <target>кнопка закрытия</target> + <target>Кнопка закрытия</target> </phrase> <phrase> <source>collapse</source> - <target>крах</target> + <target>свернуть</target> </phrase> <phrase> <source>column heading</source> @@ -257,7 +254,7 @@ </phrase> <phrase> <source>expand</source> - <target>расширять</target> + <target>развернуть</target> </phrase> <phrase> <source>Explore</source> @@ -285,15 +282,15 @@ </phrase> <phrase> <source>Find Next</source> - <target>Продолжить поиск</target> + <target>Найти далее</target> </phrase> <phrase> <source>Find What</source> - <target>Поиск</target> + <target>Искать</target> </phrase> <phrase> <source>folder</source> - <target>каталог</target> + <target>папка</target> </phrase> <phrase> <source>font</source> @@ -385,7 +382,7 @@ </phrase> <phrase> <source>landscape</source> - <target>альбом</target> + <target>альбомная</target> </phrase> <phrase> <source>link</source> @@ -513,7 +510,7 @@ </phrase> <phrase> <source>OK</source> - <target>OK</target> + <target>Готово</target> </phrase> <phrase> <source>OLE</source> @@ -525,7 +522,7 @@ </phrase> <phrase> <source>OLE embedded object</source> - <target>внедренный OLE-объект</target> + <target>внедрённый OLE-объект</target> </phrase> <phrase> <source>OLE linked object</source> @@ -533,7 +530,7 @@ </phrase> <phrase> <source>OLE nondefault drag and drop</source> - <target>предопределенный OLE-механизм</target> + <target>предопределённый OLE-механизм</target> </phrase> <phrase> <source>Open</source> @@ -557,7 +554,7 @@ </phrase> <phrase> <source>Page Setup</source> - <target>шаг установки</target> + <target>Параметры страницы</target> </phrase> <phrase> <source>palette window</source> @@ -625,11 +622,11 @@ </phrase> <phrase> <source>portrait</source> - <target>портрет</target> + <target>книжная</target> </phrase> <phrase> <source>press</source> - <target>нажимать</target> + <target>нажать</target> </phrase> <phrase> <source>primary container</source> @@ -757,7 +754,7 @@ </phrase> <phrase> <source>secondary window</source> - <target>подчиненное окно</target> + <target>подчинённое окно</target> </phrase> <phrase> <source>select</source> @@ -765,7 +762,7 @@ </phrase> <phrase> <source>Select All</source> - <target>Выделить все</target> + <target>Выделить всё</target> </phrase> <phrase> <source>selection</source> @@ -861,11 +858,11 @@ </phrase> <phrase> <source>status bar</source> - <target>статусная строка</target> + <target>строка состояния</target> </phrase> <phrase> <source>Stop</source> - <target>Стоп</target> + <target>Остановить</target> </phrase> <phrase> <source>tab control</source> @@ -897,7 +894,7 @@ </phrase> <phrase> <source>toggle key</source> - <target>кнопка-выключатель</target> + <target>кнопка-переключатель</target> </phrase> <phrase> <source>toolbar</source> @@ -979,4 +976,88 @@ <source>Yes</source> <target>Да</target> </phrase> +<phrase> + <source>No</source> + <target>Нет</target> +</phrase> +<phrase> + <source>Options</source> + <target>Параметры</target> +</phrase> +<phrase> + <source>directory</source> + <target>каталог</target> +</phrase> +<phrase> + <source>Finish</source> + <target>Завершить</target> +</phrase> +<phrase> + <source>Continue</source> + <target>Продолжить</target> +</phrase> +<phrase> + <source>advanced</source> + <target>расширенный</target> +</phrase> +<phrase> + <source>layout</source> + <target>компоновка</target> +</phrase> +<phrase> + <source>layout</source> + <target>компоновщик</target> +</phrase> +<phrase> + <source>plugin</source> + <target>модуль</target> +</phrase> +<phrase> + <source>script</source> + <target>сценарий</target> +</phrase> +<phrase> + <source>spacer</source> + <target>разделитель</target> +</phrase> +<phrase> + <source>tabbar</source> + <target>панель вкладок</target> +</phrase> +<phrase> + <source>whitespace</source> + <target>символ пробела</target> +</phrase> +<phrase> + <source>Forward</source> + <target>Вперёд</target> +</phrase> +<phrase> + <source>Back</source> + <target>Назад</target> +</phrase> +<phrase> + <source>Search wrapped</source> + <target>Поиск с начала</target> +</phrase> +<phrase> + <source>OK</source> + <target>Выбрать</target> +</phrase> +<phrase> + <source>OK</source> + <target>Закрыть</target> +</phrase> +<phrase> + <source>Match case</source> + <target>С учётом регистра</target> +</phrase> +<phrase> + <source>Case Sensitive</source> + <target>Регистрозависимо</target> +</phrase> +<phrase> + <source>Whole words</source> + <target>Слова полностью</target> +</phrase> </QPH> diff --git a/tools/porting/src/qt3headers0.resource b/tools/porting/src/qt3headers0.resource Binary files differindex 13be468..8e24385 100644 --- a/tools/porting/src/qt3headers0.resource +++ b/tools/porting/src/qt3headers0.resource diff --git a/tools/porting/src/qt3headers1.resource b/tools/porting/src/qt3headers1.resource Binary files differindex e06d270..8da4b9a 100644 --- a/tools/porting/src/qt3headers1.resource +++ b/tools/porting/src/qt3headers1.resource diff --git a/tools/porting/src/qt3headers2.resource b/tools/porting/src/qt3headers2.resource Binary files differindex e44c81d..62bdb8e 100644 --- a/tools/porting/src/qt3headers2.resource +++ b/tools/porting/src/qt3headers2.resource diff --git a/tools/porting/src/qt3headers3.resource b/tools/porting/src/qt3headers3.resource Binary files differindex 6d259f2..6a096e8 100644 --- a/tools/porting/src/qt3headers3.resource +++ b/tools/porting/src/qt3headers3.resource diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index c14b46d..8ef4f0b 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1850,8 +1850,10 @@ HtmlGenerator::generateAnnotatedList(const Node *relative, out() << "</table></p>\n"; } -void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker, - const QMap<QString, const Node *> &classMap) +void +HtmlGenerator::generateCompactList(const Node *relative, + CodeMarker *marker, + const QMap<QString,const Node*> &classMap) { const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' const int NumColumns = 4; // number of columns in the result @@ -1994,28 +1996,29 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker << " </b>"; } out() << "</td>\n"; - - // bad loop - QMap<QString, const Node *>::Iterator it; - it = paragraph[currentParagraphNo[i]].begin(); - for (j = 0; j < currentOffsetInParagraph[i]; j++) - ++it; - - out() << "<td>"; - // Previously, we used generateFullName() for this, but we - // require some special formatting. - out() << "<a href=\"" - << linkForNode(it.value(), relative) - << "\">"; - QStringList pieces = fullName(it.value(), relative, marker).split("::"); - out() << protect(pieces.last()); - out() << "</a>"; - if (pieces.size() > 1) { - out() << " ("; - generateFullName(it.value()->parent(), relative, marker); - out() << ")"; - } - out() << "</td>\n"; + + if (!paragraphName[currentParagraphNo[i]].isEmpty()) { + QMap<QString, const Node *>::Iterator it; + it = paragraph[currentParagraphNo[i]].begin(); + for (j = 0; j < currentOffsetInParagraph[i]; j++) + ++it; + + out() << "<td>"; + // Previously, we used generateFullName() for this, but we + // require some special formatting. + out() << "<a href=\"" + << linkForNode(it.value(), relative) + << "\">"; + QStringList pieces = fullName(it.value(), relative, marker).split("::"); + out() << protect(pieces.last()); + out() << "</a>"; + if (pieces.size() > 1) { + out() << " ("; + generateFullName(it.value()->parent(), relative, marker); + out() << ")"; + } + out() << "</td>\n"; + } currentOffset[i]++; currentOffsetInParagraph[i]++; diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index 3fbeb44..77b03d2 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -29,7 +29,6 @@ qhp.Qt.indexRoot = # See also extraimages.HTML qhp.Qt.extraFiles = classic.css \ images/qt-logo.png \ - images/trolltech-logo \ images/taskmenuextension-example.png \ images/coloreditorfactoryimage.png \ images/dynamiclayouts-example.png \ diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index 1ec9b72..d154254 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -31,7 +31,6 @@ qhp.Qt.indexRoot = # See also extraimages.HTML qhp.Qt.extraFiles = classic.css \ images/qt-logo.png \ - images/trolltech-logo \ images/taskmenuextension-example.png \ images/coloreditorfactoryimage.png \ images/dynamiclayouts-example.png \ diff --git a/translations/assistant_adp_ru.ts b/translations/assistant_adp_ru.ts new file mode 100644 index 0000000..a587a91 --- /dev/null +++ b/translations/assistant_adp_ru.ts @@ -0,0 +1,780 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="ru"> +<context> + <name>AssistantServer</name> + <message> + <source>Failed to bind to port %1</source> + <translation>Не удалось открыть порт %1</translation> + </message> + <message> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> +</context> +<context> + <name>FontPanel</name> + <message> + <source>&Family</source> + <translation>Се&мейство</translation> + </message> + <message> + <source>&Style</source> + <translation>&Стиль</translation> + </message> + <message> + <source>Font</source> + <translation>Шрифт</translation> + </message> + <message> + <source>&Writing system</source> + <translation>Система &письма</translation> + </message> + <message> + <source>&Point size</source> + <translation>&Размер в пикселях</translation> + </message> +</context> +<context> + <name>FontSettingsDialog</name> + <message> + <source>Application</source> + <translation>Приложение</translation> + </message> + <message> + <source>Browser</source> + <translation>Обозреватель</translation> + </message> + <message> + <source>Font settings for:</source> + <translation>Настройки шрифта для:</translation> + </message> + <message> + <source>Use custom settings</source> + <translation>Использование индивидуальных настроек</translation> + </message> + <message> + <source>Font Settings</source> + <translation>Настройки шрифта</translation> + </message> +</context> +<context> + <name>HelpDialog</name> + <message> + <source>&Index</source> + <translation>&Указатель</translation> + </message> + <message> + <source>&Look For:</source> + <translation>&Искать:</translation> + </message> + <message> + <source>&New</source> + <translation>&Создать</translation> + </message> + <message> + <source>&Search</source> + <translation>&Поиск</translation> + </message> + <message> + <source><b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p></source> + <translation><b>Ввод слова.</b><p>В список попадет то, что лучше соответствует введенной строке.</p></translation> + </message> + <message> + <source><b>Enter search word(s).</b><p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.</p></source> + <translation><b>Ввод одного или более слов для поиска.</b><p>Сюда следует ввести одно или несколько слов, которые требуется найти. Слова могут содержкать символы-заменители (*). Если требуется найти словосочетание, то его нужно заключить в кавычки.</p></translation> + </message> + <message> + <source><b>Found documents</b><p>This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.</p></source> + <translation><b>Найденные документы</b><p>В этом списке представлены все найденные при последнем поиске документы. Документы упорядочены по релевантности, т.е. чем выше, тем чаще в нём встречаются указанные слова.</p></translation> + </message> + <message> + <source><b>Help topics organized by category.</b><p>Double-click an item to see the topics in that category. To view a topic, just double-click it.</p></source> + <translation><b>Статьи справки распределённые по разделам.</b><p>Дважды кликните по одному из пунктов, чтобы увидеть какие статьи содержатся в данном разделе. Для открытия статьи просто дважды щелкните на ней.</p></translation> + </message> + <message> + <source><b>Help</b><p>Choose the topic you want help on from the contents list, or search the index for keywords.</p></source> + <translation><b>Справка</b><p>Выберите необходимую статью справки из списка разделов или воспользуйтесь поиском по предметному указателю.</p></translation> + </message> + <message> + <source><b>List of available help topics.</b><p>Double-click on an item to open its help page. If more than one is found, you must specify which page you want.</p></source> + <translation><b>Список доступных статей справки.</b><p>Дважды щёлкните на пункте для открытия страницы помощи. Если найдено более одной, то потребуется выбрать желаемую страницу.</p></translation> + </message> + <message> + <source>Add new bookmark</source> + <translation>Добавить новую закладку</translation> + </message> + <message> + <source>Add the currently displayed page as a new bookmark.</source> + <translation>Добавление текущей открытой страницы в закладки.</translation> + </message> + <message> + <source>Cannot open the index file %1</source> + <translation>Не удаётся открыть файл индекса %1</translation> + </message> + <message> + <source>Con&tents</source> + <translation>Содер&жание</translation> + </message> + <message> + <source>Delete bookmark</source> + <translation>Удалить закладку</translation> + </message> + <message> + <source>Delete the selected bookmark.</source> + <translation>Удаление выбранной закладки.</translation> + </message> + <message> + <source>Display the help page for the full text search.</source> + <translation>Открытие справки по полнотекстовому поиску.</translation> + </message> + <message> + <source>Display the help page.</source> + <translation>Открыть страницу справки.</translation> + </message> + <message> + <source>Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.</source> + <translation>Здесь отображается список тем, распределенных по разделам, указатель или закладки. Последняя вкладка содержит полнотекстовый поиск.</translation> + </message> + <message> + <source>Displays the list of bookmarks.</source> + <translation>Отображает список закладок.</translation> + </message> + <message> + <source>Documentation file %1 does not exist! +Skipping file.</source> + <translation>Файл документации %1 не существует! +Пропущен.</translation> + </message> + <message> + <source>Documentation file %1 is not compatible! +Skipping file.</source> + <translation>Файл документации %1 не совместим! +Пропущен.</translation> + </message> + <message> + <source>Done</source> + <translation>Готово</translation> + </message> + <message> + <source>Enter keyword</source> + <translation>Введите ключевое слово</translation> + </message> + <message> + <source>Enter searchword(s).</source> + <translation>Введите одно или более слов для поиска.</translation> + </message> + <message> + <source>Failed to load keyword index file +Assistant will not work!</source> + <translation>Не удалось загрузить файл индекса ключевых слов +Assistant не будет работать!</translation> + </message> + <message> + <source>Failed to save fulltext search index +Assistant will not work!</source> + <translation>Не удалось сохранить индекс полнотекстового поиска +Assistant не будет работать!</translation> + </message> + <message> + <source>Found &Documents:</source> + <translation>Найденные &документы:</translation> + </message> + <message> + <source>Full Text Search</source> + <translation>Полнотекстовый поиск</translation> + </message> + <message> + <source>He&lp</source> + <translation>&Справка</translation> + </message> + <message> + <source>Help</source> + <translation>Справка</translation> + </message> + <message> + <source>Indexing files...</source> + <translation>Индексирование файлов...</translation> + </message> + <message> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> + <message> + <source>Open Link in New Window</source> + <translation>Открыть ссылку в новом окне</translation> + </message> + <message> + <source>Parse Error</source> + <translation>Ошибка обработки</translation> + </message> + <message> + <source>Prepare...</source> + <translation>Подготовка...</translation> + </message> + <message> + <source>Preparing...</source> + <translation>Подготовка...</translation> + </message> + <message> + <source>Pressing this button starts the search.</source> + <translation>Нажатие на эту кнопку запустит процесс поиска.</translation> + </message> + <message> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <source>Reading dictionary...</source> + <translation>Чтение каталога...</translation> + </message> + <message> + <source>Searching f&or:</source> + <translation>&Искать:</translation> + </message> + <message> + <source>Start searching.</source> + <translation>Начать поиск.</translation> + </message> + <message> + <source>The closing quotation mark is missing.</source> + <translation>Пропущена закрывающая кавычка.</translation> + </message> + <message> + <source>Using a wildcard within phrases is not allowed.</source> + <translation>Использование символов-заменителей внутри фраз не допустимо.</translation> + </message> + <message> + <source>Warning</source> + <translation>Предупреждение</translation> + </message> + <message> + <source>column 1</source> + <translation>столбец 1</translation> + </message> + <message> + <source>Open Link in Current Tab</source> + <translation>Открыть ссылку в текущей вкладке</translation> + </message> + <message numerus="yes"> + <source>%n document(s) found.</source> + <translation> + <numerusform>Найден %n документ.</numerusform> + <numerusform>Найдено %n документа.</numerusform> + <numerusform>Найдено %n документов.</numerusform> + </translation> + </message> + <message> + <source>&Bookmarks</source> + <translation>&Закладки</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Удалить</translation> + </message> +</context> +<context> + <name>HelpWindow</name> + <message> + <source><div align="center"><h1>The page could not be found</h1><br><h3>'%1'</h3></div></source> + <translation><div align="center"><h1>Страница не найдена</h1><br><h3>'%1'</h3></div></translation> + </message> + <message> + <source>Copy &Link Location</source> + <translation>Копировать &адрес ссылки</translation> + </message> + <message> + <source>Error...</source> + <translation>Ошибка...</translation> + </message> + <message> + <source>Failed to open link: '%1'</source> + <translation>Не удалось открыть ссылку: '%1'</translation> + </message> + <message> + <source>Help</source> + <translation>Справка</translation> + </message> + <message> + <source>OK</source> + <translation>Закрыть</translation> + </message> + <message> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> + <message> + <source>Open Link in New Window Shift+LMB</source> + <translation>Открыть ссылку в новом окне Shift+LMB</translation> + </message> + <message> + <source>Unable to launch web browser. +</source> + <translation>Невозможно запустить вэб-браузер. +</translation> + </message> +</context> +<context> + <name>Index</name> + <message> + <source>Untitled</source> + <translation>Неозаглавлено</translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <source>"What's This?" context sensitive help.</source> + <translation>"Что это?" - контекстная справка.</translation> + </message> + <message> + <source>&Add Bookmark</source> + <translation>&Добавление закладки</translation> + </message> + <message> + <source>&Close</source> + <translation>&Закрыть</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Копировать</translation> + </message> + <message> + <source>&Edit</source> + <translation>&Правка</translation> + </message> + <message> + <source>&File</source> + <translation>&Файл</translation> + </message> + <message> + <source>&Find in Text...</source> + <translation>П&оиск по тексту...</translation> + </message> + <message> + <source>&Go</source> + <translation>&Перейти</translation> + </message> + <message> + <source>&Help</source> + <translation>&Справка</translation> + </message> + <message> + <source>&Home</source> + <translation>&Домой</translation> + </message> + <message> + <source>&Next</source> + <translation>&Вперёд</translation> + </message> + <message> + <source>&Previous</source> + <translation>&Назад</translation> + </message> + <message> + <source>&Print...</source> + <translation>&Печать...</translation> + </message> + <message> + <source>&View</source> + <translation>&Вид</translation> + </message> + <message> + <source>&Window</source> + <translation>&Окно</translation> + </message> + <message> + <source>...</source> + <translation>...</translation> + </message> + <message> + <source>About Qt</source> + <translation>О Qt</translation> + </message> + <message> + <source>About Qt Assistant</source> + <translation>О Qt Assistant</translation> + </message> + <message> + <source>Add Tab</source> + <translation>Добавить вкладку</translation> + </message> + <message> + <source>Add the currently displayed page as a new bookmark.</source> + <translation>Добавление текущей открытой страницы в закладки.</translation> + </message> + <message> + <source>Boo&kmarks</source> + <translation>&Закладки</translation> + </message> + <message> + <source>Cannot open file for writing!</source> + <translation>Не удается открыть файл для записи!</translation> + </message> + <message> + <source>Close Tab</source> + <translation>Закрыть вкладку</translation> + </message> + <message> + <source>Close the current window.</source> + <translation>Закрыть текущее окно.</translation> + </message> + <message> + <source>Display further information about Qt Assistant.</source> + <translation>Показать дополнительную информацию о Qt Assistant.</translation> + </message> + <message> + <source>Displays the main page of a specific documentation set.</source> + <translation>Открывает главную страницу выбранного набора документации.</translation> + </message> + <message> + <source>E&xit</source> + <translation>Вы&ход</translation> + </message> + <message> + <source>Failed to open about application contents in file: '%1'</source> + <translation>Не удалось получить информацию о приложении из файла: '%1'</translation> + </message> + <message> + <source>Find &Next</source> + <translation>Продолжить п&оиск</translation> + </message> + <message> + <source>Find &Previous</source> + <translation>Найти &предыдущее</translation> + </message> + <message> + <source>Font Settings...</source> + <translation>Настройки шрифта...</translation> + </message> + <message> + <source>Go</source> + <translation>Перейти</translation> + </message> + <message> + <source>Go to the home page. Qt Assistant's home page is the Qt Reference Documentation.</source> + <translation>Перейти на домашнюю страницу. Домашная страница Qt Assistant - Справочная документация по Qt.</translation> + </message> + <message> + <source>Go to the next page.</source> + <translation>Переход на следующую страницу.</translation> + </message> + <message> + <source>Initializing Qt Assistant...</source> + <translation>Инициализация Qt Assistant...</translation> + </message> + <message> + <source>Minimize</source> + <translation>Свернуть</translation> + </message> + <message> + <source>New Window</source> + <translation>Новое окно</translation> + </message> + <message> + <source>Next Tab</source> + <translation>Следующая вкладка</translation> + </message> + <message> + <source>Open a new window.</source> + <translation>Открыть новое окно.</translation> + </message> + <message> + <source>Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter.</source> + <translation>Открыть окно поиска. Qt Assistant произведёт поиск введённого текста на текущей открытой странице.</translation> + </message> + <message> + <source>Previous Tab</source> + <translation>Предыдущая вкладка</translation> + </message> + <message> + <source>Print the currently displayed page.</source> + <translation>Печать текущей открытой страницы.</translation> + </message> + <message> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <source>Qt Assistant Manual</source> + <translation>Руководство по Qt Assistant</translation> + </message> + <message> + <source>Qt Assistant by Nokia</source> + <translation>Qt Assistant от Nokia</translation> + </message> + <message> + <source>Quit Qt Assistant.</source> + <translation>Выйти из Qt Assistant.</translation> + </message> + <message> + <source>Save Page</source> + <translation>Сохранить страницу</translation> + </message> + <message> + <source>Save Page As...</source> + <translation>Сохранить страницу как...</translation> + </message> + <message> + <source>Select the page in contents tab.</source> + <translation>Выбор страницы в оглавлении.</translation> + </message> + <message> + <source>Sidebar</source> + <translation>Боковая панель</translation> + </message> + <message> + <source>Sync with Table of Contents</source> + <translation>Синхронизировать с оглавлением</translation> + </message> + <message> + <source>Toolbar</source> + <translation>Панель инструментов</translation> + </message> + <message> + <source>Views</source> + <translation>Виды</translation> + </message> + <message> + <source>What's This?</source> + <translation>Что это?</translation> + </message> + <message> + <source>Zoom &in</source> + <translation>У&величить</translation> + </message> + <message> + <source>Zoom &out</source> + <translation>У&меньшить</translation> + </message> + <message> + <source>Zoom in on the document, i.e. increase the font size.</source> + <translation>Увеличение масштаба документа, т.е. увеличение размера шрифта.</translation> + </message> + <message> + <source>Zoom out on the document, i.e. decrease the font size.</source> + <translation>Уменьшение масштаба документа, т.е. уменьшение размера шрифта.</translation> + </message> + <message> + <source>Ctrl+M</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>SHIFT+CTRL+=</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+T</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+I</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+B</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+S</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+]</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+[</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+P</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Q</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Copy the selected text to the clipboard.</source> + <translation>Скопировать выделенный текст в буфер обмена.</translation> + </message> + <message> + <source>Ctrl+C</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+F</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>F3</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Shift+F3</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Home</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Go to the previous page.</source> + <translation>Переход на предыдущую страницу.</translation> + </message> + <message> + <source>Alt+Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Alt+Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl++</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+-</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+N</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+W</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Shift+F1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Alt+N</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Alt+Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Alt+Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Alt+Q</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>F1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ctrl+Alt+S</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <source>Qt Assistant by Nokia</source> + <translation>Qt Assistant от Nokia</translation> + </message> +</context> +<context> + <name>TabbedBrowser</name> + <message> + <source>...</source> + <translation>...</translation> + </message> + <message> + <source><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped</source> + <translation><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Поиск с начала</translation> + </message> + <message> + <source>Add page</source> + <translation>Добавить страницу</translation> + </message> + <message> + <source>Case Sensitive</source> + <translation>Регистрозависимо</translation> + </message> + <message> + <source>Close Other Tabs</source> + <translation>Закрыть остальные вкладки</translation> + </message> + <message> + <source>Close Tab</source> + <translation>Закрыть вкладку</translation> + </message> + <message> + <source>Close page</source> + <translation>Закрыть страницу</translation> + </message> + <message> + <source>New Tab</source> + <translation>Новая вкладка</translation> + </message> + <message> + <source>Next</source> + <translation>Следующий</translation> + </message> + <message> + <source>Previous</source> + <translation>Предыдущий</translation> + </message> + <message> + <source>Untitled</source> + <translation>Безымянный</translation> + </message> + <message> + <source>Whole words</source> + <translation>Слова полностью</translation> + </message> + <message> + <source>TabbedBrowser</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>TopicChooser</name> + <message> + <source>&Close</source> + <translation>&Закрыть</translation> + </message> + <message> + <source>&Display</source> + <translation>&Показать</translation> + </message> + <message> + <source>&Topics</source> + <translation>&Статьи</translation> + </message> + <message> + <source>Choose Topic</source> + <translation>Выбор статьи</translation> + </message> + <message> + <source>Choose a topic for <b>%1</b></source> + <translation>Выберите статью для <b>%1</b></translation> + </message> + <message> + <source>Close the Dialog.</source> + <translation>Закрытие окна.</translation> + </message> + <message> + <source>Displays a list of available help topics for the keyword.</source> + <translation>Показывает список доступных статей справки, соответствующих ключевому слову.</translation> + </message> + <message> + <source>Open the topic selected in the list.</source> + <translation>Открытие выбранной в списке темы.</translation> + </message> + <message> + <source>Select a topic from the list and click the <b>Display</b>-button to open the online help.</source> + <translation>Выберите статью из списка и нажмите на кнопку <b>Показать</b> для открытия онлайн справки.</translation> + </message> +</context> +</TS> diff --git a/translations/assistant_ru.ts b/translations/assistant_ru.ts new file mode 100644 index 0000000..32aa739 --- /dev/null +++ b/translations/assistant_ru.ts @@ -0,0 +1,1063 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="ru"> +<context> + <name>AboutDialog</name> + <message> + <location filename="../tools/assistant/tools/assistant/aboutdialog.cpp" line="+110"/> + <source>&Close</source> + <translation>&Закрыть</translation> + </message> +</context> +<context> + <name>AboutLabel</name> + <message> + <location line="-14"/> + <source>Warning</source> + <translation>Предупреждение</translation> + </message> + <message> + <location line="+1"/> + <source>Unable to launch external application. +</source> + <translation>Невозможно запустить внешнее приложение. +</translation> + </message> + <message> + <location line="+1"/> + <source>OK</source> + <translation>Закрыть</translation> + </message> +</context> +<context> + <name>BookmarkDialog</name> + <message> + <location filename="../tools/assistant/tools/assistant/bookmarkdialog.ui" line="+19"/> + <source>Add Bookmark</source> + <translation>Добавление закладки</translation> + </message> + <message> + <location line="+10"/> + <source>Bookmark:</source> + <translation>Закладка:</translation> + </message> + <message> + <location line="+7"/> + <source>Add in Folder:</source> + <translation>Добавить в папку:</translation> + </message> + <message> + <location line="+29"/> + <source>+</source> + <translation>+</translation> + </message> + <message> + <location line="+28"/> + <source>New Folder</source> + <translation>Новая папка</translation> + </message> + <message> + <location filename="../tools/assistant/tools/assistant/bookmarkmanager.cpp" line="+185"/> + <location line="+18"/> + <location line="+36"/> + <location line="+24"/> + <location line="+32"/> + <source>Bookmarks</source> + <translation>Закладки</translation> + </message> + <message> + <location line="-69"/> + <source>Delete Folder</source> + <translation>Удалить папку</translation> + </message> + <message> + <location line="+1"/> + <source>Rename Folder</source> + <translation>Переименовать папку</translation> + </message> +</context> +<context> + <name>BookmarkManager</name> + <message> + <location line="+449"/> + <source>Bookmarks</source> + <translation>Закладки</translation> + </message> + <message> + <location line="+36"/> + <source>Remove</source> + <translation>Удалить</translation> + </message> + <message> + <location line="+1"/> + <source>You are going to delete a Folder, this will also<br>remove it's content. Are you sure to continue?</source> + <translation>Удаление папки приведёт к удалению её содержимого.<br>Желаете продолжить?</translation> + </message> + <message> + <location line="+109"/> + <location line="+9"/> + <source>New Folder</source> + <translation>Новая папка</translation> + </message> +</context> +<context> + <name>BookmarkWidget</name> + <message> + <location line="-436"/> + <source>Delete Folder</source> + <translation>Удалить папку</translation> + </message> + <message> + <location line="+1"/> + <source>Rename Folder</source> + <translation>Переименовать папку</translation> + </message> + <message> + <location line="+2"/> + <source>Show Bookmark</source> + <translation>Открыть закладку</translation> + </message> + <message> + <location line="+1"/> + <source>Show Bookmark in New Tab</source> + <translation>Открыть закладку в новой вкладке</translation> + </message> + <message> + <location line="+3"/> + <source>Delete Bookmark</source> + <translation>Удалить закладку</translation> + </message> + <message> + <location line="+1"/> + <source>Rename Bookmark</source> + <translation>Переименовать закладку</translation> + </message> + <message> + <location line="+38"/> + <source>Filter:</source> + <translation>Фильтр:</translation> + </message> + <message> + <location line="+23"/> + <source>Add</source> + <translation>Добавить</translation> + </message> + <message> + <location line="+9"/> + <source>Remove</source> + <translation>Удалить</translation> + </message> +</context> +<context> + <name>CentralWidget</name> + <message> + <location filename="../tools/assistant/tools/assistant/centralwidget.cpp" line="+237"/> + <source>Add new page</source> + <translation>Открыть новую страницу</translation> + </message> + <message> + <location line="+9"/> + <source>Close current page</source> + <translation>Закрыть текущую страницу</translation> + </message> + <message> + <location line="+284"/> + <source>Print Document</source> + <translation>Печать документа</translation> + </message> + <message> + <location line="+148"/> + <location line="+2"/> + <source>unknown</source> + <translation>безымянная вкладка</translation> + </message> + <message> + <location line="+91"/> + <source>Add New Page</source> + <translation>Открыть новую страницу</translation> + </message> + <message> + <location line="+3"/> + <source>Close This Page</source> + <translation>Закрыть данную страницу</translation> + </message> + <message> + <location line="+3"/> + <source>Close Other Pages</source> + <translation>Закрыть остальные страницы</translation> + </message> + <message> + <location line="+5"/> + <source>Add Bookmark for this Page...</source> + <translation>Добавить закладку для этой страницы...</translation> + </message> + <message> + <location line="+255"/> + <source>Search</source> + <translation>Поиск</translation> + </message> +</context> +<context> + <name>ContentWindow</name> + <message> + <location filename="../tools/assistant/tools/assistant/contentwindow.cpp" line="+158"/> + <source>Open Link</source> + <translation>Открыть ссылку</translation> + </message> + <message> + <location line="+1"/> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> +</context> +<context> + <name>FilterNameDialogClass</name> + <message> + <location filename="../tools/assistant/tools/assistant/filternamedialog.ui" line="+13"/> + <source>Add Filter Name</source> + <translation>Добавление фильтра</translation> + </message> + <message> + <location line="+12"/> + <source>Filter Name:</source> + <translation>Название фильтра:</translation> + </message> +</context> +<context> + <name>FindWidget</name> + <message> + <location filename="../tools/assistant/tools/assistant/centralwidget.cpp" line="-925"/> + <source>Previous</source> + <translation>Предыдущее совпадение</translation> + </message> + <message> + <location line="+4"/> + <source>Next</source> + <translation>Следующее совпадение</translation> + </message> + <message> + <location line="+4"/> + <source>Case Sensitive</source> + <translation>Регистрозависимо</translation> + </message> + <message> + <location line="+3"/> + <source>Whole words</source> + <translation>Слова полностью</translation> + </message> + <message> + <location line="+12"/> + <source><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Search wrapped</source> + <translation><img src=":/trolltech/assistant/images/wrap.png">&nbsp;Поиск с начала</translation> + </message> +</context> +<context> + <name>FontPanel</name> + <message> + <location filename="../tools/shared/fontpanel/fontpanel.cpp" line="+63"/> + <source>Font</source> + <translation>Шрифт</translation> + </message> + <message> + <location line="+11"/> + <source>&Writing system</source> + <translation>Система &письма</translation> + </message> + <message> + <location line="+3"/> + <source>&Family</source> + <translation>Се&мейство</translation> + </message> + <message> + <location line="+4"/> + <source>&Style</source> + <translation>&Стиль</translation> + </message> + <message> + <location line="+4"/> + <source>&Point size</source> + <translation>&Размер в точках</translation> + </message> +</context> +<context> + <name>HelpViewer</name> + <message> + <location filename="../tools/assistant/tools/assistant/helpviewer.cpp" line="+284"/> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> + <message> + <location line="+147"/> + <source><title>Error 404...</title><div align="center"><br><br><h1>The page could not be found</h1><br><h3>'%1'</h3></div></source> + <translation><title>Ошибка 404...</title><div align="center"><br><br><h1>Страница не найдена</h1><br><h3>'%1'</h3></div></translation> + </message> + <message> + <location line="+61"/> + <source>Help</source> + <translation>Справка</translation> + </message> + <message> + <location line="+1"/> + <source>Unable to launch external application. +</source> + <translation>Невозможно запустить внешнее приложение. +</translation> + </message> + <message> + <location line="+0"/> + <source>OK</source> + <translation>Закрыть</translation> + </message> + <message> + <location line="+63"/> + <source>Copy &Link Location</source> + <translation>Копировать &адрес ссылки</translation> + </message> + <message> + <location line="+3"/> + <source>Open Link in New Tab Ctrl+LMB</source> + <translation>Открыть ссылку в новой вкладке Ctrl+LMB</translation> + </message> +</context> +<context> + <name>IndexWindow</name> + <message> + <location filename="../tools/assistant/tools/assistant/indexwindow.cpp" line="+66"/> + <source>&Look for:</source> + <translation>&Искать:</translation> + </message> + <message> + <location line="+68"/> + <source>Open Link</source> + <translation>Открыть ссылку</translation> + </message> + <message> + <location line="+1"/> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> +</context> +<context> + <name>InstallDialog</name> + <message> + <location filename="../tools/assistant/tools/assistant/installdialog.cpp" line="+75"/> + <location filename="../tools/assistant/tools/assistant/installdialog.ui" line="+13"/> + <source>Install Documentation</source> + <translation>Установка документации</translation> + </message> + <message> + <location line="+30"/> + <source>Downloading documentation info...</source> + <translation>Загрузка информации о документации...</translation> + </message> + <message> + <location line="+48"/> + <source>Download canceled.</source> + <translation>Загрузка отменена.</translation> + </message> + <message> + <location line="+26"/> + <location line="+78"/> + <location line="+27"/> + <source>Done.</source> + <translation>Готово.</translation> + </message> + <message> + <location line="-90"/> + <source>The file %1 already exists. Do you want to overwrite it?</source> + <translation>Файл %1 уже существует. Желаете перезаписать его?</translation> + </message> + <message> + <location line="+11"/> + <source>Unable to save the file %1: %2.</source> + <translation>Невозможно сохранить файл %1: %2.</translation> + </message> + <message> + <location line="+8"/> + <source>Downloading %1...</source> + <translation>Загрузка %1...</translation> + </message> + <message> + <location line="+19"/> + <location line="+42"/> + <location line="+38"/> + <source>Download failed: %1.</source> + <translation>Загрузка не удалась: %1.</translation> + </message> + <message> + <location line="-70"/> + <source>Documentation info file is corrupt!</source> + <translation>Файл информации о документации повреждён!</translation> + </message> + <message> + <location line="+37"/> + <source>Download failed: Downloaded file is corrupted.</source> + <translation>Загрузка не удалась: загруженный файл повреждён.</translation> + </message> + <message> + <location line="+2"/> + <source>Installing documentation %1...</source> + <translation>Установка документации %1...</translation> + </message> + <message> + <location line="+22"/> + <source>Error while installing documentation: +%1</source> + <translation>При установке документации возникла ошибка: +%1</translation> + </message> + <message> + <location filename="../tools/assistant/tools/assistant/installdialog.ui" line="+6"/> + <source>Available Documentation:</source> + <translation>Доступная документация:</translation> + </message> + <message> + <location line="+10"/> + <source>Install</source> + <translation>Установить</translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation>Отмена</translation> + </message> + <message> + <location line="+7"/> + <source>Close</source> + <translation>Закрыть</translation> + </message> + <message> + <location line="+20"/> + <source>Installation Path:</source> + <translation>Путь установки:</translation> + </message> + <message> + <location line="+10"/> + <source>...</source> + <translation>...</translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../tools/assistant/tools/assistant/mainwindow.cpp" line="+108"/> + <location line="+354"/> + <source>Index</source> + <translation>Индекс</translation> + </message> + <message> + <location line="-348"/> + <location line="+346"/> + <source>Contents</source> + <translation>Содержание</translation> + </message> + <message> + <location line="-341"/> + <location line="+345"/> + <source>Bookmarks</source> + <translation>Закладки</translation> + </message> + <message> + <location line="-333"/> + <location line="+208"/> + <location line="+476"/> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <location line="-508"/> + <location line="+5"/> + <source>Unfiltered</source> + <translation>Без фильтрации</translation> + </message> + <message> + <location line="+21"/> + <source>Looking for Qt Documentation...</source> + <translation type="unfinished">Поиск по документации Qt...</translation> + </message> + <message> + <location line="+61"/> + <source>&File</source> + <translation>&Файл</translation> + </message> + <message> + <location line="+2"/> + <source>Page Set&up...</source> + <translation>Параметры &страницы...</translation> + </message> + <message> + <location line="+2"/> + <source>Print Preview...</source> + <translation>Предпросмотр печати...</translation> + </message> + <message> + <location line="+3"/> + <source>&Print...</source> + <translation>&Печать...</translation> + </message> + <message> + <location line="+6"/> + <source>New &Tab</source> + <translation>Новая &вкладка</translation> + </message> + <message> + <location line="+3"/> + <source>&Close Tab</source> + <translation>&Закрыть вкладку</translation> + </message> + <message> + <location line="+4"/> + <source>&Quit</source> + <translation>В&ыход</translation> + </message> + <message> + <location line="+1"/> + <source>CTRL+Q</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>&Edit</source> + <translation>&Правка</translation> + </message> + <message> + <location line="+1"/> + <source>&Copy selected Text</source> + <translation>&Копировать выделенный текст</translation> + </message> + <message> + <location line="+6"/> + <source>&Find in Text...</source> + <translation>П&оиск в тексте...</translation> + </message> + <message> + <location line="+5"/> + <source>Find &Next</source> + <translation>Найти &следующее</translation> + </message> + <message> + <location line="+4"/> + <source>Find &Previous</source> + <translation>Найти &предыдущее</translation> + </message> + <message> + <location line="+5"/> + <source>Preferences...</source> + <translation>Настройки...</translation> + </message> + <message> + <location line="+3"/> + <source>&View</source> + <translation>&Вид</translation> + </message> + <message> + <location line="+1"/> + <source>Zoom &in</source> + <translation>У&величить</translation> + </message> + <message> + <location line="+5"/> + <source>Zoom &out</source> + <translation>У&меньшить</translation> + </message> + <message> + <location line="+5"/> + <source>Normal &Size</source> + <translation>Нормальный р&азмер</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+0</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>ALT+C</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>ALT+I</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>ALT+O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> + <source>Search</source> + <translation>Поиск</translation> + </message> + <message> + <location line="+1"/> + <source>ALT+S</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>&Go</source> + <translation>&Перейти</translation> + </message> + <message> + <location line="+1"/> + <source>&Home</source> + <translation>&Домой</translation> + </message> + <message> + <location line="+1"/> + <source>ALT+Home</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>&Back</source> + <translation>&Назад</translation> + </message> + <message> + <location line="+5"/> + <source>&Forward</source> + <translation>&Вперёд</translation> + </message> + <message> + <location line="+5"/> + <source>Sync with Table of Contents</source> + <translation>Синхронизировать с содержанием</translation> + </message> + <message> + <location line="+6"/> + <source>Next Page</source> + <translation>Следующая страница</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+Alt+Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Previous Page</source> + <translation>Предыдущая страница</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+Alt+Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>&Bookmarks</source> + <translation>&Закладки</translation> + </message> + <message> + <location line="+1"/> + <source>Add Bookmark...</source> + <translation>Добавить закладку...</translation> + </message> + <message> + <location line="+1"/> + <source>CTRL+D</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+2"/> + <source>&Help</source> + <translation>&Справка</translation> + </message> + <message> + <location line="+1"/> + <source>About...</source> + <translation>О программе...</translation> + </message> + <message> + <location line="+3"/> + <source>Navigation Toolbar</source> + <translation>Панель навигации</translation> + </message> + <message> + <location line="+22"/> + <source>&Window</source> + <translation>&Окно</translation> + </message> + <message> + <location line="+2"/> + <source>Zoom</source> + <translation>Масштаб</translation> + </message> + <message> + <location line="+1"/> + <source>Minimize</source> + <translation>Свернуть</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+M</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+50"/> + <source>Toolbars</source> + <translation>Панели инструментов</translation> + </message> + <message> + <location line="+15"/> + <source>Filter Toolbar</source> + <translation>Панель фильтров</translation> + </message> + <message> + <location line="+2"/> + <source>Filtered by:</source> + <translation>Отфильтровано по:</translation> + </message> + <message> + <location line="+23"/> + <source>Address Toolbar</source> + <translation>Панель адреса</translation> + </message> + <message> + <location line="+4"/> + <source>Address:</source> + <translation>Адрес:</translation> + </message> + <message> + <location line="+114"/> + <source>Could not find the associated content item.</source> + <translation type="unfinished">Не удалось найти элемент, связанный с содержанием.</translation> + </message> + <message> + <location line="+81"/> + <source>About %1</source> + <translation type="unfinished">О %1</translation> + </message> + <message> + <location line="+114"/> + <source>Updating search index</source> + <translation>Обновление поискового индекса</translation> + </message> +</context> +<context> + <name>PreferencesDialog</name> + <message> + <location filename="../tools/assistant/tools/assistant/preferencesdialog.cpp" line="+256"/> + <location line="+43"/> + <source>Add Documentation</source> + <translation>Добавить документацию</translation> + </message> + <message> + <location line="-43"/> + <source>Qt Compressed Help Files (*.qch)</source> + <translation>Сжатые файлы справки Qt (*.qch)</translation> + </message> + <message> + <location line="+29"/> + <source>The namespace %1 is already registered!</source> + <translation>Пространство имён %1 уже зарегистрировано!</translation> + </message> + <message> + <location line="+8"/> + <source>The specified file is not a valid Qt Help File!</source> + <translation>Указанный файл не является корректным файлом справки Qt!</translation> + </message> + <message> + <location line="+23"/> + <source>Remove Documentation</source> + <translation>Удалить документацию</translation> + </message> + <message> + <location line="+1"/> + <source>Some documents currently opened in Assistant reference the documentation you are attempting to remove. Removing the documentation will close those documents.</source> + <translation>Некоторые открытые в Qt Assistant документы ссылаются на документацию, которую вы пытаетесь удалить. Удаление данной документации приведёт к закрытию таких документов.</translation> + </message> + <message> + <location line="+2"/> + <source>Cancel</source> + <translation>Отмена</translation> + </message> + <message> + <location line="+1"/> + <source>OK</source> + <translation>Удалить</translation> + </message> + <message> + <location line="+86"/> + <source>Use custom settings</source> + <translation>Использовать индивидуальные настройки</translation> + </message> +</context> +<context> + <name>PreferencesDialogClass</name> + <message> + <location filename="../tools/assistant/tools/assistant/preferencesdialog.ui" line="+14"/> + <source>Preferences</source> + <translation>Настройки</translation> + </message> + <message> + <location line="+10"/> + <source>Fonts</source> + <translation>Шрифты</translation> + </message> + <message> + <location line="+14"/> + <source>Font settings:</source> + <translation>Настройки шрифта:</translation> + </message> + <message> + <location line="+8"/> + <source>Browser</source> + <translation>Обозреватель</translation> + </message> + <message> + <location line="+5"/> + <source>Application</source> + <translation>Приложение</translation> + </message> + <message> + <location line="+19"/> + <source>Filters</source> + <translation>Фильтры</translation> + </message> + <message> + <location line="+6"/> + <source>Filter:</source> + <translation>Фильтр:</translation> + </message> + <message> + <location line="+10"/> + <source>Attributes:</source> + <translation>Атрибуты:</translation> + </message> + <message> + <location line="+11"/> + <source>1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>Add</source> + <translation>Добавить</translation> + </message> + <message> + <location line="+7"/> + <location line="+51"/> + <source>Remove</source> + <translation>Удалить</translation> + </message> + <message> + <location line="-43"/> + <source>Documentation</source> + <translation>Документация</translation> + </message> + <message> + <location line="+6"/> + <source>Registered Documentation:</source> + <translation>Зарегистрированная документация:</translation> + </message> + <message> + <location line="+30"/> + <source>Add...</source> + <translation>Добавить...</translation> + </message> + <message> + <location line="+32"/> + <source>Options</source> + <translation>Параметры</translation> + </message> + <message> + <location line="+6"/> + <source>Homepage</source> + <translation>Домашная страница</translation> + </message> + <message> + <location line="+26"/> + <source>Current Page</source> + <translation>Текущая страница</translation> + </message> + <message> + <location line="+7"/> + <source>Restore to default</source> + <translation type="unfinished">Восстановить по умолчанию</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <location filename="../tools/assistant/tools/assistant/bookmarkmanager.cpp" line="+157"/> + <location line="+1"/> + <source>Bookmark</source> + <translation>Закладка</translation> + </message> + <message> + <location filename="../tools/assistant/tools/assistant/cmdlineparser.cpp" line="+112"/> + <source>The specified collection file does not exist!</source> + <translation type="unfinished">Указанный файл набора отсутствует!</translation> + </message> + <message> + <location line="+4"/> + <source>Missing collection file!</source> + <translation type="unfinished">Отсутствует файл набора!</translation> + </message> + <message> + <location line="+9"/> + <source>Invalid URL!</source> + <translation>Некорректный URL!</translation> + </message> + <message> + <location line="+4"/> + <source>Missing URL!</source> + <translation>Отсутствует URL!</translation> + </message> + <message> + <location line="+17"/> + <location line="+19"/> + <location line="+19"/> + <source>Unknown widget: %1</source> + <translation>Неизвестный виджет: %1</translation> + </message> + <message> + <location line="-34"/> + <location line="+19"/> + <location line="+19"/> + <source>Missing widget!</source> + <translation>Отсутствует виджет!</translation> + </message> + <message> + <location line="+7"/> + <location line="+12"/> + <source>The specified Qt help file does not exist!</source> + <translation>Указанный файл справки Qt отсутствует!</translation> + </message> + <message> + <location line="-7"/> + <location line="+12"/> + <source>Missing help file!</source> + <translation>Отсутствует файл справки!</translation> + </message> + <message> + <location line="+7"/> + <source>Missing filter argument!</source> + <translation>Отсутствует параметр фильтра!</translation> + </message> + <message> + <location line="+12"/> + <source>Unknown option: %1</source> + <translation>Неизвестный параметр: %1</translation> + </message> + <message> + <location line="+30"/> + <location line="+2"/> + <source>Qt Assistant</source> + <translation>Qt Assistant</translation> + </message> + <message> + <location filename="../tools/assistant/tools/assistant/main.cpp" line="+203"/> + <source>Could not register documentation file +%1 + +Reason: +%2</source> + <translation>Не удалось зарегистрировать файл документации +%1 + +Причина: +%2</translation> + </message> + <message> + <location line="+4"/> + <source>Documentation successfully registered.</source> + <translation>Документация успешно зарегистрирована.</translation> + </message> + <message> + <location line="+8"/> + <source>Documentation successfully unregistered.</source> + <translation>Документация успешно дерегистрирована.</translation> + </message> + <message> + <location line="+3"/> + <source>Could not unregister documentation file +%1 + +Reason: +%2</source> + <translation>Не удалось дерегистрировать файл документации +%1 + +Причина: +%2</translation> + </message> + <message> + <location line="+37"/> + <source>Cannot load sqlite database driver!</source> + <translation>Не удалось загрузить драйвер базы данных sqlite!</translation> + </message> + <message> + <location line="+9"/> + <source>The specified collection file could not be read!</source> + <translation type="unfinished">Не удалось прочитать указанный файл набора!</translation> + </message> +</context> +<context> + <name>RemoteControl</name> + <message> + <location filename="../tools/assistant/tools/assistant/remotecontrol.cpp" line="+157"/> + <source>Debugging Remote Control</source> + <translation>Отладочное удалённое управление</translation> + </message> + <message> + <location line="+1"/> + <source>Received Command: %1 %2</source> + <translation>Получена команда: %1 %2</translation> + </message> +</context> +<context> + <name>SearchWidget</name> + <message> + <location filename="../tools/assistant/tools/assistant/searchwidget.cpp" line="+195"/> + <source>&Copy</source> + <translation>&Копировать</translation> + </message> + <message> + <location line="+4"/> + <source>Copy &Link Location</source> + <translation>Копировать &адрес ссылки</translation> + </message> + <message> + <location line="+4"/> + <source>Open Link in New Tab</source> + <translation>Открыть ссылку в новой вкладке</translation> + </message> + <message> + <location line="+8"/> + <source>Select All</source> + <translation>Выделить всё</translation> + </message> +</context> +<context> + <name>TopicChooser</name> + <message> + <location filename="../tools/assistant/tools/assistant/topicchooser.cpp" line="+54"/> + <source>Choose a topic for <b>%1</b>:</source> + <translation>Выберите статью для <b>%1</b>:</translation> + </message> + <message> + <location filename="../tools/assistant/tools/assistant/topicchooser.ui" line="+16"/> + <source>Choose Topic</source> + <translation>Выбор статьи</translation> + </message> + <message> + <location line="+21"/> + <source>&Topics</source> + <translation>&Статьи</translation> + </message> + <message> + <location line="+51"/> + <source>&Display</source> + <translation>&Показать</translation> + </message> + <message> + <location line="+16"/> + <source>&Close</source> + <translation>&Закрыть</translation> + </message> +</context> +</TS> diff --git a/translations/linguist_ru.ts b/translations/linguist_ru.ts new file mode 100644 index 0000000..058d86a --- /dev/null +++ b/translations/linguist_ru.ts @@ -0,0 +1,2002 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="ru"> +<context> + <name></name> + <message> + <location filename="../tools/linguist/linguist/phrasebookbox.cpp" line="+59"/> + <source>(New Entry)</source> + <translation>(Новая запись)</translation> + </message> +</context> +<context> + <name>AboutDialog</name> + <message> + <location filename="../tools/linguist/linguist/mainwindow.cpp" line="+1357"/> + <source>Qt Linguist</source> + <translation>Qt Linguist</translation> + </message> +</context> +<context> + <name>BatchTranslationDialog</name> + <message> + <location filename="../tools/linguist/linguist/batchtranslation.ui" line="+54"/> + <source>Qt Linguist - Batch Translation</source> + <translation>Qt Linguist - Пакетный перевод</translation> + </message> + <message> + <location line="+18"/> + <source>Options</source> + <translation>Параметры</translation> + </message> + <message> + <location line="+18"/> + <source>Set translated entries to finished</source> + <translation>Помечать переведенные записи как завершённые</translation> + </message> + <message> + <location line="+10"/> + <source>Retranslate entries with existing translation</source> + <translation>Переводить записи, уже имеющие перевод</translation> + </message> + <message> + <location line="+7"/> + <source>Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked.</source> + <translation>Имейте в виду, что изменённые записи будут отмечены как незавершённые, если не включен параметр "Помечать переведенные записи как завершённые".</translation> + </message> + <message> + <location line="+3"/> + <source>Translate also finished entries</source> + <translation>Также переводить записи с завершёнными переводами</translation> + </message> + <message> + <location line="+16"/> + <source>Phrase book preference</source> + <translation>Предпочитаемые разговорники</translation> + </message> + <message> + <location line="+35"/> + <source>Move up</source> + <translation>Поднять</translation> + </message> + <message> + <location line="+7"/> + <source>Move down</source> + <translation>Опустить</translation> + </message> + <message> + <location line="+24"/> + <source>The batch translator will search through the selected phrase books in the order given above.</source> + <translation>Пакетный переводчик будет искать в выбранных разговорниках в указанном выше порядке.</translation> + </message> + <message> + <location line="+34"/> + <source>&Run</source> + <translation>&Выполнить</translation> + </message> + <message> + <location line="+7"/> + <source>Cancel</source> + <translation>Отмена</translation> + </message> + <message> + <location filename="../tools/linguist/linguist/batchtranslationdialog.cpp" line="+79"/> + <source>Batch Translation of '%1' - Qt Linguist</source> + <translation>Пакетный перевод '%1' - Qt Linguist</translation> + </message> + <message> + <location line="+37"/> + <source>Searching, please wait...</source> + <translation>Идёт поиск, ждите...</translation> + </message> + <message> + <location line="+0"/> + <source>&Cancel</source> + <translation>&Отмена</translation> + </message> + <message> + <location line="+42"/> + <source>Linguist batch translator</source> + <translation>Пакетный переводчик Qt Linguist</translation> + </message> + <message numerus="yes"> + <location line="+1"/> + <source>Batch translated %n entries</source> + <translation> + <numerusform>Автоматически переведена %n запись</numerusform> + <numerusform>Автоматически переведены %n записи</numerusform> + <numerusform>Автоматически переведено %n записей</numerusform> + </translation> + </message> +</context> +<context> + <name>DataModel</name> + <message> + <location filename="../tools/linguist/linguist/messagemodel.cpp" line="+214"/> + <source><qt>Duplicate messages found in '%1':</source> + <translation><qt>В '%1' обнаружены повторяющиеся сообщения:</translation> + </message> + <message> + <location line="+4"/> + <source><p>[more duplicates omitted]</source> + <translation><p>[остальные повторы не указаны]</translation> + </message> + <message> + <location line="+3"/> + <source><p>* Context: %1<br>* Source: %2</source> + <translation><p>* Контекст: %1<br>* Источник: %2</translation> + </message> + <message> + <location line="+3"/> + <source><br>* Comment: %3</source> + <translation><br>* Комментарий: %3</translation> + </message> + <message> + <location line="+70"/> + <source>Linguist does not know the plural rules for '%1'. +Will assume a single universal form.</source> + <translation>Qt Linguist не знает правила множественных форм для '%1'. +Будет использована универсальная единичная форма.</translation> + </message> + <message> + <location line="+56"/> + <source>Cannot create '%2': %1</source> + <translation>Не удалось создать '%2': %1</translation> + </message> + <message> + <location line="+56"/> + <source>Universal Form</source> + <translation>Универсальная форма</translation> + </message> +</context> +<context> + <name>ErrorsView</name> + <message> + <location filename="../tools/linguist/linguist/errorsview.cpp" line="+76"/> + <source>Accelerator possibly superfluous in translation.</source> + <translation>Возможно, лишний акселератор в переводе.</translation> + </message> + <message> + <location line="+3"/> + <source>Accelerator possibly missing in translation.</source> + <translation>Возможно, пропущен акселератор в переводе.</translation> + </message> + <message> + <location line="+3"/> + <source>Translation does not end with the same punctuation as the source text.</source> + <translation>Перевод не заканчивается тем же знаком препинания, что и исходный текст.</translation> + </message> + <message> + <location line="+3"/> + <source>A phrase book suggestion for '%1' was ignored.</source> + <translation>Предложение разговорника для '%1' пропущено.</translation> + </message> + <message> + <location line="+3"/> + <source>Translation does not refer to the same place markers as in the source text.</source> + <translation>Перевод не содержит тех же маркеров форматирования, что и исходный текст.</translation> + </message> + <message> + <location line="+3"/> + <source>Translation does not contain the necessary %n place marker.</source> + <translation>Перевод не содержит необходимого маркера форматирования %n.</translation> + </message> + <message> + <location line="+3"/> + <source>Unknown error</source> + <translation>Неизвестная ошибка</translation> + </message> +</context> +<context> + <name>FindDialog</name> + <message> + <location filename="../tools/linguist/linguist/finddialog.cpp" line="+42"/> + <source></source> + <comment>Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog</comment> + <translation></translation> + </message> + <message> + <location filename="../tools/linguist/linguist/finddialog.ui" line="+60"/> + <source>Find</source> + <translation>Поиск</translation> + </message> + <message> + <location line="+3"/> + <source>This window allows you to search for some text in the translation source file.</source> + <translation>Данное окно позволяет искать текст в файле перевода.</translation> + </message> + <message> + <location line="+28"/> + <source>&Find what:</source> + <translation>&Искать:</translation> + </message> + <message> + <location line="+10"/> + <source>Type in the text to search for.</source> + <translation>Введите искомый текст.</translation> + </message> + <message> + <location line="+9"/> + <source>Options</source> + <translation>Параметры</translation> + </message> + <message> + <location line="+12"/> + <source>Source texts are searched when checked.</source> + <translation>Если отмечено, поиск будет вестись в исходных текстах.</translation> + </message> + <message> + <location line="+3"/> + <source>&Source texts</source> + <translation>&Исходные тексты</translation> + </message> + <message> + <location line="+10"/> + <source>Translations are searched when checked.</source> + <translation>Если отмечено, поиск будет вестись в переведённых текстах.</translation> + </message> + <message> + <location line="+3"/> + <source>&Translations</source> + <translation>&Переводы</translation> + </message> + <message> + <location line="+10"/> + <source>Texts such as 'TeX' and 'tex' are considered as different when checked.</source> + <translation>Если отмечено, строки "ПрИмЕр" и "пример" будет считаться разными.</translation> + </message> + <message> + <location line="+3"/> + <source>&Match case</source> + <translation>С учётом &регистра</translation> + </message> + <message> + <location line="+7"/> + <source>Comments and contexts are searched when checked.</source> + <translation>Если отмечено, поиск будет вестись по контекстам и комментариям.</translation> + </message> + <message> + <location line="+3"/> + <source>&Comments</source> + <translation>&Комментарии</translation> + </message> + <message> + <location line="+10"/> + <source>Ignore &accelerators</source> + <translation>Пропускать &акселераторы</translation> + </message> + <message> + <location line="+23"/> + <source>Click here to find the next occurrence of the text you typed in.</source> + <translation>Найти следующее совпадение для введённого текста.</translation> + </message> + <message> + <location line="+3"/> + <source>Find Next</source> + <translation>Найти далее</translation> + </message> + <message> + <location line="+13"/> + <source>Click here to close this window.</source> + <translation>Закрыть окно.</translation> + </message> + <message> + <location line="+3"/> + <source>Cancel</source> + <translation>Отмена</translation> + </message> +</context> +<context> + <name>LRelease</name> + <message numerus="yes"> + <location filename="../tools/linguist/shared/qm.cpp" line="+715"/> + <source> Generated %n translation(s) (%1 finished and %2 unfinished) +</source> + <translation> + <numerusform> Создан %n перевод (%1 завершённых и %2 незавершённых) +</numerusform> + <numerusform> Создано %n перевода (%1 завершённых и %2 незавершённых) +</numerusform> + <numerusform> Создано %n переводов (%1 завершённых и %2 незавершённых) +</numerusform> + </translation> + </message> + <message numerus="yes"> + <location line="+4"/> + <source> Ignored %n untranslated source text(s) +</source> + <translation> + <numerusform> Пропущен %n непереведённый исходный текст +</numerusform> + <numerusform> Пропущено %n непереведённых исходных текста +</numerusform> + <numerusform> Пропущено %n непереведённых исходных текстов +</numerusform> + </translation> + </message> +</context> +<context> + <name>MainWindow</name> + <message> + <location filename="../tools/linguist/linguist/mainwindow.cpp" line="-1315"/> + <source></source> + <comment>This is the application's main window.</comment> + <translatorcomment>Основное окно программы.</translatorcomment> + <translation></translation> + </message> + <message> + <location line="+165"/> + <source>Source text</source> + <translation>Исходный текст</translation> + </message> + <message> + <location line="+1"/> + <location line="+25"/> + <source>Index</source> + <translation>Индекс</translation> + </message> + <message> + <location line="-2"/> + <location line="+61"/> + <source>Context</source> + <translation>Контекст</translation> + </message> + <message> + <location line="-60"/> + <source>Items</source> + <translation>Записи</translation> + </message> + <message> + <location line="+77"/> + <source>This panel lists the source contexts.</source> + <translation>В данной панели перечислены исходные контексты.</translation> + </message> + <message> + <location line="+15"/> + <source>Strings</source> + <translation>Строки</translation> + </message> + <message> + <location line="+39"/> + <source>Phrases and guesses</source> + <translation>Фразы и похожие переводы</translation> + </message> + <message> + <location line="+10"/> + <source>Sources and Forms</source> + <translation>Исходники и формы</translation> + </message> + <message> + <location line="+15"/> + <source>Warnings</source> + <translation>Предупреждения</translation> + </message> + <message> + <location line="+59"/> + <source> MOD </source> + <comment>status bar: file(s) modified</comment> + <translation> ИЗМ </translation> + </message> + <message> + <location line="+125"/> + <source>Loading...</source> + <translation>Загрузка...</translation> + </message> + <message> + <location line="+32"/> + <location line="+22"/> + <source>Loading File - Qt Linguist</source> + <translation>Загрузка файла - Qt Linguist</translation> + </message> + <message> + <location line="-21"/> + <source>The file '%1' does not seem to be related to the currently open file(s) '%2'. + +Close the open file(s) first?</source> + <translation>Файл '%1', похоже, не связан с открытым файлом(ами) '%2'. + +Закрыть открытые файлы?</translation> + </message> + <message> + <location line="+22"/> + <source>The file '%1' does not seem to be related to the file '%2' which is being loaded as well. + +Skip loading the first named file?</source> + <translation>Файл '%1', похоже, не связан с загруженным файлом '%2'. + +Пропустить загрузку файла?</translation> + </message> + <message numerus="yes"> + <location line="+61"/> + <source>%n translation unit(s) loaded.</source> + <translation> + <numerusform>Загружена %n запись.</numerusform> + <numerusform>Загружено %n записи.</numerusform> + <numerusform>Загружено %n записей.</numerusform> + </translation> + </message> + <message> + <location line="+93"/> + <source>Related files (%1);;</source> + <translation>Связанные файлы (%1);;</translation> + </message> + <message> + <location line="+4"/> + <source>Open Translation Files</source> + <translation>Открыть файлы перевода</translation> + </message> + <message> + <location line="+10"/> + <location line="+31"/> + <source>File saved.</source> + <translation>Файл сохранён.</translation> + </message> + <message> + <location line="+15"/> + <location line="+1164"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+246"/> + <source>Release</source> + <translation>Компиляция</translation> + </message> + <message> + <location line="-1163"/> + <source>Qt message files for released applications (*.qm) +All files (*)</source> + <translation>Скомпилированные файлы перевода для приложений Qt (*.qm) +Все файлы (*)</translation> + </message> + <message> + <location line="+3"/> + <location line="+12"/> + <source>File created.</source> + <translation>Файл создан.</translation> + </message> + <message> + <location line="+27"/> + <location line="+355"/> + <source>Printing...</source> + <translation>Печать...</translation> + </message> + <message> + <location line="-347"/> + <source>Context: %1</source> + <translation>Контекст: %1</translation> + </message> + <message> + <location line="+32"/> + <source>finished</source> + <translation>завершён</translation> + </message> + <message> + <location line="+3"/> + <source>unresolved</source> + <translation>неразрешённый</translation> + </message> + <message> + <location line="+3"/> + <source>obsolete</source> + <translation>устаревший</translation> + </message> + <message> + <location line="+15"/> + <location line="+307"/> + <source>Printing... (page %1)</source> + <translation>Печать... (страница %1)</translation> + </message> + <message> + <location line="-300"/> + <location line="+307"/> + <source>Printing completed</source> + <translation>Печать завершена</translation> + </message> + <message> + <location line="-305"/> + <location line="+307"/> + <source>Printing aborted</source> + <translation>Печать прервана</translation> + </message> + <message> + <location line="-232"/> + <source>Search wrapped.</source> + <translation>Поиск с начала.</translation> + </message> + <message> + <location line="+17"/> + <location line="+278"/> + <location line="+40"/> + <location line="+24"/> + <location line="+22"/> + <location line="+516"/> + <location line="+1"/> + <location line="+274"/> + <location line="+40"/> + <location line="+10"/> + <source>Qt Linguist</source> + <translation>Qt Linguist</translation> + </message> + <message> + <location line="-1204"/> + <location line="+102"/> + <source>Cannot find the string '%1'.</source> + <translation>Не удалось найти строку '%1'.</translation> + </message> + <message> + <location line="-82"/> + <source>Search And Translate in '%1' - Qt Linguist</source> + <translation>Поиск и перевод '%1' - Qt Linguist</translation> + </message> + <message> + <location line="+34"/> + <location line="+23"/> + <location line="+24"/> + <source>Translate - Qt Linguist</source> + <translation>Перевод - Qt Linguist</translation> + </message> + <message numerus="yes"> + <location line="-46"/> + <source>Translated %n entry(s)</source> + <translation> + <numerusform>Переведена %n запись</numerusform> + <numerusform>Переведено %n записи</numerusform> + <numerusform>Переведено %n записей</numerusform> + </translation> + </message> + <message> + <location line="+23"/> + <source>No more occurrences of '%1'. Start over?</source> + <translation>Нет больше совпадений с '%1'. Начать заново?</translation> + </message> + <message> + <location line="+30"/> + <source>Create New Phrase Book</source> + <translation>Создать разговорник</translation> + </message> + <message> + <location line="+1"/> + <source>Qt phrase books (*.qph) +All files (*)</source> + <translation>Разговорники Qt (*.qph) +Все файлы (*)</translation> + </message> + <message> + <location line="+11"/> + <source>Phrase book created.</source> + <translation>Разговорник создан.</translation> + </message> + <message> + <location line="+17"/> + <source>Open Phrase Book</source> + <translation>Открыть разговорник</translation> + </message> + <message> + <location line="+1"/> + <source>Qt phrase books (*.qph);;All files (*)</source> + <translation>Разговорники Qt (*.qph);;Все файлы (*)</translation> + </message> + <message numerus="yes"> + <location line="+7"/> + <source>%n phrase(s) loaded.</source> + <translation> + <numerusform>Загружена %n фраза.</numerusform> + <numerusform>Загружено %n фразы.</numerusform> + <numerusform>Загружено %n фраз.</numerusform> + </translation> + </message> + <message> + <location line="+93"/> + <location line="+3"/> + <location line="+7"/> + <source>Add to phrase book</source> + <translation>Добавить в разговорник</translation> + </message> + <message> + <location line="-9"/> + <source>No appropriate phrasebook found.</source> + <translation>Подходящий разговорник не найден.</translation> + </message> + <message> + <location line="+3"/> + <source>Adding entry to phrasebook %1</source> + <translation>Добавление записи в разговорник %1</translation> + </message> + <message> + <location line="+7"/> + <source>Select phrase book to add to</source> + <translation>Выберите разговорник, в который желаете добавить фразу</translation> + </message> + <message> + <location line="+29"/> + <source>Unable to launch Qt Assistant (%1)</source> + <translation>Не удалось запустить Qt Assistant (%1)</translation> + </message> + <message> + <location line="+17"/> + <source>Version %1</source> + <translation>Версия %1</translation> + </message> + <message> + <location line="+6"/> + <source><center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist is a tool for adding translations to Qt applications.</p><p>%2</p><p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p></source> + <translation type="unfinished"><center><img src=":/images/splash.png"/></img><p>%1</p></center><p>Qt Linguist - инструмент для добавления переводов в приложения на основе Qt.</p><p>%2</p><p>Copyright (C) 2009 Корпорация Nokia и/или её дочерние подразделения.</p><p>Программа предоставляется "как есть" без гарантий любого рода, включая гарантии дизайна, коммерческой ценности и пригодности для определённой цели.</p></translation> + </message> + <message> + <location line="+41"/> + <source>Do you want to save the modified files?</source> + <translation>Желаете сохранить изменённые файлы?</translation> + </message> + <message> + <location line="+22"/> + <source>Do you want to save '%1'?</source> + <translation>Желаете сохранить '%1'?</translation> + </message> + <message> + <location line="+43"/> + <source>Qt Linguist[*]</source> + <translation>Qt Linguist[*]</translation> + </message> + <message> + <location line="+2"/> + <source>%1[*] - Qt Linguist</source> + <translation>%1[*] - Qt Linguist</translation> + </message> + <message> + <location line="+267"/> + <location line="+12"/> + <source>No untranslated translation units left.</source> + <translation>Непереведённых записей не осталось.</translation> + </message> + <message> + <location line="+176"/> + <source>&Window</source> + <translation>&Окно</translation> + </message> + <message> + <location line="+2"/> + <source>Minimize</source> + <translation>Свернуть</translation> + </message> + <message> + <location line="+1"/> + <source>Ctrl+M</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+12"/> + <source>Display the manual for %1.</source> + <translation>Показать руководство для %1.</translation> + </message> + <message> + <location line="+1"/> + <source>Display information about %1.</source> + <translation>Показать информацию о %1.</translation> + </message> + <message> + <location line="+70"/> + <source>&Save '%1'</source> + <translation>&Сохранить'%1'</translation> + </message> + <message> + <location line="+1"/> + <source>Save '%1' &As...</source> + <translation>Сохранить'%1' &как...</translation> + </message> + <message> + <location line="+1"/> + <source>Release '%1'</source> + <translation>Скомпилировать '%1'</translation> + </message> + <message> + <location line="+1"/> + <source>Release '%1' As...</source> + <translation>Скомпилировать '%1' как...</translation> + </message> + <message> + <location line="+1"/> + <source>&Close '%1'</source> + <translation>&Закрыть '%1'</translation> + </message> + <message> + <location line="+2"/> + <location line="+15"/> + <source>&Save</source> + <translation>&Сохранить</translation> + </message> + <message> + <location line="-14"/> + <location line="+11"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="-11"/> + <source>Save &As...</source> + <translation>Сохранить &как...</translation> + </message> + <message> + <location line="-9"/> + <location line="+10"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+508"/> + <location line="+3"/> + <source>Release As...</source> + <translation>Скомпилировать как...</translation> + </message> + <message> + <location line="-9"/> + <location line="+13"/> + <source>&Close</source> + <translation>&Закрыть</translation> + </message> + <message> + <location line="-10"/> + <source>Save All</source> + <translation>Сохранить все</translation> + </message> + <message> + <location line="+1"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+118"/> + <source>&Release All</source> + <translation>С&компилировать все</translation> + </message> + <message> + <location line="+1"/> + <source>Close All</source> + <translation>Закрыть все</translation> + </message> + <message> + <location line="+7"/> + <source>&Release</source> + <translation>С&компилировать</translation> + </message> + <message> + <location line="+16"/> + <source>Translation File &Settings for '%1'...</source> + <translation>&Параметры файла перевода для '%1'...</translation> + </message> + <message> + <location line="+1"/> + <source>&Batch Translation of '%1'...</source> + <translation>Пак&етный перевод '%1'...</translation> + </message> + <message> + <location line="+1"/> + <source>Search And &Translate in '%1'...</source> + <translation>&Найти и перевести в '%1'...</translation> + </message> + <message> + <location line="+2"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="-32"/> + <source>Translation File &Settings...</source> + <translation>&Параметры файла перевода...</translation> + </message> + <message> + <location line="+1"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="-100"/> + <source>&Batch Translation...</source> + <translation>Пак&етный перевод...</translation> + </message> + <message> + <location line="+1"/> + <source>Search And &Translate...</source> + <translation>&Найти и перевести...</translation> + </message> + <message> + <location line="+51"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+28"/> + <source>File</source> + <translation>Файл</translation> + </message> + <message> + <location line="+7"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+11"/> + <source>Edit</source> + <translation>Правка</translation> + </message> + <message> + <location line="+6"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+11"/> + <source>Translation</source> + <translation>Перевод</translation> + </message> + <message> + <location line="+6"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+11"/> + <source>Validation</source> + <translation>Проверка</translation> + </message> + <message> + <location line="+7"/> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="+11"/> + <source>Help</source> + <translation>Справка</translation> + </message> + <message> + <location line="+84"/> + <source>Cannot read from phrase book '%1'.</source> + <translation>Не удалось прочитать из разговорника '%1'.</translation> + </message> + <message> + <location line="+15"/> + <source>Close this phrase book.</source> + <translation>Закрыть разговорник.</translation> + </message> + <message> + <location line="+4"/> + <source>Enables you to add, modify, or delete entries in this phrase book.</source> + <translation>Позволяет добавлять, изменять и удалять записи в разговорнике.</translation> + </message> + <message> + <location line="+5"/> + <source>Print the entries in this phrase book.</source> + <translation>Печать записей фраз разговорника.</translation> + </message> + <message> + <location line="+16"/> + <source>Cannot create phrase book '%1'.</source> + <translation>Не удалось создать разговорник '%1'.</translation> + </message> + <message> + <location line="+10"/> + <source>Do you want to save phrase book '%1'?</source> + <translation>Желаете сохранить разговорник '%1'?</translation> + </message> + <message> + <location line="+314"/> + <source>All</source> + <translation>Все</translation> + </message> + <message> + <location filename="../tools/linguist/linguist/mainwindow.ui" line="-750"/> + <source>MainWindow</source> + <translation>Главное окно</translation> + </message> + <message> + <location line="+14"/> + <source>&Phrases</source> + <translation>Фра&зы</translation> + </message> + <message> + <location line="+4"/> + <source>&Close Phrase Book</source> + <translation>&Закрыть разговорник</translation> + </message> + <message> + <location line="+5"/> + <source>&Edit Phrase Book</source> + <translation>&Редактироваь разговорник</translation> + </message> + <message> + <location line="+5"/> + <source>&Print Phrase Book</source> + <translation>&Печатать разговорник</translation> + </message> + <message> + <location line="+13"/> + <source>V&alidation</source> + <translation>П&роверка</translation> + </message> + <message> + <location line="+9"/> + <source>&View</source> + <translation>&Вид</translation> + </message> + <message> + <location line="+4"/> + <source>Vie&ws</source> + <translation>Вид&ы</translation> + </message> + <message> + <location line="+5"/> + <source>&Toolbars</source> + <translation>Пан&ели инструментов</translation> + </message> + <message> + <location line="+12"/> + <source>&Help</source> + <translation>&Справка</translation> + </message> + <message> + <location line="+9"/> + <source>&Translation</source> + <translation>П&еревод</translation> + </message> + <message> + <location line="+11"/> + <source>&File</source> + <translation>&Файл</translation> + </message> + <message> + <location line="+4"/> + <source>Recently Opened &Files</source> + <translation>Недавно открытые &файлы</translation> + </message> + <message> + <location line="+23"/> + <source>&Edit</source> + <translation>&Правка</translation> + </message> + <message> + <location line="+27"/> + <source>&Open...</source> + <translation>&Открыть...</translation> + </message> + <message> + <location line="+3"/> + <source>Open a Qt translation source file (TS file) for editing</source> + <translation>Открыть исходный файл переводов Qt (файл TS) для изменения</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+O</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>E&xit</source> + <translation>В&ыход</translation> + </message> + <message> + <location line="+6"/> + <source>Close this window and exit.</source> + <translation>Закрыть окно и выйти.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+Q</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>Save</source> + <translation>Сохранить</translation> + </message> + <message> + <location line="+3"/> + <source>Save changes made to this Qt translation source file</source> + <translation>Сохранить изменения в данном исходном файле перевода Qt</translation> + </message> + <message> + <location line="+8"/> + <source>Save As...</source> + <translation>Сохранить как...</translation> + </message> + <message> + <location line="+3"/> + <source>Save changes made to this Qt translation source file into a new file.</source> + <translation>Сохранить изменения в данном исходном файле перевода Qt в новый файл.</translation> + </message> + <message> + <location line="+8"/> + <source>Create a Qt message file suitable for released applications from the current message file.</source> + <translation>Скомпилировать файл перевода Qt из текущего файла.</translation> + </message> + <message> + <location line="+5"/> + <source>&Print...</source> + <translation>&Печать...</translation> + </message> + <message> + <location line="+3"/> + <source>Print a list of all the translation units in the current translation source file.</source> + <translation>Печать списка всех записей перевода из текущего файла.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+P</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>&Undo</source> + <translation>&Отменить</translation> + </message> + <message> + <location line="+3"/> + <source>Undo the last editing operation performed on the current translation.</source> + <translation>Отменить последнее изменение текущего перевода.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+Z</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Redo</source> + <translation>&Повторить</translation> + </message> + <message> + <location line="+3"/> + <source>Redo an undone editing operation performed on the translation.</source> + <translation>Повторить отменённую правку перевода.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+Y</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>Cu&t</source> + <translation>Выр&езать</translation> + </message> + <message> + <location line="+3"/> + <source>Copy the selected translation text to the clipboard and deletes it.</source> + <translation>Скопировать отмеченный текст в буфер обмена и удалить его из оригинала.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+X</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Copy</source> + <translation>&Копировать</translation> + </message> + <message> + <location line="+3"/> + <source>Copy the selected translation text to the clipboard.</source> + <translation>Скопировать отмеченный текст в буфер обмена.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+C</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Paste</source> + <translation>&Вставить</translation> + </message> + <message> + <location line="+3"/> + <source>Paste the clipboard text into the translation.</source> + <translation>Вставить текст из буфера обмена в перевод.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+V</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>Select &All</source> + <translation>В&ыделить всё</translation> + </message> + <message> + <location line="+3"/> + <source>Select the whole translation text.</source> + <translation>Выделить весь текст перевода.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+A</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Find...</source> + <translation>&Найти...</translation> + </message> + <message> + <location line="+3"/> + <source>Search for some text in the translation source file.</source> + <translation>Найти текст в исходном файле перевода.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+F</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>Find &Next</source> + <translation>Найти д&алее</translation> + </message> + <message> + <location line="+3"/> + <source>Continue the search where it was left.</source> + <translation>Продолжить поиск с места, где он был остановлен.</translation> + </message> + <message> + <location line="+3"/> + <source>F3</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>&Prev Unfinished</source> + <translation>&Пред. незавершённый</translation> + </message> + <message> + <location line="+3"/> + <source>Previous unfinished item.</source> + <translation>Предыдущий незавершённый перевод.</translation> + </message> + <message> + <location line="+3"/> + <source>Move to the previous unfinished item.</source> + <translation>Перейти к предыдущему незавершённому переводу.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+K</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>&Next Unfinished</source> + <translation>&След. незавершённый</translation> + </message> + <message> + <location line="+3"/> + <source>Next unfinished item.</source> + <translation>Следующий незавершённый перевод.</translation> + </message> + <message> + <location line="+3"/> + <source>Move to the next unfinished item.</source> + <translation>Перейти к следующему незавершённому переводу.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+J</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>P&rev</source> + <translation>Пр&едыдущий</translation> + </message> + <message> + <location line="+3"/> + <source>Move to previous item.</source> + <translation>Предыдущий перевод.</translation> + </message> + <message> + <location line="+3"/> + <source>Move to the previous item.</source> + <translation>Перейти к предыдущему переводу.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+Shift+K</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>Ne&xt</source> + <translation>С&ледующий</translation> + </message> + <message> + <location line="+3"/> + <source>Next item.</source> + <translation>Следующий перевод.</translation> + </message> + <message> + <location line="+3"/> + <source>Move to the next item.</source> + <translation>Перейти к следующему переводу.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+Shift+J</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Done and Next</source> + <translation>&Готово и далее</translation> + </message> + <message> + <location line="+3"/> + <source>Mark item as done and move to the next unfinished item.</source> + <translation>Пометить перевод как завершённый и перейти к следующему незавершённому.</translation> + </message> + <message> + <location line="+3"/> + <source>Mark this item as done and move to the next unfinished item.</source> + <translation>Пометить перевод как завершённый и перейти к следующему незавершённому.</translation> + </message> + <message> + <location line="+11"/> + <location line="+3"/> + <source>Copy from source text</source> + <translation>Скопировать из исходного текста</translation> + </message> + <message> + <location line="+3"/> + <location line="+3"/> + <source>Copies the source text into the translation field.</source> + <translation>Скопировать исходный текст в поле перевода.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+B</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Accelerators</source> + <translation>&Акселераторы</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of accelerators.</source> + <translation>Переключение проверки акселераторов.</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of accelerators, i.e. whether the number of ampersands in the source and translation text is the same. If the check fails, a message is shown in the warnings window.</source> + <translation>Переключение проверки акселераторов, т.е. совпадает ли количество амперсандов в исходном и переведённом текстах. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation> + </message> + <message> + <location line="+11"/> + <source>&Ending Punctuation</source> + <translation>&Знаки препинания</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of ending punctuation.</source> + <translation>Переключение проверки знаков препинания в конце текста.</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of ending punctuation. If the check fails, a message is shown in the warnings window.</source> + <translation>Переключение проверки знаков препинания в конце текста. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation> + </message> + <message> + <location line="+11"/> + <source>&Phrase matches</source> + <translation>Совпадение &фраз</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle checking that phrase suggestions are used.</source> + <translation>Переключение проверки использования предложений для фраз. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle checking that phrase suggestions are used. If the check fails, a message is shown in the warnings window.</source> + <translation>Переключение проверки использования предложений для фраз. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation> + </message> + <message> + <location line="+11"/> + <source>Place &Marker Matches</source> + <translation>Совпадение &маркеров</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of place markers.</source> + <translation>Переключение проверки маркеров форматирования.</translation> + </message> + <message> + <location line="+3"/> + <source>Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window.</source> + <translation>Переключение проверки маркеров форматирования, т.е. все ли маркеры (%1, %2, ...) исходного текста присутствуют в переведённом. Если выявлено несовпадение, будет показано сообщение в окне предупреждений.</translation> + </message> + <message> + <location line="+8"/> + <source>&New Phrase Book...</source> + <translation>&Новый разговорник...</translation> + </message> + <message> + <location line="+3"/> + <source>Create a new phrase book.</source> + <translation>Создать разговорник.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+N</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>&Open Phrase Book...</source> + <translation>&Открыть разговорник...</translation> + </message> + <message> + <location line="+3"/> + <source>Open a phrase book to assist translation.</source> + <translation>Открыть разговорник для помощи в переводе.</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+H</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>&Reset Sorting</source> + <translation>&Сброс сортировки</translation> + </message> + <message> + <location line="+3"/> + <source>Sort the items back in the same order as in the message file.</source> + <translation>Упорядочить элементы в той последовательности, в которой они находятся в файле.</translation> + </message> + <message> + <location line="+14"/> + <source>&Display guesses</source> + <translation>&Предлагать похожие</translation> + </message> + <message> + <location line="+3"/> + <source>Set whether or not to display translation guesses.</source> + <translation>Определяет необходимо или нет отображать похожие переводы.</translation> + </message> + <message> + <location line="+14"/> + <source>&Statistics</source> + <translation>&Статистика</translation> + </message> + <message> + <location line="+3"/> + <source>Display translation statistics.</source> + <translation>Показать статистику перевода.</translation> + </message> + <message> + <location line="+8"/> + <source>&Manual</source> + <translation>&Руководство</translation> + </message> + <message> + <location line="+6"/> + <source>F1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+8"/> + <source>About Qt Linguist</source> + <translation>О Qt Linguist</translation> + </message> + <message> + <location line="+8"/> + <source>About Qt</source> + <translation>О Qt</translation> + </message> + <message> + <location line="+3"/> + <source>Display information about the Qt toolkit by Trolltech.</source> + <translation>Показать информацию об инструментарии Qt от Nokia.</translation> + </message> + <message> + <location line="+14"/> + <source>&What's This?</source> + <translation>&Что это?</translation> + </message> + <message> + <location line="+3"/> + <location line="+3"/> + <source>What's This?</source> + <translation>Что это?</translation> + </message> + <message> + <location line="+3"/> + <source>Enter What's This? mode.</source> + <translation>Переход в режим "Что это?".</translation> + </message> + <message> + <location line="+3"/> + <source>Shift+F1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+11"/> + <source>&Search And Translate...</source> + <translation>&Найти и перевести...</translation> + </message> + <message> + <location line="+3"/> + <source>Replace the translation on all entries that matches the search source text.</source> + <translation>Заменить перевод всех записей, которые совпадают с искомым исходным текстом.</translation> + </message> + <message> + <location line="+14"/> + <source>Batch translate all entries using the information in the phrase books.</source> + <translation>Перевести все записи в пакетном режиме, используя информацию из разговорника.</translation> + </message> + <message> + <location line="+14"/> + <source>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file.</source> + <translation>Создание готового файла перевода Qt из текущего файла. Имя файла будет автоматически определено из имени .ts файла.</translation> + </message> + <message> + <location line="+63"/> + <source>Open/Refresh Form &Preview</source> + <translation>Открыть/обновить предпрос&мотр формы</translation> + </message> + <message> + <location line="+3"/> + <location line="+3"/> + <source>Form Preview Tool</source> + <translation>Инструмент предпросмотра форм</translation> + </message> + <message> + <location line="+3"/> + <source>F5</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+22"/> + <source>&Add to Phrase Book</source> + <translation>&Добавить в разговорник</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+T</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Open Read-O&nly...</source> + <translation>Открыть только для &чтения...</translation> + </message> + <message> + <location line="+5"/> + <source>&Save All</source> + <translation>&Сохранить все</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+S</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+10"/> + <source>Close</source> + <translation>Закрыть</translation> + </message> + <message> + <location line="+5"/> + <source>&Close All</source> + <translation>&Закрыть все</translation> + </message> + <message> + <location line="+3"/> + <source>Ctrl+W</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>MessageEditor</name> + <message> + <location filename="../tools/linguist/linguist/messageeditor.cpp" line="+42"/> + <source></source> + <comment>This is the right panel of the main window.</comment> + <translatorcomment>Правая панель основного окна</translatorcomment> + <translation></translation> + </message> + <message> + <location line="+30"/> + <source>German</source> + <translation>Немецкий</translation> + </message> + <message> + <location line="+1"/> + <source>Japanese</source> + <translation>Японский</translation> + </message> + <message> + <location line="+1"/> + <source>French</source> + <translation>Французский</translation> + </message> + <message> + <location line="+1"/> + <source>Polish</source> + <translation>Польский</translation> + </message> + <message> + <location line="+1"/> + <source>Chinese</source> + <translation>Китайский</translation> + </message> + <message> + <location line="+50"/> + <source>This whole panel allows you to view and edit the translation of some source text.</source> + <translation>Данная панель позволяет просматривать и редактировать перевод исходного текста.</translation> + </message> + <message> + <location line="+18"/> + <source>Source text</source> + <translation>Исходный текст</translation> + </message> + <message> + <location line="+2"/> + <source>This area shows the source text.</source> + <translation>В данной области отображается исходный текст.</translation> + </message> + <message> + <location line="+3"/> + <source>Source text (Plural)</source> + <translation>Исходный текст (множественная форма)</translation> + </message> + <message> + <location line="+2"/> + <source>This area shows the plural form of the source text.</source> + <translation>В данной области отображается исходный текст во множественной форме.</translation> + </message> + <message> + <location line="+3"/> + <source>Developer comments</source> + <translation>Комментарии разработчика</translation> + </message> + <message> + <location line="+3"/> + <source>This area shows a comment that may guide you, and the context in which the text occurs.</source> + <translation>В данной области отображается комментарий, который поможет определить в каком контексте встречается переводимый текст.</translation> + </message> + <message> + <location line="+59"/> + <source>Here you can enter comments for your own use. They have no effect on the translated applications.</source> + <translation>Здесь вы можете оставить комментарий для собственного использования. Комментарии не влияют на перевод приложений.</translation> + </message> + <message> + <location line="+205"/> + <source>%1 translation (%2)</source> + <translation>%1 перевод (%2)</translation> + </message> + <message> + <location line="+19"/> + <source>This is where you can enter or modify the translation of the above source text.</source> + <translation>Здесь вы можете ввести или изменить перевод текста, представленного выше.</translation> + </message> + <message> + <location line="+5"/> + <source>%1 translation</source> + <translation>%1 перевод</translation> + </message> + <message> + <location line="+1"/> + <source>%1 translator comments</source> + <translation>Комментарий переводчика на %1</translation> + </message> + <message> + <location line="+140"/> + <source>'%1' +Line: %2</source> + <translation>'%1' +Строка: %2</translation> + </message> +</context> +<context> + <name>MessageModel</name> + <message> + <location filename="../tools/linguist/linguist/messagemodel.cpp" line="+832"/> + <source>Completion status for %1</source> + <translation>Состояние завершённости для %1</translation> + </message> + <message> + <location line="+15"/> + <source><file header></source> + <translation><заголовок файла></translation> + </message> + <message> + <location line="+2"/> + <source><context comment></source> + <translation><контекстный комментарий></translation> + </message> + <message> + <location line="+71"/> + <source><unnamed context></source> + <translation><безымянный контекст></translation> + </message> +</context> +<context> + <name>MsgEdit</name> + <message> + <location filename="../tools/linguist/linguist/messageeditor.cpp" line="-544"/> + <source></source> + <comment>This is the right panel of the main window.</comment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PhraseBookBox</name> + <message> + <location filename="../tools/linguist/linguist/phrasebookbox.cpp" line="-17"/> + <source></source> + <comment>Go to Phrase > Edit Phrase Book... The dialog that pops up is a PhraseBookBox.</comment> + <translation></translation> + </message> + <message> + <location line="+25"/> + <source>%1[*] - Qt Linguist</source> + <translation>%1[*] - Qt Linguist</translation> + </message> + <message> + <location line="+90"/> + <source>Qt Linguist</source> + <translation>Qt Linguist</translation> + </message> + <message> + <location line="+1"/> + <source>Cannot save phrase book '%1'.</source> + <translation>Не удалось сохранить разговорник '%1'.</translation> + </message> + <message> + <location filename="../tools/linguist/linguist/phrasebookbox.ui" line="+54"/> + <source>Edit Phrase Book</source> + <translation>Правка разговорника</translation> + </message> + <message> + <location line="+3"/> + <source>This window allows you to add, modify, or delete entries in a phrase book.</source> + <translation>Данное окно позволяет добавлять, изменять и удалять записи в разговорнике.</translation> + </message> + <message> + <location line="+10"/> + <source>&Translation:</source> + <translation>&Перевод:</translation> + </message> + <message> + <location line="+10"/> + <source>This is the phrase in the target language corresponding to the source phrase.</source> + <translation>Перевод, соответствующий исходной фразе.</translation> + </message> + <message> + <location line="+7"/> + <source>S&ource phrase:</source> + <translation>&Исходная фраза:</translation> + </message> + <message> + <location line="+10"/> + <source>This is a definition for the source phrase.</source> + <translation>Определение исходной фразы.</translation> + </message> + <message> + <location line="+7"/> + <source>This is the phrase in the source language.</source> + <translation>Фраза на исходном языке.</translation> + </message> + <message> + <location line="+7"/> + <source>&Definition:</source> + <translation>&Определение:</translation> + </message> + <message> + <location line="+35"/> + <source>Click here to add the phrase to the phrase book.</source> + <translation>Добавить фразу в разговорник.</translation> + </message> + <message> + <location line="+3"/> + <source>&New Entry</source> + <translation>Новая &запись</translation> + </message> + <message> + <location line="+7"/> + <source>Click here to remove the entry from the phrase book.</source> + <translation>Удалить фразу из разговорника.</translation> + </message> + <message> + <location line="+3"/> + <source>&Remove Entry</source> + <translation>&Удалить</translation> + </message> + <message> + <location line="+7"/> + <source>Settin&gs...</source> + <translation>&Настройки...</translation> + </message> + <message> + <location line="+7"/> + <source>Click here to save the changes made.</source> + <translation>Сохранить изменения.</translation> + </message> + <message> + <location line="+3"/> + <source>&Save</source> + <translation>&Сохранить</translation> + </message> + <message> + <location line="+7"/> + <source>Click here to close this window.</source> + <translation>Закрыть окно.</translation> + </message> + <message> + <location line="+3"/> + <source>Close</source> + <translation>Закрыть</translation> + </message> +</context> +<context> + <name>PhraseModel</name> + <message> + <location filename="../tools/linguist/linguist/phrasemodel.cpp" line="+117"/> + <source>Source phrase</source> + <translation>Исходная фраза</translation> + </message> + <message> + <location line="+2"/> + <source>Translation</source> + <translation>Перевод</translation> + </message> + <message> + <location line="+2"/> + <source>Definition</source> + <translation>Определение</translation> + </message> +</context> +<context> + <name>PhraseView</name> + <message> + <location filename="../tools/linguist/linguist/phraseview.cpp" line="+121"/> + <source>Insert</source> + <translation>Вставить</translation> + </message> + <message> + <location line="+3"/> + <source>Edit</source> + <translation>Правка</translation> + </message> + <message> + <location line="+113"/> + <source>Guess (%1)</source> + <translation>Похожая (%1)</translation> + </message> + <message> + <location line="+2"/> + <source>Guess</source> + <translation>Похожая</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <location filename="../tools/linguist/linguist/mainwindow.cpp" line="-1806"/> + <source>Translation files (%1);;</source> + <translation>Файлы перевода (%1);;</translation> + </message> + <message> + <location line="+5"/> + <source>All files (*)</source> + <translation>Все файлы (*)</translation> + </message> + <message> + <location filename="../tools/linguist/linguist/messagemodel.cpp" line="-1118"/> + <location line="+18"/> + <location line="+67"/> + <location line="+39"/> + <location line="+17"/> + <location line="+15"/> + <location filename="../tools/linguist/linguist/phrase.cpp" line="+196"/> + <source>Qt Linguist</source> + <translation>Qt Linguist</translation> + </message> + <message> + <location filename="../tools/linguist/shared/po.cpp" line="+651"/> + <source>GNU Gettext localization files</source> + <translation>Файлы локализации GNU Gettext</translation> + </message> + <message> + <location filename="../tools/linguist/shared/qm.cpp" line="+12"/> + <source>Compiled Qt translations</source> + <translation>Скомпилированные переводы Qt</translation> + </message> + <message> + <location filename="../tools/linguist/shared/qph.cpp" line="+192"/> + <source>Qt Linguist 'Phrase Book'</source> + <translation>'Разговорник' Qt Linguist</translation> + </message> + <message> + <location filename="../tools/linguist/shared/ts.cpp" line="+752"/> + <source>Qt translation sources (format 1.1)</source> + <translation>Исходные файлы перевода Qt (формат 1.1)</translation> + </message> + <message> + <location line="+8"/> + <source>Qt translation sources (format 2.0)</source> + <translation>Исходные файлы перевода Qt (формат 2.0)</translation> + </message> + <message> + <location line="+9"/> + <source>Qt translation sources (latest format)</source> + <translation>Исходные файлы перевода Qt (последний формат)</translation> + </message> + <message> + <location filename="../tools/linguist/shared/xliff.cpp" line="+817"/> + <source>XLIFF localization files</source> + <translation>Файлы локализации XLIFF</translation> + </message> + <message> + <location filename="../tools/linguist/shared/cpp.cpp" line="+1089"/> + <source>C++ source files</source> + <translation>Исходные коды C++</translation> + </message> + <message> + <location filename="../tools/linguist/shared/java.cpp" line="+652"/> + <source>Java source files</source> + <translation>Исходные коды Java</translation> + </message> + <message> + <location filename="../tools/linguist/shared/qscript.cpp" line="+2399"/> + <source>Qt Script source files</source> + <translation>Исходные коды Qt Script</translation> + </message> + <message> + <location filename="../tools/linguist/shared/ui.cpp" line="+213"/> + <source>Qt Designer form files</source> + <translation>Формы Qt Designer</translation> + </message> + <message> + <location line="+9"/> + <source>Qt Jambi form files</source> + <translation>Формы Qt Jambi</translation> + </message> +</context> +<context> + <name>SourceCodeView</name> + <message> + <location filename="../tools/linguist/linguist/sourcecodeview.cpp" line="+70"/> + <source><i>Source code not available</i></source> + <translation><i>Исходный код недоступен</i></translation> + </message> + <message> + <location line="+33"/> + <source><i>File %1 not available</i></source> + <translation><i>Файл %1 недоступен</i></translation> + </message> + <message> + <location line="+5"/> + <source><i>File %1 not readable</i></source> + <translation><i>Невозможно прочитать файл %1</i></translation> + </message> +</context> +<context> + <name>Statistics</name> + <message> + <location filename="../tools/linguist/linguist/statistics.ui" line="+54"/> + <source>Statistics</source> + <translation>Статистика</translation> + </message> + <message> + <location line="+24"/> + <source>Close</source> + <translation>Закрыть</translation> + </message> + <message> + <location line="+34"/> + <source>Translation</source> + <translation>Перевод</translation> + </message> + <message> + <location line="+7"/> + <source>Source</source> + <translation>Источник</translation> + </message> + <message> + <location line="+7"/> + <location line="+7"/> + <location line="+14"/> + <location line="+7"/> + <location line="+21"/> + <location line="+7"/> + <source>0</source> + <translation>0</translation> + </message> + <message> + <location line="-42"/> + <source>Words:</source> + <translation>Слов:</translation> + </message> + <message> + <location line="+21"/> + <source>Characters:</source> + <translation>Символов:</translation> + </message> + <message> + <location line="+7"/> + <source>Characters (with spaces):</source> + <translation>Символов (с пробелами):</translation> + </message> +</context> +<context> + <name>TranslateDialog</name> + <message> + <location filename="../tools/linguist/linguist/translatedialog.ui" line="+60"/> + <source>This window allows you to search for some text in the translation source file.</source> + <translation>Данное окно позволяет искать текст в файле перевода.</translation> + </message> + <message> + <location line="+28"/> + <location line="+27"/> + <source>Type in the text to search for.</source> + <translation>Введите искомый текст.</translation> + </message> + <message> + <location line="-20"/> + <source>Find &source text:</source> + <translation>&Найти текст:</translation> + </message> + <message> + <location line="+10"/> + <source>&Translate to:</source> + <translation>&Перевести как:</translation> + </message> + <message> + <location line="+19"/> + <source>Search options</source> + <translation>Параметры поиска</translation> + </message> + <message> + <location line="+6"/> + <source>Texts such as 'TeX' and 'tex' are considered as different when checked.</source> + <translation>Если отмечено, строки "ПрИмЕр" и "пример" будет считаться разными.</translation> + </message> + <message> + <location line="+3"/> + <source>Match &case</source> + <translation>С учётом &регистра</translation> + </message> + <message> + <location line="+7"/> + <source>Mark new translation as &finished</source> + <translation>Помечать перевод как завер&шённый</translation> + </message> + <message> + <location line="+33"/> + <source>Click here to find the next occurrence of the text you typed in.</source> + <translation>Найти следующее совпадение для введённого текста.</translation> + </message> + <message> + <location line="+3"/> + <source>Find Next</source> + <translation>Найти далее</translation> + </message> + <message> + <location line="+13"/> + <source>Translate</source> + <translation>Перевести</translation> + </message> + <message> + <location line="+7"/> + <source>Translate All</source> + <translation>Перевести все</translation> + </message> + <message> + <location line="+7"/> + <source>Click here to close this window.</source> + <translation>Закрыть окно.</translation> + </message> + <message> + <location line="+3"/> + <source>Cancel</source> + <translation>Отмена</translation> + </message> +</context> +<context> + <name>TranslationSettingsDialog</name> + <message> + <location filename="../tools/linguist/linguist/translationsettings.ui" line="+20"/> + <source>Source language</source> + <translation>Исходный язык</translation> + </message> + <message> + <location line="+15"/> + <location line="+38"/> + <source>Language</source> + <translation>Язык</translation> + </message> + <message> + <location line="-25"/> + <location line="+38"/> + <source>Country/Region</source> + <translation>Страна/Регион</translation> + </message> + <message> + <location line="-28"/> + <source>Target language</source> + <translation>Язык перевода</translation> + </message> + <message> + <location filename="../tools/linguist/linguist/translationsettingsdialog.cpp" line="+68"/> + <source>Any Country</source> + <translation>Любая страна</translation> + </message> + <message> + <location line="+11"/> + <location line="+8"/> + <source>Settings for '%1' - Qt Linguist</source> + <translation>Настройки для '%1' - Qt Linguist</translation> + </message> +</context> +</TS> diff --git a/translations/qt_help_ru.ts b/translations/qt_help_ru.ts new file mode 100644 index 0000000..16748fb --- /dev/null +++ b/translations/qt_help_ru.ts @@ -0,0 +1,361 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="ru"> +<context> + <name>QCLuceneResultWidget</name> + <message> + <location filename="../tools/assistant/lib/qhelpsearchresultwidget.cpp" line="+110"/> + <source>Search Results</source> + <translation>Результаты поиска</translation> + </message> + <message> + <location line="+7"/> + <source>Note:</source> + <translation>Замечание:</translation> + </message> + <message> + <location line="+1"/> + <source>The search results may not be complete since the documentation is still being indexed!</source> + <translation>Могли быть показаны не все результаты, так как документация ещё индексируется!</translation> + </message> + <message> + <location line="+11"/> + <source>Your search did not match any documents.</source> + <translation>По вашему запросу не найдено ни одного документа.</translation> + </message> + <message> + <location line="+4"/> + <source>(The reason for this might be that the documentation is still being indexed.)</source> + <translation>(Причиной этого может быть то, что документация ещё индексируется.)</translation> + </message> +</context> +<context> + <name>QHelpCollectionHandler</name> + <message> + <location filename="../tools/assistant/lib/qhelpcollectionhandler.cpp" line="+79"/> + <source>The collection file is not set up yet!</source> + <translation type="unfinished">Файл набора ещё не установлен!</translation> + </message> + <message> + <location line="+22"/> + <source>Cannot load sqlite database driver!</source> + <translation>Не удалось загрузить драйвер базы данных sqlite!</translation> + </message> + <message> + <location line="+11"/> + <location line="+48"/> + <source>Cannot open collection file: %1</source> + <translation>Не удалось открыть файл набора: %1</translation> + </message> + <message> + <location line="-39"/> + <source>Cannot create tables in file %1!</source> + <translation>Не удалось создать таблицы в файле %1!</translation> + </message> + <message> + <location line="+16"/> + <source>The specified collection file already exists!</source> + <translation type="unfinished">Указанный файла набора уже существует!</translation> + </message> + <message> + <location line="+5"/> + <source>Cannot create directory: %1</source> + <translation>Не удалось создать каталог: %1</translation> + </message> + <message> + <location line="+23"/> + <source>Cannot copy collection file: %1</source> + <translation type="unfinished">Не удалось скопировать файл набора: %1</translation> + </message> + <message> + <location line="+119"/> + <source>Unknown filter!</source> + <translation>Неизвестный фильтр!</translation> + </message> + <message> + <location line="+55"/> + <source>Cannot register filter %1!</source> + <translation>Не удалось зарегистрировать фильтр %1!</translation> + </message> + <message> + <location line="+44"/> + <source>Cannot open documentation file %1!</source> + <translation>Не удалось открыть файл документации %1!</translation> + </message> + <message> + <location line="+6"/> + <source>Invalid documentation file!</source> + <translation>Некорректный файл документации!</translation> + </message> + <message> + <location line="+34"/> + <source>The namespace %1 was not registered!</source> + <translation>Пространство имён %1 не зарегистрировано!</translation> + </message> + <message> + <location line="+120"/> + <source>Namespace %1 already exists!</source> + <translation>Пространство имён %1 уже существует!</translation> + </message> + <message> + <location line="+13"/> + <source>Cannot register namespace!</source> + <translation>Не удалось зарегистрировать пространство имён!</translation> + </message> + <message> + <location line="+24"/> + <source>Cannot open database to optimize!</source> + <translation>Не удалось открыть базу данных для оптимизации!</translation> + </message> +</context> +<context> + <name>QHelpDBReader</name> + <message> + <location filename="../tools/assistant/lib/qhelpdbreader.cpp" line="+98"/> + <source>Cannot open database '%1' '%2': %3</source> + <extracomment>The placeholders are: %1 - The name of the database which cannot be opened %2 - The unique id for the connection %3 - The actual error string</extracomment> + <translation>Не удалось открыть базу данных '%1' '%2': %3</translation> + </message> +</context> +<context> + <name>QHelpEngineCore</name> + <message> + <location filename="../tools/assistant/lib/qhelpenginecore.cpp" line="+516"/> + <source>The specified namespace does not exist!</source> + <translation>Указанное пространство имён не существует!</translation> + </message> +</context> +<context> + <name>QHelpEngineCorePrivate</name> + <message> + <location line="-394"/> + <source>Cannot open documentation file %1: %2!</source> + <translation>Не удалось открыть файл документации %1: %2!</translation> + </message> +</context> +<context> + <name>QHelpGenerator</name> + <message> + <location filename="../tools/assistant/lib/qhelpgenerator.cpp" line="+157"/> + <source>Invalid help data!</source> + <translation>Некорректные данные справки!</translation> + </message> + <message> + <location line="+6"/> + <source>No output file name specified!</source> + <translation>Не указано имя результирующего файла!</translation> + </message> + <message> + <location line="+14"/> + <source>Building up file structure...</source> + <translation>Создание структуры файла...</translation> + </message> + <message> + <location line="-7"/> + <source>The file %1 cannot be overwritten!</source> + <translation>Невозможно перезаписать файл %1!</translation> + </message> + <message> + <location line="+18"/> + <source>Cannot open data base file %1!</source> + <translation>Не удалось открыть файл базы данных %1!</translation> + </message> + <message> + <location line="+11"/> + <source>Cannot register namespace %1!</source> + <translation>Не удалось зарегистрировать пространство имён %1!</translation> + </message> + <message> + <location line="+6"/> + <source>Insert custom filters...</source> + <translation>Вставка индивидуальных фильтров...</translation> + </message> + <message> + <location line="+12"/> + <source>Insert help data for filter section (%1 of %2)...</source> + <translation>Вставка данных справки для секции фильтра (%1 из %2)...</translation> + </message> + <message> + <location line="+18"/> + <source>Documentation successfully generated.</source> + <translation>Документация успешно создана.</translation> + </message> + <message> + <location line="+76"/> + <source>Some tables already exist!</source> + <translation>Некоторые таблицы уже существуют!</translation> + </message> + <message> + <location line="+61"/> + <source>Cannot create tables!</source> + <translation>Не удалось создать таблицы!</translation> + </message> + <message> + <location line="+86"/> + <source>Cannot register virtual folder!</source> + <translation>Не удалось зарегистрировать виртуальный каталог!</translation> + </message> + <message> + <location line="+10"/> + <source>Insert files...</source> + <translation>Вставка файлов...</translation> + </message> + <message> + <location line="+42"/> + <source>The referenced file %1 must be inside or within a subdirectory of (%2). Skipping it.</source> + <translation>Файл %1 должен быть в каталоге '%2' или в его подкаталоге. Пропускаем.</translation> + </message> + <message> + <location line="+7"/> + <source>The file %1 does not exist! Skipping it.</source> + <translation>Файл %1 не существует! Пропускаем.</translation> + </message> + <message> + <location line="+6"/> + <source>Cannot open file %1! Skipping it.</source> + <translation>Не удалось открыть файл %1! Пропускаем.</translation> + </message> + <message> + <location line="+131"/> + <source>The filter %1 is already registered!</source> + <translation>Фильтр %1 уже зарегистрирован!</translation> + </message> + <message> + <location line="+5"/> + <source>Cannot register filter %1!</source> + <translation>Не удалось зарегистрировать фильтр %1!</translation> + </message> + <message> + <location line="+24"/> + <source>Insert indices...</source> + <translation>Вставка указателей...</translation> + </message> + <message> + <location line="+80"/> + <source>Insert contents...</source> + <translation>Вставка оглавления...</translation> + </message> + <message> + <location line="+8"/> + <source>Cannot insert contents!</source> + <translation>Не удаётся вставить оглавление!</translation> + </message> + <message> + <location line="+12"/> + <source>Cannot register contents!</source> + <translation>Не удаётся зарегистрировать оглавление!</translation> + </message> +</context> +<context> + <name>QHelpSearchQueryWidget</name> + <message> + <location filename="../tools/assistant/lib/qhelpsearchquerywidget.cpp" line="+200"/> + <source>Search for:</source> + <translation>Искать:</translation> + </message> + <message> + <location line="+2"/> + <source>Search</source> + <translation>Поиск</translation> + </message> + <message> + <location line="+16"/> + <source>Advanced search</source> + <translation>Расширенный поиск</translation> + </message> + <message> + <location line="+18"/> + <source>words <B>similar</B> to:</source> + <translation><B>похожие</B> слова:</translation> + </message> + <message> + <location line="+5"/> + <source><B>without</B> the words:</source> + <translation><B>не содержит</B> слова:</translation> + </message> + <message> + <location line="+5"/> + <source>with <B>exact phrase</B>:</source> + <translation>содержит <B>фразу полностью</B>:</translation> + </message> + <message> + <location line="+5"/> + <source>with <B>all</B> of the words:</source> + <translation>содержит <B>все</B> слова:</translation> + </message> + <message> + <location line="+5"/> + <source>with <B>at least one</B> of the words:</source> + <translation>содержит <B> минимум одно</B> из слов:</translation> + </message> +</context> +<context> + <name>QHelpSearchResultWidget</name> + <message> + <location filename="../tools/assistant/lib/qhelpsearchresultwidget.cpp" line="+235"/> + <source>0 - 0 of 0 Hits</source> + <translation>0 - 0 из 0 соответствий</translation> + </message> +</context> +<context> + <name>QHelpSearchResultWidgetPrivate</name> + <message> + <location line="-61"/> + <source>%1 - %2 of %3 Hits</source> + <translation>%1 - %2 из %3 соответствий</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <location filename="../tools/assistant/lib/qhelp_global.h" line="+83"/> + <source>Untitled</source> + <translation>Безымянный</translation> + </message> + <message> + <location filename="../tools/assistant/lib/qhelpprojectdata.cpp" line="+80"/> + <source>Unknown token.</source> + <translation type="unfinished">Неизвестный токен.</translation> + </message> + <message> + <location line="+13"/> + <source>Unknown token. Expected "QtHelpProject"!</source> + <translation type="unfinished">Неизвестный токен. Ожидается "QtHelpProject"!</translation> + </message> + <message> + <location line="+5"/> + <source>Error in line %1: %2</source> + <translation>Ошибка в строке %1: %2</translation> + </message> + <message> + <location line="+13"/> + <source>A virtual folder must not contain a '/' character!</source> + <translation>Виртуальный каталог не должен содержать символ '/'!</translation> + </message> + <message> + <location line="+4"/> + <source>A namespace must not contain a '/' character!</source> + <translation>Пространство имён не должно содержать символ '/'!</translation> + </message> + <message> + <location line="+16"/> + <source>Missing namespace in QtHelpProject.</source> + <translation>Отсутствует пространство имён в QtHelpProject.</translation> + </message> + <message> + <location line="+2"/> + <source>Missing virtual folder in QtHelpProject</source> + <translation>Отсутствует виртуальный каталог в QtHelpProject</translation> + </message> + <message> + <location line="+88"/> + <source>Missing attribute in keyword at line %1.</source> + <translation>Отсутствует атрибут у ключевого слова в строке %1.</translation> + </message> + <message> + <location line="+83"/> + <source>The input file %1 could not be opened!</source> + <translation>Невозможно открыть исходный файл %1!</translation> + </message> +</context> +</TS> diff --git a/translations/translations.pri b/translations/translations.pri index cdb157e..480849f 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -8,8 +8,16 @@ defineReplace(prependAll) { return ($$result) } -LUPDATE = $$QT_BUILD_TREE/bin/lupdate -locations relative -no-ui-lines -win32:LUPDATE ~= s|/|\|g +defineReplace(fixPath) { +WIN { + return ($$replace($$1, /, \)) +} ELSE { + return ($$1) +} +} + +LUPDATE = $$fixPath($$QT_BUILD_TREE/bin/lupdate) -locations relative -no-ui-lines +LRELEASE = $$fixPath($$QT_BUILD_TREE/bin/lrelease) ###### Qt Libraries @@ -34,18 +42,27 @@ ts-qt.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ -ts $$prependAll($$[QT_INSTALL_TRANSLATIONS]/qt_,$$QT_TS,.ts)) ts-qt.depends = sub-tools +qm-qt.commands = $$LRELEASE $$prependAll($$[QT_INSTALL_TRANSLATIONS]/qt_,$$QT_TS,.ts) +qm-qt.depends = sub-tools + ###### Designer ts-designer.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/designer/translations/translations.pro) ts-designer.depends = sub-tools +qm-designer.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/designer/translations/translations.pro +qm-designer.depends = sub-tools + ###### Linguist ts-linguist.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/linguist/linguist/linguist.pro) ts-linguist.depends = sub-tools +qm-linguist.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/linguist/linguist/linguist.pro +qm-linguist.depends = sub-tools + ###### Assistant ts-assistant.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ @@ -56,21 +73,36 @@ ts-assistant.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/assistant/translations/translations_adp.pro) ts-assistant.depends = sub-tools +qm-assistant.commands = ($$LRELEASE $$QT_SOURCE_TREE/tools/assistant/translations/translations.pro \ + && $$LRELEASE \ + $$QT_SOURCE_TREE/tools/assistant/translations/qt_help.pro \ + && $$LRELEASE \ + $$QT_SOURCE_TREE/tools/assistant/translations/translations_adp.pro) +qm-assistant.depends = sub-tools + ###### Qtconfig ts-qtconfig.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/qtconfig/translations/translations.pro) ts-qtconfig.depends = sub-tools +qm-qtconfig.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/qtconfig/translations/translations.pro +qm-qtconfig.depends = sub-tools + ###### Qvfp ts-qvfb.commands = (cd $$QT_SOURCE_TREE/src && $$LUPDATE \ ../tools/qvfb/translations/translations.pro) ts-qvfb.depends = sub-tools +qm-qvfb.commands = $$LRELEASE $$QT_SOURCE_TREE/tools/qvfb/translations/translations.pro +qm-qvfb.depends = sub-tools + ###### Overall Rules ts.depends = ts-qt ts-designer ts-linguist ts-assistant ts-qtconfig ts-qvfb +qm.depends = qm-qt qm-designer qm-linguist qm-assistant qm-qtconfig qm-qvfb QMAKE_EXTRA_TARGETS += ts-qt ts-designer ts-linguist ts-assistant ts-qtconfig ts-qvfb \ - ts + qm-qt qm-designer qm-linguist qm-assistant qm-qtconfig qm-qvfb \ + ts qm diff --git a/translations/translations.pro b/translations/translations.pro deleted file mode 100644 index 6f14108..0000000 --- a/translations/translations.pro +++ /dev/null @@ -1,50 +0,0 @@ -TRANSLATIONS = $$files(*.ts) - -LRELEASE = $$QT_BUILD_TREE/bin/lrelease -win32 { - LRELEASE ~= s|/|\|g -} else:!static { - path = $$QT_BUILD_TREE/lib - !macx:var = LD_LIBRARY_PATH - else:qt_no_framework:var = DYLD_LIBRARY_PATH - else:var = DYLD_FRAMEWORK_PATH - - LRELEASE = test -z \"\$\$$$var\" && $$var=$$path || $$var=$$path:\$\$$$var; export $$var; $$LRELEASE -} - -contains(TEMPLATE_PREFIX, vc):vcproj = 1 - -TEMPLATE = app -TARGET = qm_phony_target -CONFIG -= qt separate_debug_info -QT = -LIBS = - -updateqm.input = TRANSLATIONS -updateqm.output = ${QMAKE_FILE_BASE}.qm -isEmpty(vcproj):updateqm.variable_out = PRE_TARGETDEPS -updateqm.commands = @echo lrelease ${QMAKE_FILE_IN}; $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} -updateqm.name = LRELEASE ${QMAKE_FILE_IN} -updateqm.CONFIG += no_link -QMAKE_EXTRA_COMPILERS += updateqm - -isEmpty(vcproj) { - QMAKE_LINK = @: IGNORE THIS LINE - OBJECTS_DIR = - win32:CONFIG -= embed_manifest_exe -} else { - CONFIG += console - PHONY_DEPS = . - phony_src.input = PHONY_DEPS - phony_src.output = phony.c - phony_src.variable_out = GENERATED_SOURCES - phony_src.commands = echo int main() { return 0; } > phony.c - phony_src.name = CREATE phony.c - phony_src.CONFIG += combine - QMAKE_EXTRA_COMPILERS += phony_src -} - -translations.path = $$[QT_INSTALL_TRANSLATIONS] -translations.files = $$TRANSLATIONS -translations.files ~= s,\\.ts$,.qm,g -INSTALLS += translations |